Skip to main content
Version: v0.0.14

@cosyte/ccda

Classes​

CcdaDocument​

The immutable parsed C-CDA document. Carries the recognized identity, the header, the top-level sections (empty for an unstructured document, see nonXmlBody), and the frozen lenient-parse warnings.

Example​

import { parseCcda } from "@cosyte/ccda";
const doc = parseCcda(xml);
console.log(doc.documentType, doc.getPatient()?.name?.text, doc.getMrn());

Constructors​

Constructor​

new CcdaDocument(init): CcdaDocument

Internal

Construct a CcdaDocument. Freezes the warnings array (after a slice) so callers cannot mutate parser output after handoff.

Parameters​
init​

CcdaDocumentInit

Returns​

CcdaDocument

Properties​

allergies​

readonly allergies: readonly AllergyConcern[]

Extracted Allergy Concern Acts (across all sections). Empty when none.

documentType​

readonly documentType: DocumentType | undefined

The recognized document type, or undefined when the root templateId is unrecognized/absent.

encounters​

readonly encounters: readonly Encounter[]

Extracted Encounter Activities, visits/admissions (across all sections). Empty when none.

familyHistory​

readonly familyHistory: readonly FamilyHistory[]

Extracted Family History Organizers, one per relative (across all sections). Empty when none.

functionalStatus​

readonly functionalStatus: readonly StatusObservation[]

Extracted Functional Status findings (across all sections). Empty when none.

readonly header: CcdaHeader

The parsed US Realm Header.

immunizations​

readonly immunizations: readonly Immunization[]

Extracted Immunization Activities (across all sections). Empty when none.

medications​

readonly medications: readonly Medication[]

Extracted Medication Activities (across all sections). Empty when none.

mentalStatus​

readonly mentalStatus: readonly StatusObservation[]

Extracted Mental Status findings (across all sections). Empty when none.

nonXmlBody​

readonly nonXmlBody: ED | undefined

The quarantined nonXMLBody content for an unstructured document (base64 never decoded).

pastMedicalHistory​

readonly pastMedicalHistory: readonly Problem[]

Extracted Past Medical History problems, bare historical Problem Observations. Empty when none.

plannedItems​

readonly plannedItems: readonly PlannedItem[]

Extracted planned items from the Plan of Treatment, all future/ordered (across all sections). Empty when none.

problems​

readonly problems: readonly ProblemConcern[]

Extracted Problem Concern Acts (across all sections). Empty when none.

procedures​

readonly procedures: readonly Procedure[]

Extracted procedures, performed or planned (across all sections). Empty when none.

profile​

readonly profile: ProfileAttribution | undefined

The profile applied at parse time (name + lineage), or undefined when none was active.

results​

readonly results: readonly ResultOrganizer[]

Extracted Result Organizers, lab/diagnostic panels (across all sections). Empty when none.

sections​

readonly sections: readonly CcdaSection[]

Top-level framed sections from the structuredBody. Empty for an unstructured document.

smokingStatus​

readonly smokingStatus: readonly SmokingStatus[]

Extracted Smoking Status observations from Social History. Empty when none.

templateIds​

readonly templateIds: readonly II[]

The root templateIds, in document order (raw recognition signal).

vitals​

readonly vitals: readonly VitalSignsOrganizer[]

Extracted Vital Signs Organizers, vital-reading clusters (across all sections). Empty when none.

warnings​

readonly warnings: readonly CcdaWarning[]

Lenient-parse warnings, frozen at the model boundary.

Methods​

allSections()​

allSections(): readonly CcdaSection[]

Every section in the document, flattened depth-first (top-level sections followed by their nested subsections). Order is document order.

Returns​

readonly CcdaSection[]

Example​
for (const s of doc.allSections()) console.log(s.key ?? "(unrecognized)");
findSection()​

findSection(key): CcdaSection | undefined

Find the first recognized section with the given catalog key, searching top-level sections then their subsections (depth-first). Returns undefined when no recognized section matches.

Parameters​
key​

string

Returns​

CcdaSection | undefined

Example​
const allergies = doc.findSection("allergies");
console.log(allergies?.narrativeText);
getAllergies()​

getAllergies(): readonly AllergyConcern[]

The patient's Allergy Concern Acts, each wrapping one or more allergy/intolerance observations (including the "No Known Allergies" negated form). Empty when the document carries no Allergies entries.

Returns​

readonly AllergyConcern[]

Example​
const nka = doc.getAllergies().some((c) => c.allergies.some((a) => a.noKnownAllergy));
getEncounters()​

getEncounters(): readonly Encounter[]

The patient's Encounter Activities, each carrying the encounter type code, status, and visit period. Empty when the document carries no Encounters entries.

Returns​

readonly Encounter[]

Example​
for (const e of doc.getEncounters()) console.log(e.code?.code, e.effectiveTime);
getFamilyHistory()​

getFamilyHistory(): readonly FamilyHistory[]

The patient's Family History, one FamilyHistory per relative, each carrying the relative's structured identity and their recorded conditions. Empty when the document carries no Family History entries.

Returns​

readonly FamilyHistory[]

Example​
for (const h of doc.getFamilyHistory())
console.log(h.relative.relationship?.code, h.observations.length);
getFunctionalStatus()​

getFunctionalStatus(): readonly StatusObservation[]

The patient's Functional Status findings, ADLs, mobility, and self-care observations (plus any scored assessment scales). Empty when the document carries no Functional Status entries.

Returns​

readonly StatusObservation[]

Example​
const scales = doc.getFunctionalStatus().filter((o) => o.assessmentScale);
console.log(scales[0]?.code?.code);
getImmunizations()​

getImmunizations(): readonly Immunization[]

The patient's Immunization Activities, each carrying the CVX vaccine, dose, route, and date (including the refused not-administered form). Empty when the document carries no Immunizations entries.

Returns​

readonly Immunization[]

Example​
const given = doc.getImmunizations().filter((i) => i.refused !== true);
console.log(given[0]?.vaccine?.code);
getMedications()​

getMedications(): readonly Medication[]

The patient's Medication Activities, each carrying the RxNorm drug, dose, route, and timing. Empty when the document carries no Medications entries.

Returns​

readonly Medication[]

Example​
for (const m of doc.getMedications()) console.log(m.drug?.code, m.dose?.value);
getMentalStatus()​

getMentalStatus(): readonly StatusObservation[]

The patient's Mental Status findings, cognition and mood observations (plus any scored assessment scales such as a PHQ-9). Empty when the document carries no Mental Status entries.

Returns​

readonly StatusObservation[]

Example​
for (const o of doc.getMentalStatus()) console.log(o.code?.code, o.value?.kind);
getMrn()​

getMrn(): string | undefined

The patient's MRN string, the first patientRole/id extension (see pickMrn). undefined when there is no patient, when that id has no extension, or when it carries a nullFlavor: the document disowned that identifier, and a bare string return has nowhere to carry the marking that qualified it. It withholds rather than falling through to the next <id>, since nothing in a C-CDA ranks patientRole/id entries and the next one is as likely to be an account or member number. The verbatim value is still reachable at getPatient()?.identifiers, where the nullFlavor travels with it.

Returns​

string | undefined

Example​
console.log(doc.getMrn() ?? "no MRN");
getPastMedicalHistory()​

getPastMedicalHistory(): readonly Problem[]

The patient's Past Medical History, historical problems carried as bare Problem Observations (distinct from the active-concern Problems section). Empty when the document carries no Past Medical History entries.

Returns​

readonly Problem[]

Example​
console.log(doc.getPastMedicalHistory()[0]?.value?.code);
getPatient()​

getPatient(): CcdaPatient | undefined

The first recordTarget patient, or undefined when the document carries none. A document with multiple record targets emits MULTIPLE_RECORD_TARGETS at parse time; this returns the first.

Returns​

CcdaPatient | undefined

Example​
const p = doc.getPatient();
console.log(p?.name?.text ?? "unknown patient");
getPlannedItems()​

getPlannedItems(): readonly PlannedItem[]

The patient's planned items from the Plan of Treatment, each future/ordered (never performed), carrying its planned code, kind, and a disposition of "planned" derived from moodCode (never read as performed). Empty when the document carries no Plan of Treatment entries.

Two bounds, because a quiet result here is not a complete one. This returns seven entry templates and the Plan of Treatment Section admits eleven: Instruction (…22.4.20), Handoff Communication Participants (…22.4.141), Nutrition Recommendation (…22.4.130) and Goal Observation (…22.4.121) are not acts planned for the patient and are not returned, and nothing is raised about them. A Goal Observation is the clearest of the four: it is moodCode="GOL", which this parser calls neither performed nor planned. And a planned entry is reached as a direct <entry> act or nested inside a Planned Intervention Act (…22.4.146), the one container R2.1 lets hold all seven inline. Nesting is not solved in general: R2.1 also puts planned acts inside a Nutrition Recommendation (…22.4.130, six of the seven) and a Planned Intervention Act inside an Intervention Act (…22.4.131), and a planned entry in either is still not reached. All of it re-serializes faithfully, so toString() is the fallback.

Returns​

readonly PlannedItem[]

Example​
const orders = doc.getPlannedItems().filter((p) => p.kind === "medicationActivity");
console.log(orders[0]?.code?.code);
getProblems()​

getProblems(): readonly ProblemConcern[]

The patient's Problem Concern Acts, each wrapping one or more coded problems with an active/resolved status. Empty when the document carries no Problems entries.

Returns​

readonly ProblemConcern[]

Example​
const active = doc.getProblems().filter((c) => c.status === "active");
console.log(active[0]?.problems[0]?.value?.code);
getProcedures()​

getProcedures(): readonly Procedure[]

The patient's procedures, each carrying its procedure code, status, and a disposition of "performed" vs "planned" derived from moodCode (never conflated). Empty when the document carries no Procedures entries.

Returns​

readonly Procedure[]

Example​
const performed = doc.getProcedures().filter((p) => p.disposition === "performed");
console.log(performed[0]?.code?.code);
getResults()​

getResults(): readonly ResultOrganizer[]

The patient's Result Organizers, lab/diagnostic panels, each carrying its member Result Observations with UCUM-checked values and reference ranges. Empty when the document carries no Results entries.

Returns​

readonly ResultOrganizer[]

Example​
for (const panel of doc.getResults())
for (const r of panel.results) console.log(r.code?.code, r.interpretation?.code);
getSmokingStatus()​

getSmokingStatus(): readonly SmokingStatus[]

The patient's Smoking Status observations (from Social History), each carrying the SNOMED smoking-status value and an unknown flag for the explicitly-unknown form. Empty when the document records no smoking status.

Returns​

readonly SmokingStatus[]

Example​
const known = doc.getSmokingStatus().filter((s) => !s.unknown);
console.log(known[0]?.value?.code);
getVitals()​

getVitals(): readonly VitalSignsOrganizer[]

The patient's Vital Signs Organizers, reading clusters, each carrying its member Vital Sign Observations with UCUM-checked PQ values. Empty when the document carries no Vital Signs entries.

Returns​

readonly VitalSignsOrganizer[]

Example​
for (const cluster of doc.getVitals())
for (const v of cluster.vitals) console.log(v.code?.code, v.value);
toString()​

toString(): string

Serialize this document back to spec-clean C-CDA XML, the conservative emit half of the Postel's-Law contract. Returns the faithful re-emission of the source the parser read (no silent loss of unmodeled content), with a guaranteed XML declaration. Serialization is a fixed point: parseCcda(doc.toString()).toString() === doc.toString().

Returns​

string

The spec-clean XML text.

Throws​

If this document was hand-constructed (not produced by parseCcda) and so retains no source document to emit.

Example​
const doc = parseCcda(xml);
const xmlOut = doc.toString();
withWarnings()​

withWarnings(additional): CcdaDocument

Return a new CcdaDocument with additional warnings appended, structurally sharing every parsed field (header, sections, entries, and the serialized snapshot) with this instance by reference. The original is never mutated. A downstream pass (e.g. profile-aware validation) uses this to annotate a document without re-parsing.

Parameters​
additional​

readonly CcdaWarning[]

Warnings to append after the existing ones.

Returns​

CcdaDocument

A new document; this instance is unchanged.

Example​
const annotated = doc.withWarnings([
{ code: "SECTION_PLACEMENT_SUSPECT", message: "...", position: {} },
]);
// doc.warnings is unchanged; annotated.warnings has the extra entry.

CcdaEditError​

The typed error editCcda throws when an edit cannot be applied safely , a hand-constructed source with no XML to edit, a structured-body-less document, an add/replace precondition violation, an edit that would drop a per-document-type SHALL required section, or a revision of a source whose ClinicalDocument.id is absent or marked nullFlavor (the RPLC link has no prior version it can truthfully name). Consumers narrow via code.

Example​

import { editCcda, CcdaEditError } from "@cosyte/ccda";
try {
editCcda(doc, { sections: [{ kind: "problems", mode: "add", content: [] }] });
} catch (err) {
if (err instanceof CcdaEditError && err.code === "SECTION_ALREADY_PRESENT") {
// the document already has a Problems section, use "replace" or "upsert"
}
}

Extends​

  • Error

Constructors​

Constructor​

new CcdaEditError(code, message): CcdaEditError

Internal

Construct a new CcdaEditError.

Parameters​
code​

CcdaEditErrorCode

The stable failure code.

message​

string

A human-readable, PHI-free explanation.

Returns​

CcdaEditError

Overrides​

Error.constructor

Properties​

code​

readonly code: CcdaEditErrorCode

The stable CcdaEditErrorCode discriminant.


CcdaParseError​

Thrown by parseCcda (and the secure XML substrate it calls) when the input violates one of the seven unrecoverable Tier-3 rules, a declared DTD/external entity, entity-expansion or size/depth/node-count limits, malformed XML, or a well-formed document whose root is not ClinicalDocument. Carries a bounded structural CcdaPosition and a message taken whole from FATAL_MESSAGES; unlike some sibling parsers it retains no raw input snippet, precisely because C-CDA payloads are clinical documents and any snippet would risk leaking PHI. Nothing the document said reaches err.message or, under { strict: true }, err.stack.

Example​

import { parseCcda, CcdaParseError } from "@cosyte/ccda";
try {
parseCcda(raw);
} catch (err) {
if (err instanceof CcdaParseError && err.code === "NOT_A_CLINICAL_DOCUMENT") {
// err.position, err.code available, no PHI in either
}
}

Extends​

  • Error

Constructors​

Constructor​

new CcdaParseError(code, message, position): CcdaParseError

Internal

Construct a new CcdaParseError. All three fields are required so every thrower populates a code, a message (which must come from FATAL_MESSAGES, never be built from the input), and a structural position.

Parameters​
code​

FatalCode

message​

string

position​

CcdaPosition

Returns​

CcdaParseError

Overrides​

Error.constructor

Properties​

code​

readonly code: FatalCode

position​

readonly position: CcdaPosition


CcdaProfileDefinitionError​

Thrown by defineCcdaProfile when a profile definition is structurally invalid, a missing/empty name, an unknown option key, a tolerate entry whose code is not a real WarningCode, a missing rationale, or, the load-bearing safety rule, an attempt to tolerate a safety-critical warning code. Distinct from CcdaParseError (which is about a document): this is about a malformed profile, so it is never part of the lenient parse path and carries no CcdaPosition.

Example​

import { defineCcdaProfile, CcdaProfileDefinitionError } from "@cosyte/ccda";
try {
defineCcdaProfile({ name: "bad", tolerate: [{ code: "MISSING_DOSE_QUANTITY", rationale: "x" }] });
} catch (err) {
if (err instanceof CcdaProfileDefinitionError) {
// a profile may never tolerate a safety-critical code
}
}

Extends​

  • Error

Constructors​

Constructor​

new CcdaProfileDefinitionError(message, profileName?): CcdaProfileDefinitionError

Internal

Construct a new CcdaProfileDefinitionError.

Parameters​
message​

string

profileName?​

string

Returns​

CcdaProfileDefinitionError

Overrides​

Error.constructor

Properties​

profileName​

readonly profileName: string | undefined

The offending profile's name, when known at throw time.

Interfaces​

Allergy​

An Allergy-Intolerance Observation. allergen is the offending substance (RxNorm / UNII / SNOMED) from the playing entity; type is the propensity type (the observation value). noKnownAllergy is the negationInd="true" "no known allergies" assertion, distinct from nullFlavor (substance unknown). criticality is the propensity criticality; per-reaction severity lives on each AllergyReaction.

Example​

import type { Allergy } from "@cosyte/ccda";
function allergenCode(a: Allergy): string | undefined {
return a.noKnownAllergy ? undefined : a.allergen?.code;
}

Properties​

allergen?​

readonly optional allergen?: CD

allergenLevelSuspect?​

readonly optional allergenLevelSuspect?: boolean

criticality?​

readonly optional criticality?: CD

ids​

readonly ids: readonly II[]

narrative?​

readonly optional narrative?: string

negated?​

readonly optional negated?: boolean

noKnownAllergy​

readonly noKnownAllergy: boolean

nullFlavor?​

readonly optional nullFlavor?: string

reactions​

readonly reactions: readonly AllergyReaction[]

type?​

readonly optional type?: CD


AllergyConcern​

An Allergy Concern Act: the concern wrapper around one or more Allergy observations. status is the active/resolved/inactive state from the concern statusCode; effectiveTime is the concern window.

Example​

import type { AllergyConcern } from "@cosyte/ccda";
function isActive(c: AllergyConcern): boolean {
return c.status === "active";
}

Properties​

allergies​

readonly allergies: readonly Allergy[]

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

status​

readonly status: ConcernStatus


AllergyReaction​

One reaction (manifestation) of an allergy. manifestation is the coded clinical effect (e.g. hives); severity is the reaction's nested Severity Observation value, distinct from the propensity's overall criticality.

Example​

import type { AllergyReaction } from "@cosyte/ccda";
const r: AllergyReaction = { manifestation: { code: "247472004", codeSystem: "2.16.840.1.113883.6.96" } };

Properties​

manifestation?​

readonly optional manifestation?: CD

severity?​

readonly optional severity?: CD


BL​

Parsed HL7 v3 Boolean. value is the parsed boolean (omitted when the @value token was neither "true" nor "false"); nullFlavor is set when the element declared one.

Example​

import type { BL } from "@cosyte/ccda";
const flag: BL = { value: true };

Properties​

nullFlavor?​

readonly optional nullFlavor?: string

value?​

readonly optional value?: boolean


BuildCcdaAllergy​

An Allergy Concern for the Allergies section. Either an allergen (RxNorm at ingredient level by default, or UNII / SNOMED CT) or noKnownAllergy: true (the negationInd "No Known Allergies" assertion) is required, the two are never conflated. reaction, severity, and criticality are optional; severity (of a reaction) and criticality (of the propensity) are distinct axes.

Example​

import type { BuildCcdaAllergy } from "@cosyte/ccda";
const penicillin: BuildCcdaAllergy = {
allergen: { code: "7980", displayName: "Penicillin G" },
reaction: { code: "247472004", displayName: "Hives" },
criticality: { code: "CRITH", displayName: "High criticality" },
};
const nka: BuildCcdaAllergy = { noKnownAllergy: true };

Properties​

allergen?​

readonly optional allergen?: BuildCode

The offending substance (RxNorm ingredient default, or UNII / SNOMED CT).

criticality?​

readonly optional criticality?: BuildCode

The propensity criticality (HL7 ObservationValue by default), optional.

noKnownAllergy?​

readonly optional noKnownAllergy?: boolean

Assert "No Known Allergies" (negationInd="true"), mutually exclusive with allergen.

onset?​

readonly optional onset?: string

Onset date as an HL7 date string, the Allergy Concern Act effectiveTime/low (when the allergy became a tracked concern), optional. When omitted the SHALL low is emitted as nullFlavor="UNK", never a fabricated date.

reaction?​

readonly optional reaction?: BuildCode

The reaction manifestation (SNOMED CT by default), optional.

resolution?​

readonly optional resolution?: string

Resolution date as an HL7 date string, the concern effectiveTime/high (when the concern was completed). Requires status: "resolved", exactly as a BuildCcdaProblem resolution does; buildCcda rejects a resolution date on a non-resolved allergy. A resolved allergy whose date is unknown still emits a nullFlavor="UNK" high.

severity?​

readonly optional severity?: BuildCode

The reaction's severity (SNOMED CT by default), optional.

status?​

readonly optional status?: "active" | "resolved" | "inactive"

Active / resolved / inactive; defaults to "active".

type?​

readonly optional type?: BuildCode

The propensity type, the Allergy-Intolerance Observation value (SNOMED CT by default), from the C-CDA Allergy/Intolerance Type value set: e.g. drug allergy 416098002, food allergy 414285001, environmental 426232007. Defaults to the neutral 419199007 "Allergy to substance", the builder does not guess "Drug allergy" for a non-drug allergen.


BuildCcdaEncounter​

An Encounter Activity for the Encounters section (…22.4.49). type is the coded encounter type (CPT by default, or SNOMED CT / HL7 ActEncounterCode) and is required, the template SHALL contain a code [1..1]. period is the visit/admission window emitted as the SHALL effectiveTime [1..1] (an IVL_TS); when omitted the SHALL slot is filled with a nullFlavor="UNK" low rather than a fabricated date. status maps to the optional statusCode.

Example​

import type { BuildCcdaEncounter } from "@cosyte/ccda";
const visit: BuildCcdaEncounter = {
type: { code: "99213", displayName: "Office outpatient visit 15 minutes" }, // CPT
status: "completed",
period: { low: "20230615", high: "20230615" },
};

Properties​

period?​

readonly optional period?: object

The visit/admission period as HL7 date strings (an IVL_TS low/high); either bound optional. Emitted as the SHALL effectiveTime; nullFlavor="UNK" low when omitted.

high?​

readonly optional high?: string

low?​

readonly optional low?: string

status?​

readonly optional status?: string

The encounter statusCode; defaults to "completed".

type​

readonly type: BuildCode

The coded encounter type (CPT by default, or SNOMED CT / HL7 ActEncounterCode).


BuildCcdaFamilyHistory​

One Family History Organizer (…22.4.45) for the Family History section, a single relative plus the observations (conditions) recorded for them. The relative's identity is carried once on the organizer (not flattened into each condition), so the parser reads every condition back grouped under its relative.

Example​

import type { BuildCcdaFamilyHistory } from "@cosyte/ccda";
const father: BuildCcdaFamilyHistory = {
relative: { relationship: { code: "9947008", displayName: "Father" }, deceased: true },
observations: [
{ condition: { code: "22298006", displayName: "Myocardial infarction" }, causeOfDeath: true },
],
};

Properties​

observations​

readonly observations: readonly BuildCcdaFamilyHistoryObservation[]

The conditions recorded for the relative; each becomes a Family History Observation. Must be non-empty, the organizer SHALL carry at least one observation component; pass [{}] (an unknown condition) rather than an empty list, else buildCcda throws a TypeError.

relative​

readonly relative: BuildCcdaFamilyMember

The family member this organizer describes.


BuildCcdaFamilyHistoryObservation​

A single condition recorded for a relative, one Family History Observation (…22.4.46). The illness is the coded condition (SNOMED CT by default); ageAtOnset (whole UCUM years) becomes a nested Age Observation (…22.4.31); causeOfDeath adds a Family History Death Observation (…22.4.47) marking this condition as the relative's cause of death; effectiveTime (an HL7 date string) is the SHOULD [0..1] time of the condition.

The condition is never fabricated. When condition is omitted the SHALL value is emitted as nullFlavor="UNK", an explicit unknown, never a guessed illness. ageAtOnset, causeOfDeath, and effectiveTime are optional , each emitted only when supplied, never invented.

Example​

import type { BuildCcdaFamilyHistoryObservation } from "@cosyte/ccda";
const mi: BuildCcdaFamilyHistoryObservation = {
condition: { code: "22298006", displayName: "Myocardial infarction" }, // SNOMED CT
ageAtOnset: 57,
causeOfDeath: true,
};

Properties​

ageAtOnset?​

readonly optional ageAtOnset?: number

The relative's age at onset in whole years, a nested Age Observation, emitted only when supplied.

causeOfDeath?​

readonly optional causeOfDeath?: boolean

When true, marks this condition as the relative's cause of death (Family History Death Observation).

condition?​

readonly optional condition?: BuildCode

The coded condition the relative had (SNOMED CT default). Omit for an explicit unknown (value nullFlavor="UNK"), never guessed.

effectiveTime?​

readonly optional effectiveTime?: string

The time/date of the condition (HL7 date string); the SHOULD [0..1] effectiveTime, emitted only when supplied.


BuildCcdaFamilyMember​

The relative a BuildCcdaFamilyHistory organizer describes, the family member whose conditions the organizer records. Emitted as the organizer's subject/relatedSubject (a @classCode="PRS" personal relationship).

The relationship is never fabricated. relationship is the coded relation of the relative to the patient, SNOMED CT by default (e.g. 72705000 mother, 9947008 father, 394859005… ), overridable via codeSystem (e.g. the HL7 RoleCode FTH/MTH on 2.16.840.1.113883.5.111). When omitted, the SHALL relatedSubject/code is emitted as nullFlavor="UNK", an explicit unknown relation, never guessed. gender (an HL7 AdministrativeGender code, e.g. "M"/"F"), birthTime (an HL7 date string), and deceased (the sdtc:deceasedInd flag) are all optional MAY elements, each emitted only when supplied, never fabricated.

Example​

import type { BuildCcdaFamilyMember } from "@cosyte/ccda";
const mother: BuildCcdaFamilyMember = {
relationship: { code: "72705000", displayName: "Mother" }, // SNOMED CT
gender: "F",
deceased: true,
};

Properties​

birthTime?​

readonly optional birthTime?: string

The relative's birth date (HL7 date string); emitted only when supplied.

deceased?​

readonly optional deceased?: boolean

Whether the relative is deceased (sdtc:deceasedInd); emitted only when supplied.

gender?​

readonly optional gender?: string

The relative's HL7 AdministrativeGender code (e.g. "M"/"F"); emitted only when supplied.

relationship?​

readonly optional relationship?: BuildCode

The coded relationship of the relative to the patient (SNOMED CT default). Omit for an explicit unknown (relatedSubject/code nullFlavor="UNK"), never guessed.


BuildCcdaFunctionalStatus​

A Functional Status finding for the Functional Status section, a Functional Status Observation (…22.4.67, the 2014-06-09 stamp). The observation's code is fixed to LOINC 54522-8 "Functional status" by the template; the specific finding is the coded value. value is the SNOMED CT finding (e.g. able to walk 165245003, dependent on wheelchair 105503008, self-care 129019007).

Functional and mental status are never conflated. This builds only the Functional Status templates (section …22.2.14, observation …22.4.67), so the parser reads every finding back tagged domain: "functional", a functional finding is never filed under mental status (or vice versa).

Unknown is never defaulted to a finding. When value is omitted the observation's SHALL value is emitted as nullFlavor="UNK", an explicit unknown, never invented as a real finding. effectiveTime is when the status was assessed; the template's SHALL effectiveTime is filled with nullFlavor="UNK" when the caller supplies none, never a fabricated date.

Example​

import type { BuildCcdaFunctionalStatus } from "@cosyte/ccda";
const ambulation: BuildCcdaFunctionalStatus = {
value: { code: "165245003", displayName: "Able to walk" }, // SNOMED CT
effectiveTime: "20240101",
};
const unrecorded: BuildCcdaFunctionalStatus = {}; // → value nullFlavor="UNK"

Properties​

effectiveTime?​

readonly optional effectiveTime?: string

The date the status was assessed (HL7 date string); nullFlavor="UNK" when omitted.

value?​

readonly optional value?: BuildCode

The SNOMED CT functional-status finding (the observation value). Omit for an explicit unknown (value nullFlavor="UNK"), never defaulted to a real finding.


BuildCcdaFunctionalStatusOrganizer​

A Functional Status Organizer for the Functional Status section, a Functional Status Organizer (…22.4.66, the 2014-06-09 stamp, @classCode="CLUSTER") that groups two or more related Functional Status Observations (…22.4.67) under one categorization. Use it instead of standalone findings when the assessment is a cluster (e.g. all self-care ADLs recorded together); each grouped observation is otherwise identical to a standalone BuildCcdaFunctionalStatus and reads back tagged domain: "functional".

code is the organizer's categorization, not a finding. It SHALL be present [1..1] and SHOULD be drawn from ICF (2.16.840.1.113883.6.254) or LOINC, pass the ICF chapter/category (e.g. d5 "Self-care") via code with its codeSystem. When omitted the SHALL code is emitted as nullFlavor="UNK", an explicit unknown category, never a fabricated one. codeSystem defaults to LOINC when a code is supplied without one.

findings must be non-empty. The organizer SHALL contain at least one [1..*] Functional Status Observation; an empty organizer is a TypeError (never an organizer emitted with zero members). The Assessment Scale Observation (…22.4.69), a scored scale such as a Barthel index, is a direct section entry in C-CDA R2.1, not an organizer component; only status observations are grouped here.

Example​

import type { BuildCcdaFunctionalStatusOrganizer } from "@cosyte/ccda";
const selfCare: BuildCcdaFunctionalStatusOrganizer = {
code: { code: "d5", displayName: "Self-care", codeSystem: "2.16.840.1.113883.6.254" }, // ICF
effectiveTime: "20240101",
findings: [
{ value: { code: "129019007", displayName: "Self-care" } }, // SNOMED CT
{ value: { code: "165245003", displayName: "Able to walk" } },
],
};

Properties​

code?​

readonly optional code?: BuildCode

The organizer's categorization code (SHOULD be ICF or LOINC). Omit for an explicit unknown (code nullFlavor="UNK"), never a fabricated category. codeSystem defaults to LOINC when a code is supplied without one.

effectiveTime?​

readonly optional effectiveTime?: string

When the grouped assessment was performed (HL7 date string); omitted (not fabricated) when absent.

findings​

readonly findings: readonly BuildCcdaFunctionalStatus[]

The Functional Status Observations grouped by this organizer. Must be non-empty, the organizer SHALL contain at least one member.


BuildCcdaImmunization​

An Immunization Activity for the Immunizations section. vaccine is the CVX coded product (CVX by default). dose and route are optional and never guessed, an omitted one is simply left absent. refused: true emits the administration with negationInd="true" (a not-administered / refused record), which the parser reads back as refused and flags IMMUNIZATION_REFUSED, the clinically load-bearing refusal is surfaced, never conflated with a nullFlavor "unknown". effectiveTime is the administration date; when omitted the SHALL slot is filled with nullFlavor="UNK".

Example​

import type { BuildCcdaImmunization } from "@cosyte/ccda";
const flu: BuildCcdaImmunization = {
vaccine: { code: "140", displayName: "Influenza, split virus, trivalent, injectable, preservative free" }, // CVX
dose: { value: 0.5, unit: "mL" },
route: { code: "C28161", displayName: "Intramuscular" }, // NCI Thesaurus
effectiveTime: "20240101",
};
const refused: BuildCcdaImmunization = {
vaccine: { code: "140", displayName: "Influenza, split virus, trivalent, injectable, preservative free" },
refused: true,
};

Properties​

dose?​

readonly optional dose?: BuildQuantity

The amount administered (doseQuantity), optional, never defaulted.

effectiveTime?​

readonly optional effectiveTime?: string

The administration date as an HL7 date string; nullFlavor="UNK" when omitted.

refused?​

readonly optional refused?: boolean

Emit a refused / not-administered record (negationInd="true"); parser flags IMMUNIZATION_REFUSED.

route?​

readonly optional route?: BuildCode

The administration route (routeCode); NCI Thesaurus by default.

status?​

readonly optional status?: string

The statusCode; defaults to "completed".

vaccine​

readonly vaccine: BuildCode

The CVX-coded vaccine product (CVX by default).


BuildCcdaInit​

Input to buildCcda. patient is required; each clinical collection backing a CCD SHALL section (problems, allergies, medications, results, vitalSigns, smokingStatus) defaults to empty, in which case its section is emitted as a spec-clean empty nullFlavor="NI" section. immunizations is optional, its section is emitted only when populated (Immunizations is not a CCD SHALL section). documentType is "ccd" (the default) or "referralNote"; the other ten C-CDA R2.1 document types are not implemented.

Example​

import type { BuildCcdaInit } from "@cosyte/ccda";
const init: BuildCcdaInit = {
patient: { mrn: "MRN001", given: ["Jane"], family: "Doe", gender: "F" },
problems: [{ problem: { code: "59621000", displayName: "Essential hypertension" } }],
allergies: [{ noKnownAllergy: true }],
};

Properties​

allergies?​

readonly optional allergies?: readonly BuildCcdaAllergy[]

Allergy Concerns for the Allergies section; empty section when omitted.

assessment?​

readonly optional assessment?: string

The Assessment Section narrative (documentType: "referralNote" only, a Referral Note SHALL section). Narrative-only, so this is a free-text clinician summary; when omitted the SHALL section is emitted as a spec-clean empty nullFlavor="NI" section (never a fabricated assessment). Ignored for a CCD.

confidentiality?​

readonly optional confidentiality?: string

The confidentiality code; defaults to "N" (normal).

custodianName?​

readonly optional custodianName?: string

The custodian organization name; defaults to a synthetic label.

documentId?​

readonly optional documentId?: string

The document id's extension; a synthetic id is generated when omitted.

documentType?​

readonly optional documentType?: "ccd" | "referralNote"

The document type, "ccd" (default) or "referralNote". Each specializes the US Realm Header (its own document templateId + LOINC code) and its SHALL section set; the other ten C-CDA R2.1 document types are not emitted.

effectiveTime?​

readonly optional effectiveTime?: string | Date

The document effectiveTime (a Date is formatted to UTC); defaults to now.

encounters?​

readonly optional encounters?: readonly BuildCcdaEncounter[]

Encounter Activities; the Encounters section is emitted only when non-empty (a CCD SHOULD section).

familyHistory?​

readonly optional familyHistory?: readonly BuildCcdaFamilyHistory[]

Family history for the Family History section; the section is emitted only when non-empty (a CCD SHOULD section). Each entry is one relative (a Family History Organizer) carrying that relative's conditions, read back via getFamilyHistory, grouped by relative.

functionalStatus?​

readonly optional functionalStatus?: readonly BuildCcdaFunctionalStatus[]

Standalone Functional Status findings; the Functional Status section is emitted when this or functionalStatusOrganizers is non-empty (a CCD SHOULD section).

functionalStatusOrganizers?​

readonly optional functionalStatusOrganizers?: readonly BuildCcdaFunctionalStatusOrganizer[]

Functional Status Organizers (each grouping ≥1 Functional Status Observation under one categorization); emitted into the Functional Status section alongside any standalone functionalStatus findings. The section is emitted when either is non-empty.

functionalStatusScales?​

readonly optional functionalStatusScales?: readonly BuildCcdaAssessmentScale[]

Direct-entry Assessment Scale Observations (…22.4.69) for the Functional Status section, scored instruments (e.g. a Barthel index, a Glasgow Coma scale). Emitted as direct section entries (the conformant R2.1 placement), read back tagged assessmentScale: true, domain: "functional". The Functional Status section is emitted when this, functionalStatus, or functionalStatusOrganizers is non-empty.

immunizations?​

readonly optional immunizations?: readonly BuildCcdaImmunization[]

Immunization Activities; the Immunizations section is emitted only when non-empty.

languageCode?​

readonly optional languageCode?: string

The document language; defaults to "en-US".

medications?​

readonly optional medications?: readonly BuildCcdaMedication[]

Medication Activities for the Medications section; empty section when omitted.

mentalStatus?​

readonly optional mentalStatus?: readonly BuildCcdaMentalStatus[]

Standalone Mental Status findings; the Mental Status section is emitted when this or mentalStatusOrganizers is non-empty (a CCD SHOULD section).

mentalStatusOrganizers?​

readonly optional mentalStatusOrganizers?: readonly BuildCcdaMentalStatusOrganizer[]

Mental Status Organizers (each grouping ≥1 Mental Status Observation under one categorization); emitted into the Mental Status section alongside any standalone mentalStatus findings. The section is emitted when either is non-empty.

mentalStatusScales?​

readonly optional mentalStatusScales?: readonly BuildCcdaAssessmentScale[]

Direct-entry Assessment Scale Observations (…22.4.69) for the Mental Status section, scored instruments (e.g. a PHQ-9 depression screen, a MoCA). Emitted as direct section entries (the conformant R2.1 placement), read back tagged assessmentScale: true, domain: "mental". The Mental Status section is emitted when this, mentalStatus, or mentalStatusOrganizers is non-empty.

pastMedicalHistory?​

readonly optional pastMedicalHistory?: readonly BuildCcdaProblem[]

Historical problems for the Past Medical History section; the section is emitted only when non-empty (a CCD MAY section). Each is a bare Problem Observation (not a concern act), read back via getPastMedicalHistory, never conflated with the active Problems returned by getProblems.

patient​

readonly patient: BuildCcdaPatient

The single record-target patient (required).

planOfTreatment?​

readonly optional planOfTreatment?: readonly BuildCcdaPlannedItem[]

Planned items for the Plan of Treatment section; the section is emitted only when non-empty (a CCD SHOULD section). Every item is future/ordered, read back via getPlannedItems with disposition: "planned", never conflated with the performed Procedures/Encounters.

problems?​

readonly optional problems?: readonly BuildCcdaProblem[]

Problem Concerns for the Problems section; empty section when omitted.

procedures?​

readonly optional procedures?: readonly BuildCcdaProcedure[]

Procedures; the Procedures section is emitted only when non-empty (a CCD SHOULD section).

reasonForReferral?​

readonly optional reasonForReferral?: string

The Reason for Referral Section narrative (documentType: "referralNote" only, a Referral Note SHALL section). Narrative-only free text; when omitted the SHALL section is emitted as an empty nullFlavor="NI" section (never a fabricated reason). Ignored for a CCD.

results?​

readonly optional results?: readonly BuildCcdaResultPanel[]

Result panels for the Results section; empty section when omitted.

smokingStatus?​

readonly optional smokingStatus?: readonly BuildCcdaSmokingStatus[]

Smoking Status observations for the Social History section. Social History is a CCD SHALL section (CONF:1198-30688), so for a CCD the section is always emitted, as a nullFlavor="NI" shell when this is empty. For document types whose SHALL set excludes it, the section is emitted only when non-empty.

title?​

readonly optional title?: string

The document title; defaults to the CCD document-code display name.

vitalSigns?​

readonly optional vitalSigns?: readonly BuildCcdaVitalsPanel[]

Vital Signs panels for the Vital Signs section; empty section when omitted.


BuildCcdaMedication​

A Medication Activity for the Medications section. drug is the RxNorm coded product (RxNorm by default). dose, route, frequency, and duration are all optional and never guessed: an omitted dose/route is emitted as absent, which the parser then flags (MISSING_DOSE_QUANTITY / MISSING_ROUTE_CODE) rather than being defaulted to a confident-wrong value. frequency is the periodic timing (a PIVL_TS period, e.g. every 8 hours); duration is the therapy window (an IVL_TS low/high), the two are emitted as distinct effectiveTime siblings, never conflated.

Example​

import type { BuildCcdaMedication } from "@cosyte/ccda";
const lisinopril: BuildCcdaMedication = {
drug: { code: "314076", displayName: "Lisinopril 10 MG Oral Tablet" },
dose: { value: 1, unit: "{tablet}" },
route: { code: "C38288", displayName: "Oral" },
frequency: { value: 24, unit: "h" },
};

Properties​

dose?​

readonly optional dose?: BuildQuantity

The dose per administration (doseQuantity); absent → parser flags it.

drug​

readonly drug: BuildCode

The coded drug product (RxNorm by default, or NDC).

duration?​

readonly optional duration?: object

The therapy window (IVL_TS) as HL7 date strings; either bound optional.

high?​

readonly optional high?: string

low?​

readonly optional low?: string

frequency?​

readonly optional frequency?: BuildQuantity

The periodic dosing frequency, a PIVL_TS period (e.g. { value: 8, unit: "h" }).

route?​

readonly optional route?: BuildCode

The administration route (routeCode); NCI Thesaurus by default.

status?​

readonly optional status?: "active" | "resolved" | "inactive"

Active / resolved / inactive; maps to the statusCode. Defaults to "active".


BuildCcdaMentalStatus​

A Mental Status finding for the Mental Status section, a Mental Status Observation (…22.4.74, the R2.1 2015-08-01 stamp). The observation's code is fixed to SNOMED CT 373930000 "Cognitive function finding" by the R2.1 template; the specific cognition/mood finding is the coded value (e.g. memory impairment 386807006, no abnormality detected 281900007, SNOMED CT).

Mental and functional status are never conflated. This builds only the Mental Status templates (section …22.2.56, observation …22.4.74), so the parser reads every finding back tagged domain: "mental", a mental finding is never filed under functional status (or vice versa); the two extractors key off their distinct observation template roots.

Unknown is never defaulted to a finding. When value is omitted the observation's SHALL value is emitted as nullFlavor="UNK", an explicit unknown, never invented as a real finding. effectiveTime is when the status was assessed; the template's SHALL effectiveTime is filled with nullFlavor="UNK" when the caller supplies none, never a fabricated date.

Example​

import type { BuildCcdaMentalStatus } from "@cosyte/ccda";
const memory: BuildCcdaMentalStatus = {
value: { code: "386807006", displayName: "Memory impairment" }, // SNOMED CT
effectiveTime: "20240101",
};
const unrecorded: BuildCcdaMentalStatus = {}; // → value nullFlavor="UNK"

Properties​

effectiveTime?​

readonly optional effectiveTime?: string

The date the status was assessed (HL7 date string); nullFlavor="UNK" when omitted.

value?​

readonly optional value?: BuildCode

The SNOMED CT mental-status finding (the observation value). Omit for an explicit unknown (value nullFlavor="UNK"), never defaulted to a real finding.


BuildCcdaMentalStatusOrganizer​

A Mental Status Organizer for the Mental Status section, a Mental Status Organizer (…22.4.75, the R2.1 2015-08-01 stamp, @classCode="CLUSTER") that groups two or more related Mental Status Observations (…22.4.74) under one categorization. Use it instead of standalone findings when the assessment is a cluster (e.g. an orientation battery); each grouped observation is otherwise identical to a standalone BuildCcdaMentalStatus and reads back tagged domain: "mental", never conflated with functional status (the two key off distinct organizer/observation roots).

code is the organizer's categorization, not a finding. It SHALL be present [1..1] and SHOULD be drawn from ICF (2.16.840.1.113883.6.254) or LOINC. When omitted the SHALL code is emitted as nullFlavor="UNK", an explicit unknown category, never fabricated. codeSystem defaults to LOINC when a code is supplied without one.

findings must be non-empty. The organizer SHALL contain at least one [1..*] Mental Status Observation; an empty organizer is a TypeError. The Assessment Scale Observation (…22.4.69) is a direct section entry in R2.1, not an organizer component.

Example​

import type { BuildCcdaMentalStatusOrganizer } from "@cosyte/ccda";
const cognition: BuildCcdaMentalStatusOrganizer = {
effectiveTime: "20240101",
findings: [
{ value: { code: "386807006", displayName: "Memory impairment" } }, // SNOMED CT
{ value: { code: "247663003", displayName: "Orientation finding" } },
],
};

Properties​

code?​

readonly optional code?: BuildCode

The organizer's categorization code (SHOULD be ICF or LOINC). Omit for an explicit unknown (code nullFlavor="UNK"), never a fabricated category. codeSystem defaults to LOINC when a code is supplied without one.

effectiveTime?​

readonly optional effectiveTime?: string

When the grouped assessment was performed (HL7 date string); omitted (not fabricated) when absent.

findings​

readonly findings: readonly BuildCcdaMentalStatus[]

The Mental Status Observations grouped by this organizer. Must be non-empty, the organizer SHALL contain at least one member.


BuildCcdaOptions​

Options for buildCcda. Every field is optional, buildCcda(init) is valid and produces the default behavior.

Example​

import type { BuildCcdaOptions, TerminologyAdapter } from "@cosyte/ccda";
const adapter: TerminologyAdapter = { validateCode: (c) => ({ result: myService.has(c.code) }) };
const opts: BuildCcdaOptions = { terminology: adapter };

Properties​

terminology?​

readonly optional terminology?: TerminologyAdapter

An optional consumer-supplied bring-your-own TerminologyAdapter. Two paths consume it: (1) its validateCode is forwarded to the internal re-parse so a built document surfaces SEMANTIC_CODE_INVALID for any coded value the adapter rejects; (2) its optional translate is consulted at each clinical coded slot (problem value, allergen, medication drug + route, vaccine + route) to emit <translation> alternate codings beside the primary code. The builder never coerces a code to satisfy the adapter, it emits every primary value verbatim, a <translation> is only ever an additional alternate, and an adapter with no translate opinion produces byte-identical output. Omit for the default behavior.


BuildCcdaPatient​

A patient for the document's single recordTarget. Every field is optional; an omitted demographic is emitted as a spec-clean nullFlavor="UNK" rather than invented. Supply mrn to set the patient identifier the parser returns from CcdaDocument.getMrn.

Example​

import type { BuildCcdaPatient } from "@cosyte/ccda";
const patient: BuildCcdaPatient = {
mrn: "MRN001",
given: ["Jane"],
family: "Doe",
gender: "F",
birthTime: "19800101",
};

Properties​

birthTime?​

readonly optional birthTime?: string

Birth time as an HL7 date/datetime string (e.g. "19800101").

family?​

readonly optional family?: string

gender?​

readonly optional gender?: string

Administrative gender code (M / F / UN), HL7 AdministrativeGender.

given?​

readonly optional given?: readonly string[]

mrn?​

readonly optional mrn?: string

The medical record number (the patientRole/id/@extension).

mrnAssigningAuthority?​

readonly optional mrnAssigningAuthority?: string

The assigning-authority name for the MRN; defaults to a synthetic label.

mrnRoot?​

readonly optional mrnRoot?: string

The assigning-authority OID for the MRN; defaults to a synthetic root.

prefix?​

readonly optional prefix?: readonly string[]

suffix?​

readonly optional suffix?: readonly string[]


BuildCcdaPlannedAct​

A planned Act / Encounter / Procedure (…4.39 / …4.40 / …4.41). mood accepts the full Planned moodCode value set including the appointment moods (APT/ARQ), which are valid on these element domains. Default code system: SNOMED CT for an act/procedure, CPT for an encounter.

Example​

import type { BuildCcdaPlannedAct } from "@cosyte/ccda";
const visit: BuildCcdaPlannedAct = {
kind: "encounter",
code: { code: "99213", displayName: "Office outpatient visit 15 minutes" },
mood: "APT",
};

Extends​

  • BuildCcdaPlannedItemBase

Properties​

code​

readonly code: BuildCode

The planned act/observation/drug code; default code system varies by kind.

Inherited from​

BuildCcdaPlannedItemBase.code

effectiveTime?​

readonly optional effectiveTime?: string

The planned time as an HL7 date string; emitted only when supplied, never fabricated.

[0..1] is the cardinality on five of the seven templates, not on all of them. Both substanceAdministration variants SHALL carry exactly one: Planned Medication Activity (…4.42, CONF:1098-30468) and Planned Immunization Activity (…4.120). BuildCcdaPlannedImmunization redeclares this field as required, which is why omitting it there is a type error; BuildCcdaPlannedOrder does not, so buildCcda will emit a Planned Medication Activity short that SHALL element if you leave it out.

The field stays optional, and the omission is REPORTED rather than silent BY buildCcda. Making it required would be a breaking change to a published input type, so the decision taken was to keep the type as it is and have buildCcda raise MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME on the returned document. The document is still emitted, still short that element, and no date is ever fabricated to fill it.

editCcda reports it too, so a planned medication grafted in by an edit is no longer emitted short the SHALL element in silence. Its check is scoped to the sections that call grafted and that survived into the emitted document: an offending edit a later edit in the same call discarded says nothing (reading the caller's ordered edit list instead reports a violation against a conformant document), and an offending act the source already carried is never re-reported. So the absence of this code from editCcda(...).warnings says only that the sections that call wrote carry no planned medication short this element; it says nothing about the rest of the document, and nothing about any other conformance rule.

Inherited from​

BuildCcdaPlannedItemBase.effectiveTime

kind​

readonly kind: "procedure" | "act" | "encounter"

mood?​

readonly optional mood?: PlannedActMood

The planned @moodCode; defaults to "INT". Appointment moods allowed here.


BuildCcdaPlannedImmunization​

A planned Immunization Activity (…4.120). mood excludes the appointment moods, the same substanceAdministration domain a BuildCcdaPlannedOrder draws on. code is the vaccine, emitted in the consumable (Immunization Medication Information …4.54) and defaulting to CVX, never RxNorm: the two substanceAdministration planned variants have different default systems because their slot bindings differ.

effectiveTime is required here because the template requires it, and the builder is conservative on emit, so the type requires what the template requires rather than emitting a document short a SHALL element or fabricating a date the caller never supplied. C-CDA makes effectiveTime [1..1] on this template, "the time that the immunization activity should occur".

Do not read that as "this is the only planned template that requires it". C-CDA makes effectiveTime [1..1] on both substanceAdministration planned variants: Planned Medication Activity (…4.42) SHALL carry exactly one too (CONF:1098-30468). It is the other five (…4.39, …4.40, …4.41, …4.43, …4.44) that make it [0..1]. BuildCcdaPlannedOrder still types effectiveTime as optional for its medicationActivity arm, so buildCcda can emit a Planned Medication Activity short that SHALL element. Making the field required on BuildCcdaPlannedOrder would be a breaking change to a published type, so the field stands as it is and the omission is reported instead (MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME, raised by both writers on the document they emit, never by parseCcda). No such diagnostic exists for this template, and adding one would be dead code: omitting the field here does not compile.

Example​

import type { BuildCcdaPlannedImmunization } from "@cosyte/ccda";
const dueFluShot: BuildCcdaPlannedImmunization = {
kind: "immunizationActivity",
code: { code: "140", displayName: "Influenza, split virus, trivalent, injectable, preservative free" },
effectiveTime: "20241001",
};

Extends​

  • BuildCcdaPlannedItemBase

Properties​

code​

readonly code: BuildCode

The planned act/observation/drug code; default code system varies by kind.

Inherited from​

BuildCcdaPlannedItemBase.code

effectiveTime​

readonly effectiveTime: string

When the immunization should occur. Required: the template makes it [1..1].

Overrides​

BuildCcdaPlannedItemBase.effectiveTime

kind​

readonly kind: "immunizationActivity"

mood?​

readonly optional mood?: PlannedOrderMood

The planned @moodCode; defaults to "INT". Appointment moods not representable.


BuildCcdaPlannedObservation​

A planned Observation (…4.44). mood excludes the appointment moods (not in x_ActMoodDocumentObservation). value is the expected coded result (a goal/target, SNOMED CT by default), emitted only when supplied. Default code system for the observation code: LOINC.

Example​

import type { BuildCcdaPlannedObservation } from "@cosyte/ccda";
const cbc: BuildCcdaPlannedObservation = {
kind: "observation",
code: { code: "58410-2", displayName: "CBC panel" }, // LOINC
mood: "RQO",
effectiveTime: "20240801",
};

Extends​

  • BuildCcdaPlannedItemBase

Properties​

code​

readonly code: BuildCode

The planned act/observation/drug code; default code system varies by kind.

Inherited from​

BuildCcdaPlannedItemBase.code

effectiveTime?​

readonly optional effectiveTime?: string

The planned time as an HL7 date string; emitted only when supplied, never fabricated.

[0..1] is the cardinality on five of the seven templates, not on all of them. Both substanceAdministration variants SHALL carry exactly one: Planned Medication Activity (…4.42, CONF:1098-30468) and Planned Immunization Activity (…4.120). BuildCcdaPlannedImmunization redeclares this field as required, which is why omitting it there is a type error; BuildCcdaPlannedOrder does not, so buildCcda will emit a Planned Medication Activity short that SHALL element if you leave it out.

The field stays optional, and the omission is REPORTED rather than silent BY buildCcda. Making it required would be a breaking change to a published input type, so the decision taken was to keep the type as it is and have buildCcda raise MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME on the returned document. The document is still emitted, still short that element, and no date is ever fabricated to fill it.

editCcda reports it too, so a planned medication grafted in by an edit is no longer emitted short the SHALL element in silence. Its check is scoped to the sections that call grafted and that survived into the emitted document: an offending edit a later edit in the same call discarded says nothing (reading the caller's ordered edit list instead reports a violation against a conformant document), and an offending act the source already carried is never re-reported. So the absence of this code from editCcda(...).warnings says only that the sections that call wrote carry no planned medication short this element; it says nothing about the rest of the document, and nothing about any other conformance rule.

Inherited from​

BuildCcdaPlannedItemBase.effectiveTime

kind​

readonly kind: "observation"

mood?​

readonly optional mood?: PlannedOrderMood

The planned @moodCode; defaults to "INT". Appointment moods not representable.

value?​

readonly optional value?: BuildCode

The expected coded result value (xsi:type="CD", SNOMED CT default), the plan's goal/target. Emitted only when supplied; never fabricated.


BuildCcdaPlannedOrder​

A planned Medication Activity or Supply (…4.42 / …4.43). mood excludes the appointment moods (not in these elements' base mood domain). The drug/supply code defaults to RxNorm (medication, emitted in the consumable) / SNOMED CT (supply).

Example​

import type { BuildCcdaPlannedOrder } from "@cosyte/ccda";
const order: BuildCcdaPlannedOrder = {
kind: "medicationActivity",
code: { code: "314076", displayName: "Lisinopril 10 MG Oral Tablet" },
mood: "RQO",
};

Extends​

  • BuildCcdaPlannedItemBase

Properties​

code​

readonly code: BuildCode

The planned act/observation/drug code; default code system varies by kind.

Inherited from​

BuildCcdaPlannedItemBase.code

effectiveTime?​

readonly optional effectiveTime?: string

The planned time as an HL7 date string; emitted only when supplied, never fabricated.

[0..1] is the cardinality on five of the seven templates, not on all of them. Both substanceAdministration variants SHALL carry exactly one: Planned Medication Activity (…4.42, CONF:1098-30468) and Planned Immunization Activity (…4.120). BuildCcdaPlannedImmunization redeclares this field as required, which is why omitting it there is a type error; BuildCcdaPlannedOrder does not, so buildCcda will emit a Planned Medication Activity short that SHALL element if you leave it out.

The field stays optional, and the omission is REPORTED rather than silent BY buildCcda. Making it required would be a breaking change to a published input type, so the decision taken was to keep the type as it is and have buildCcda raise MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME on the returned document. The document is still emitted, still short that element, and no date is ever fabricated to fill it.

editCcda reports it too, so a planned medication grafted in by an edit is no longer emitted short the SHALL element in silence. Its check is scoped to the sections that call grafted and that survived into the emitted document: an offending edit a later edit in the same call discarded says nothing (reading the caller's ordered edit list instead reports a violation against a conformant document), and an offending act the source already carried is never re-reported. So the absence of this code from editCcda(...).warnings says only that the sections that call wrote carry no planned medication short this element; it says nothing about the rest of the document, and nothing about any other conformance rule.

Inherited from​

BuildCcdaPlannedItemBase.effectiveTime

kind​

readonly kind: "medicationActivity" | "supply"

mood?​

readonly optional mood?: PlannedOrderMood

The planned @moodCode; defaults to "INT". Appointment moods not representable.


BuildCcdaProblem​

A Problem Concern for the Problems section. The coded problem (SNOMED CT by default, or ICD-10-CM) is the condition; status maps to the concern act's status (active/resolved/inactive) and is never guessed.

onset is the condition's onset date (the concern/observation effectiveTime low); resolution is its resolution date (the high, a.k.a. "resolution date", when the condition became biologically resolved). Per the C-CDA R2.1 Problem Observation (…22.4.4) rule the presence of a high, whether a real date or nullFlavor="UNK", itself asserts the problem is resolved, so a resolution is only meaningful on a resolved concern: buildCcda throws when resolution is supplied without status: "resolved" rather than emit a completion date on a still-active problem. A resolved problem whose resolution date is unknown still emits a nullFlavor="UNK" high (the SHALL form), never a fabricated date.

Example​

import type { BuildCcdaProblem } from "@cosyte/ccda";
const p: BuildCcdaProblem = {
problem: { code: "59621000", displayName: "Essential hypertension" },
status: "active",
onset: "20210101",
};
const resolved: BuildCcdaProblem = {
problem: { code: "195967001", displayName: "Asthma" },
status: "resolved",
onset: "20180301",
resolution: "20220615",
};

Properties​

onset?​

readonly optional onset?: string

Onset date as an HL7 date string (e.g. "20210101"), the effectiveTime/low, optional.

problem​

readonly problem: BuildCode

The coded condition (SNOMED CT default, or ICD-10-CM).

resolution?​

readonly optional resolution?: string

Resolution date as an HL7 date string (the effectiveTime/high, a.k.a. "resolution date"). Requires status: "resolved", a resolution date on a non-resolved problem is a contradiction buildCcda rejects. Omitting it on a resolved problem still emits a nullFlavor="UNK" high.

status?​

readonly optional status?: "active" | "resolved" | "inactive"

Active / resolved / inactive; defaults to "active".


BuildCcdaProcedure​

A Procedure for the Procedures section. kind selects the C-CDA Procedure Activity variant, an altering/operative "procedure" (default, <procedure> …22.4.14), a non-altering "act" service (<act> …22.4.12), or an assessment "observation" (<observation> …22.4.13). code is the coded procedure (SNOMED CT by default, or CPT / ICD-10-PCS / LOINC) and is required (the template SHALL contain a code). disposition maps to the act's moodCode, performed (EVN) vs planned (INT), which the parser reads back as its performed-vs-planned disposition; the two are never conflated. effectiveTime is emitted only when supplied (the template's effectiveTime is SHOULD [0..1], CONF:1098-7662, not fabricated when unknown).

Example​

import type { BuildCcdaProcedure } from "@cosyte/ccda";
const appendectomy: BuildCcdaProcedure = {
code: { code: "80146002", displayName: "Appendectomy" },
disposition: "performed",
effectiveTime: "20230615",
};
const plannedColonoscopy: BuildCcdaProcedure = {
code: { code: "73761001", displayName: "Colonoscopy" },
disposition: "planned",
};

Properties​

code​

readonly code: BuildCode

The coded procedure (SNOMED CT by default, or CPT / ICD-10-PCS / LOINC).

disposition?​

readonly optional disposition?: "performed" | "planned"

Performed (EVN) or planned (INT); defaults to "performed". Never conflated.

effectiveTime?​

readonly optional effectiveTime?: string

The procedure date as an HL7 date string; emitted only when supplied (SHOULD [0..1]).

kind?​

readonly optional kind?: ProcedureKind

The Procedure Activity variant; defaults to "procedure" (operative).

status?​

readonly optional status?: string

The statusCode; defaults per disposition (performed → "completed", planned → "active"). SHALL [1..1] on the template, so always emitted.

value?​

readonly optional value?: BuildCode

The coded result value (xsi:type="CD", SNOMED CT default). Required for the "observation" variant, Procedure Activity Observation (…22.4.13) SHALL contain a value [1..1], and ignored for the other two variants; buildCcda throws if a "observation" procedure omits it.


BuildCcdaResult​

One member observation of a Results panel, a Result Observation. test is the LOINC test code. Exactly one value form is required: a UCUM quantity (xsi:type="PQ"), a codedValue (xsi:type="CD"), or a stringValue (xsi:type="ST"), the builder throws if none (or more than one) is set, so a result value is never silently dropped or invented. referenceRange (when given) is emitted as a structured IVL_PQ so it round-trips numerically.

Example​

import type { BuildCcdaResult } from "@cosyte/ccda";
const glucose: BuildCcdaResult = {
test: { code: "2345-7", displayName: "Glucose" },
quantity: { value: 95, unit: "mg/dL" },
referenceRange: { low: { value: 70, unit: "mg/dL" }, high: { value: 100, unit: "mg/dL" } },
interpretation: { code: "N", displayName: "Normal" },
};

Properties​

codedValue?​

readonly optional codedValue?: BuildCode

A CD value. Exactly one of quantity/codedValue/stringValue.

effectiveTime?​

readonly optional effectiveTime?: string

The observation time as an HL7 date string, optional.

interpretation?​

readonly optional interpretation?: BuildCode

The H/L/N interpretation (HL7 ObservationInterpretation by default), optional.

quantity?​

readonly optional quantity?: BuildQuantity

A PQ value (UCUM). Exactly one of quantity/codedValue/stringValue.

referenceRange?​

readonly optional referenceRange?: object

The normal interval, emitted as a structured IVL_PQ; either bound optional.

high?​

readonly optional high?: BuildQuantity

low?​

readonly optional low?: BuildQuantity

stringValue?​

readonly optional stringValue?: string

A free-text (ST) value. Exactly one of quantity/codedValue/stringValue.

test​

readonly test: BuildCode

The LOINC test code.


BuildCcdaResultPanel​

A Results panel, a Result Organizer (the battery/panel wrapper, e.g. a CBC) around one or more BuildCcdaResult member observations. code is the panel LOINC; status maps to the organizer statusCode (default "completed").

Example​

import type { BuildCcdaResultPanel } from "@cosyte/ccda";
const cmp: BuildCcdaResultPanel = {
code: { code: "24323-8", displayName: "Comprehensive metabolic panel" },
results: [{ test: { code: "2345-7", displayName: "Glucose" }, quantity: { value: 95, unit: "mg/dL" } }],
};

Properties​

code​

readonly code: BuildCode

The panel/battery LOINC code.

effectiveTime?​

readonly optional effectiveTime?: string

The panel's span/collection time as an HL7 date string. Emitted as the organizer's effectiveTime; when omitted the SHALL slot is filled with nullFlavor="UNK" (the member observations still carry their own times).

results​

readonly results: readonly BuildCcdaResult[]

The member Result Observations (at least one for a populated panel).

status?​

readonly optional status?: string

The organizer statusCode; defaults to "completed".


BuildCcdaSmokingStatus​

A Smoking Status observation for the Social History section, the Smoking Status, Meaningful Use observation (…22.4.78), the safety-relevant social-history fact most consumers ask for. value is the SNOMED CT concept from the Current Smoking Status value set (2.16.840.1.113883.11.20.9.38, e.g. former smoker 8517006, never smoker 266919005, current every-day smoker 449868002).

Unknown is never defaulted to a status. When value is omitted the observation's SHALL value is emitted as nullFlavor="UNK", an explicit unknown that the parser reads back as unknown: true (and flags SMOKING_STATUS_UNKNOWN). The builder will never invent a "never smoker" (or any other) reading the caller did not supply: absent status ≠ non-smoker. effectiveTime is when the status was recorded; nullFlavor="UNK" when omitted.

Example​

import type { BuildCcdaSmokingStatus } from "@cosyte/ccda";
const former: BuildCcdaSmokingStatus = {
value: { code: "8517006", displayName: "Former smoker" }, // SNOMED CT
effectiveTime: "20240101",
};
const unrecorded: BuildCcdaSmokingStatus = {}; // → value nullFlavor="UNK"

Properties​

effectiveTime?​

readonly optional effectiveTime?: string

The date the status was recorded (HL7 date string); nullFlavor="UNK" when omitted.

status?​

readonly optional status?: string

The observation statusCode; defaults to "completed".

value?​

readonly optional value?: BuildCode

The SNOMED CT smoking-status concept (Current Smoking Status value set). Omit for an explicit unknown (value nullFlavor="UNK"), never defaulted to a real status.


BuildCcdaVital​

One member reading of a Vital Signs panel, a Vital Sign Observation. code is the LOINC vital (e.g. 8480-6 systolic BP); quantity is the UCUM-checked PQ reading (required, a vital sign without a value is not emitted).

Example​

import type { BuildCcdaVital } from "@cosyte/ccda";
const systolic: BuildCcdaVital = {
code: { code: "8480-6", displayName: "Systolic blood pressure" },
quantity: { value: 120, unit: "mm[Hg]" },
};

Properties​

code​

readonly code: BuildCode

The LOINC vital-sign code.

effectiveTime?​

readonly optional effectiveTime?: string

The reading time as an HL7 date string, optional.

interpretation?​

readonly optional interpretation?: BuildCode

The H/L/N interpretation (HL7 ObservationInterpretation by default), optional.

quantity​

readonly quantity: BuildQuantity

The reading as a UCUM PQ (required).


BuildCcdaVitalsPanel​

A Vital Signs panel, a Vital Signs Organizer clustering the readings taken in one event (e.g. a set of vitals at a single visit). status maps to the organizer statusCode (default "completed"); vitals are the member readings.

Example​

import type { BuildCcdaVitalsPanel } from "@cosyte/ccda";
const panel: BuildCcdaVitalsPanel = {
vitals: [
{ code: { code: "8480-6", displayName: "Systolic blood pressure" }, quantity: { value: 120, unit: "mm[Hg]" } },
{ code: { code: "8462-4", displayName: "Diastolic blood pressure" }, quantity: { value: 80, unit: "mm[Hg]" } },
],
};

Properties​

effectiveTime?​

readonly optional effectiveTime?: string

The cluster's reading time as an HL7 date string. Emitted as the organizer's SHALL effectiveTime; when omitted the slot is filled with nullFlavor="UNK".

status?​

readonly optional status?: string

The organizer statusCode; defaults to "completed".

vitals​

readonly vitals: readonly BuildCcdaVital[]

The member Vital Sign Observations (at least one for a populated panel).


BuildCode​

A coded value for the builder, the tuple the parser reads back as a CD. codeSystem defaults per slot (SNOMED CT for a problem, RxNorm for an allergen), so most callers pass only code + displayName.

Example​

import type { BuildCode } from "@cosyte/ccda";
const hypertension: BuildCode = { code: "59621000", displayName: "Essential hypertension" };

Properties​

code​

readonly code: string

The code within its system (e.g. a SNOMED CT concept id).

codeSystem?​

readonly optional codeSystem?: string

The code system OID; defaults per slot when omitted.

codeSystemName?​

readonly optional codeSystemName?: string

The code system's human name (e.g. "SNOMED CT"), optional.

displayName​

readonly displayName: string

The human-readable label, regenerated into the narrative so the two agree.


BuildQuantity​

A dimensioned quantity for the builder, a numeric value and a UCUM unit (the parser round-trips it as a PQ). The unit is emitted verbatim: it is the caller's responsibility that it be valid, case-correct UCUM ("mg/dL", "mm[Hg]", "10*3/uL"), because a non-UCUM or case-slipped unit is a real defect the parser is designed to flag (NON_UCUM_UNIT / UCUM_CASE_SUSPECT), the builder never silently "corrects" a unit to a confident-wrong value.

Example​

import type { BuildQuantity } from "@cosyte/ccda";
const glucose: BuildQuantity = { value: 95, unit: "mg/dL" };

Properties​

unit​

readonly unit: string

The UCUM unit (emitted verbatim, must be valid, case-correct UCUM).

value​

readonly value: number

The numeric magnitude.


CcdaDocumentInit​

Constructor init for CcdaDocument. Produced by buildDocument (the parts) plus the orchestrator's accumulated warnings. Optional keys are omitted (never set to undefined) per exactOptionalPropertyTypes.

Example​

import type { CcdaDocumentInit } from "@cosyte/ccda";
const init: CcdaDocumentInit = {
templateIds: [],
header: { recordTargets: [], relatedDocuments: [] },
sections: [],
problems: [],
medications: [],
allergies: [],
results: [],
vitals: [],
immunizations: [],
procedures: [],
encounters: [],
smokingStatus: [],
plannedItems: [],
functionalStatus: [],
mentalStatus: [],
familyHistory: [],
pastMedicalHistory: [],
warnings: [],
};

Properties​

allergies​

readonly allergies: readonly AllergyConcern[]

documentType?​

readonly optional documentType?: DocumentType

encounters​

readonly encounters: readonly Encounter[]

familyHistory​

readonly familyHistory: readonly FamilyHistory[]

functionalStatus​

readonly functionalStatus: readonly StatusObservation[]

header​

readonly header: CcdaHeader

immunizations​

readonly immunizations: readonly Immunization[]

medications​

readonly medications: readonly Medication[]

mentalStatus​

readonly mentalStatus: readonly StatusObservation[]

nonXmlBody?​

readonly optional nonXmlBody?: ED

pastMedicalHistory​

readonly pastMedicalHistory: readonly Problem[]

plannedItems​

readonly plannedItems: readonly PlannedItem[]

problems​

readonly problems: readonly ProblemConcern[]

procedures​

readonly procedures: readonly Procedure[]

profile?​

readonly optional profile?: ProfileAttribution

The CcdaProfile applied at parse time (its name + resolved lineage), or absent when no profile was active. Attribution only, the profile's effect is already reflected in warnings (tolerated deviations re-badged PROFILE_QUIRK_APPLIED, flagged expected).

results​

readonly results: readonly ResultOrganizer[]

sections​

readonly sections: readonly CcdaSection[]

serialized?​

readonly optional serialized?: string

Internal

The spec-clean XML snapshot captured from the source DOM at parse time, returned by CcdaDocument.toString. Populated by parseCcda; absent for a hand-constructed document (which therefore cannot be serialized until a builder API lands).

smokingStatus​

readonly smokingStatus: readonly SmokingStatus[]

templateIds​

readonly templateIds: readonly II[]

vitals​

readonly vitals: readonly VitalSignsOrganizer[]

warnings​

readonly warnings: readonly CcdaWarning[]


CcdaHeader​

The parsed US Realm Header. documentId + code + title + effectiveTime answer the document's identity; recordTargets are the patient(s) (usually exactly one, more than one emits MULTIPLE_RECORD_TARGETS). setId + versionNumber + relatedDocuments carry the CDA R2 revision chain, a replacement document (see editCcda) shares its predecessor's setId, bumps versionNumber, and names the prior version in a RPLC RelatedDocument.

Example​

import type { CcdaHeader } from "@cosyte/ccda";
function when(h: CcdaHeader): Date | undefined {
return h.effectiveTime?.date;
}

Properties​

code?​

readonly optional code?: CD

confidentialityCode?​

readonly optional confidentialityCode?: CD

documentId?​

readonly optional documentId?: II

effectiveTime?​

readonly optional effectiveTime?: TS

languageCode?​

readonly optional languageCode?: string

recordTargets​

readonly recordTargets: readonly CcdaPatient[]

relatedDocuments​

readonly relatedDocuments: readonly RelatedDocument[]

setId?​

readonly optional setId?: II

title?​

readonly optional title?: string

versionNumber?​

readonly optional versionNumber?: number


CcdaParseLimits​

Hard safety limits applied to every parse before the XML is handed to the DOM. Each cap defends a specific denial-of-service vector for hostile XML (oversized payloads, billion-laughs entity expansion, pathological element nesting). All four have library defaults; callers may tighten, or, at their own risk, loosen, any of them via ParseCcdaOptions.limits.

Example​

import type { CcdaParseLimits } from "@cosyte/ccda";
const tight: CcdaParseLimits = { maxInputBytes: 1_000_000, maxDepth: 100 };

Properties​

maxDepth?​

readonly optional maxDepth?: number

Maximum element nesting depth. Exceeding it throws ELEMENT_DEPTH_LIMIT_EXCEEDED.

maxEntityExpansions?​

readonly optional maxEntityExpansions?: number

Maximum count of &...; entity references permitted in the raw input.

maxInputBytes?​

readonly optional maxInputBytes?: number

Maximum decoded input size in bytes. Exceeding it throws INPUT_SIZE_LIMIT_EXCEEDED.

maxNodeCount?​

readonly optional maxNodeCount?: number

Maximum total element-node count. Exceeding it throws NODE_COUNT_LIMIT_EXCEEDED.


CcdaPatient​

A parsed C-CDA patient (recordTarget/patientRole). identifiers are the patient ids (the MRN lives here); demographics carry the coded gender, birth time, and optional race/ethnicity/marital status.

Example​

import type { CcdaPatient } from "@cosyte/ccda";
function label(p: CcdaPatient): string {
return p.name?.text ?? p.identifiers[0]?.extension ?? "unknown";
}

Properties​

birthTime?​

readonly optional birthTime?: TS

ethnicGroupCode?​

readonly optional ethnicGroupCode?: CD

genderCode?​

readonly optional genderCode?: CD

identifiers​

readonly identifiers: readonly II[]

maritalStatusCode?​

readonly optional maritalStatusCode?: CD

name?​

readonly optional name?: HumanName

raceCode?​

readonly optional raceCode?: CD


CcdaPosition​

Structural locator attached to every warning and fatal error. Every field is optional. Together with code it is the whole contract for locating a deviation: no diagnostic message names anything the document said.

The three string fields the parser populates are bounded, not copied. path is an element local name, which a sender can make anything, so it is echoed only when it is a member of the CDA vocabulary this parser navigates and is <withheld> otherwise. sectionCode is echoed only when it has the shape of a LOINC part number, which matters because UNKNOWN_SECTION_CODE fires exactly when the code is unrecognized. templateId is echoed only when it has the shape of an HL7 v3 UID, for the same reason: it is a consumer-controlled II.root. See ./tokens.ts for all three, and for why a shape or membership test is used rather than a length cap. line and column are the XML locator and are never derived from content.

Which codes carry which field is narrow, and worth reading before you key a profile on one. sectionCode is carried by UNKNOWN_SECTION_CODE and SECTION_MATCHED_BY_LOINC_FALLBACK. templateId is carried by those two (the section's first rooted <templateId>) and by TEMPLATE_EXTENSION_ABSENT (the matched document-type root). No other code carries either, so a QuirkMatch keyed on one narrows those codes and matches nothing on the rest: an entry-level warning such as DEPRECATED_LOINC carries neither field today.

Two document-level codes carry no templateId on purpose, and it is a decision rather than an omission. MISSING_TEMPLATE_ID has no template to name. UNKNOWN_DOCUMENT_TEMPLATE has too many: its subject is the templateId set naming no type, and the obvious pick, the first root in document order, is the US Realm Header stamp carried by essentially every real C-CDA, so keying a tolerance on it would read like narrowing while tolerating the code everywhere.

The claim that stood here through 0.0.4, that the fields were PHI-free "by construction" because a path carries element names and a sectionCode is a LOINC code, was an assumption about the sender rather than a property of the parser. For a top-level fatal like INPUT_SIZE_LIMIT_EXCEEDED no field need be populated.

Remarks​

With exactOptionalPropertyTypes: true, do not pass line: undefined explicitly, omit the key instead.

Example​

import type { CcdaPosition } from "@cosyte/ccda";
const pos: CcdaPosition = {
path: "/ClinicalDocument/component/structuredBody/component[3]/section",
sectionCode: "11450-4",
templateId: "2.16.840.1.113883.10.20.22.2.5.1",
};

Properties​

column?​

readonly optional column?: number

line?​

readonly optional line?: number

path?​

readonly optional path?: string

sectionCode?​

readonly optional sectionCode?: string

templateId?​

readonly optional templateId?: string


CcdaProfile​

A frozen, immutable vendor/conformance profile. Produced by defineCcdaProfile; consumers pass it to parseCcda(raw, { profile }) (or register it as the process default). Hand-authoring the object literal is supported but discouraged, the factory validates the safety rules and attaches describe().

Example​

import { parseCcda, ccdaProfiles } from "@cosyte/ccda";
const doc = parseCcda(xml, { profile: ccdaProfiles.smartScorecard });
console.log(doc.profile?.name); // "smartScorecard"

Properties​

describe?​

readonly optional describe?: () => string

Multi-line human-readable summary; always present on factory-built profiles.

Returns​

string

description?​

readonly optional description?: string

Optional human-readable description.

lineage​

readonly lineage: readonly string[]

Resolved lineage, [...parents, name], first-occurrence deduped.

name​

readonly name: string

The profile's unique name (registry key / attribution label).

provenance?​

readonly optional provenance?: ProfileProvenance

The cited public grounding for this profile's quirks (absent for default).

tolerate​

readonly tolerate: readonly QuirkTolerance[]

The expected, non-safety-critical deviations this profile tolerates.


CcdaSection​

A framed C-CDA section. key/title carry the recognized identity (when the section matched the catalog); code and templateIds are the raw signals; narrativeText is the human-readable <text> block and narrativeById indexes its ID-bearing nodes; subsections holds nested <component><section> children.

Example​

import type { CcdaSection } from "@cosyte/ccda";
function summarize(s: CcdaSection): string {
return `${s.key ?? "unknown"}: ${s.narrativeText ?? "(no narrative)"}`;
}

Properties​

code?​

readonly optional code?: CD

key?​

readonly optional key?: string

narrativeById​

readonly narrativeById: ReadonlyMap<string, string>

narrativeText?​

readonly optional narrativeText?: string

recognizedBy?​

readonly optional recognizedBy?: "templateId" | "loinc"

subsections​

readonly subsections: readonly CcdaSection[]

templateIds​

readonly templateIds: readonly II[]

title?​

readonly optional title?: string


CcdaWarning​

Data shape for every Tier-2 warning emitted by the parser. Warnings are plain data (distinct from CcdaParseError, which is a thrown Error subclass) so they can be safely accumulated into CcdaDocument.warnings and passed to onWarning callbacks.

Example​

import type { CcdaWarning } from "@cosyte/ccda";
const w: CcdaWarning = {
code: "UNKNOWN_SECTION_CODE",
message: "The section's LOINC code is not a recognized C-CDA section; retained as narrative-only.",
position: { sectionCode: "99999-9" },
};

Properties​

code​

readonly code: WarningCode

expected?​

readonly optional expected?: boolean

true when an active CcdaProfile expected this deviation and downgraded it, the warning is retained (never dropped) but flagged so a consumer can filter known, tolerated noise from novel deviations. In strict mode an expected warning does not escalate to a thrown error. Absent (not false) when no profile touched the warning.

message​

readonly message: string

position​

readonly position: CcdaPosition

profile?​

readonly optional profile?: string

The name of the CcdaProfile that tolerated this warning, when expected.

toleratedCode?​

readonly optional toleratedCode?: WarningCode

When code is WARNING_CODES.PROFILE_QUIRK_APPLIED, the original warning code the profile tolerated, so the specific deviation (DEPRECATED_LOINC, TEMPLATE_EXTENSION_ABSENT, …) is never lost, only re-badged as expected.


CD​

Parsed HL7 v3 coded value. code + codeSystem form the bound concept; displayName is the human label; originalText is the source text the code was derived from; translation holds alternative codings (e.g. a local code alongside a LOINC/SNOMED standard).

Example​

import type { CD } from "@cosyte/ccda";
const sectionCode: CD = {
code: "48765-2",
codeSystem: "2.16.840.1.113883.6.1",
displayName: "Allergies",
};

Properties​

code?​

readonly optional code?: string

codeSystem?​

readonly optional codeSystem?: string

codeSystemName?​

readonly optional codeSystemName?: string

displayName?​

readonly optional displayName?: string

nullFlavor?​

readonly optional nullFlavor?: string

originalText?​

readonly optional originalText?: string

translation?​

readonly optional translation?: readonly CD[]


ClinicalEntries​

The clinical entries extracted from a document body: the reconciliation triad (Problems, Medications, Allergies), the discrete-data sections (Results, Vital Signs, Immunizations), Procedures, Encounters, Social-History smoking status, and the remaining clinical sections (Plan of Treatment, Functional/Mental Status, Family/Past Medical History). Empty arrays when a body carries none.

Example​

import type { ClinicalEntries } from "@cosyte/ccda";
function summarize(e: ClinicalEntries): number {
return e.problems.length + e.medications.length + e.allergies.length;
}

Properties​

allergies​

readonly allergies: readonly AllergyConcern[]

encounters​

readonly encounters: readonly Encounter[]

familyHistory​

readonly familyHistory: readonly FamilyHistory[]

functionalStatus​

readonly functionalStatus: readonly StatusObservation[]

immunizations​

readonly immunizations: readonly Immunization[]

medications​

readonly medications: readonly Medication[]

mentalStatus​

readonly mentalStatus: readonly StatusObservation[]

pastMedicalHistory​

readonly pastMedicalHistory: readonly Problem[]

plannedItems​

readonly plannedItems: readonly PlannedItem[]

problems​

readonly problems: readonly ProblemConcern[]

procedures​

readonly procedures: readonly Procedure[]

results​

readonly results: readonly ResultOrganizer[]

smokingStatus​

readonly smokingStatus: readonly SmokingStatus[]

vitals​

readonly vitals: readonly VitalSignsOrganizer[]


CodeTranslationResult​

The outcome of TerminologyAdapter.translate, modeled on the FHIR $translate operation and @cosyte/terminology's translate. matches are the declared target codings, drawn verbatim from the consumer's map; an empty array means the source did not map. Per the never-fabricate invariant an adapter must return an empty matches for an unmapped source, never a guessed target.

Consumed on build. @cosyte/ccda defines this so a consumer can wire a ConceptMap-backed engine in behind TerminologyAdapter.translate. buildCcda consults it at each clinical coded slot (problem value, allergen, medication drug + route, vaccine + route) and emits any returned coding as a spec-clean CDA R2 <translation> alternate beside the primary code, never replacing it, and never fabricated (an empty matches emits nothing). The alternates round-trip through parseCcda into CD.translation. translate stays optional on the interface: a validation-only adapter need not implement it, and its absence yields byte-identical output.

Example​

import type { CodeTranslationResult } from "@cosyte/ccda";
const mapped: CodeTranslationResult = {
matches: [{ system: "2.16.840.1.113883.6.90", code: "I10", display: "Essential hypertension" }],
};

Properties​

matches​

readonly matches: readonly TerminologyCoding[]

The declared target codings, verbatim from the map. Empty ⇒ unmapped (never a fabricated target).


CodeValidationResult​

The outcome of TerminologyAdapter.validateCode, modeled on the FHIR $validate-code operation's out-parameters. result is the verdict: true when the adapter confirms the code is a valid, active member of its system; false when it confirms the code is not (unknown / retired / not a member). display and message are advisory only, the parser never applies display back onto the document (that would be a silent coercion); both are surfaced to the consumer, never woven into a PHI-free warning message.

Example​

import type { CodeValidationResult } from "@cosyte/ccda";
const invalid: CodeValidationResult = { result: false, message: "not in SNOMED CT US Edition" };

Properties​

display?​

readonly optional display?: string

The authoritative display the adapter knows for the code, when it has one. Advisory, never applied.

message?​

readonly optional message?: string

A human-readable reason (e.g. why a code is invalid). Advisory, never placed in a warning.

result​

readonly result: boolean

true when the code is a valid member of its system; false when it is not.


DefineCcdaProfileOptions​

Options accepted by defineCcdaProfile. Mirrors the CcdaProfile shape minus the derived lineage/describe, plus the extends input key. Every field except name is optional.

Example​

import { defineCcdaProfile, type DefineCcdaProfileOptions } from "@cosyte/ccda";
const opts: DefineCcdaProfileOptions = {
name: "my-site",
extends: ccdaProfiles.smartScorecard,
tolerate: [{ code: "UNKNOWN_SECTION_CODE", rationale: "site-local sections" }],
};
const p = defineCcdaProfile(opts);

Properties​

description?​

readonly optional description?: string

extends?​

readonly optional extends?: CcdaProfile | readonly CcdaProfile[]

name​

readonly name: string

provenance?​

readonly optional provenance?: ProfileProvenance

tolerate?​

readonly optional tolerate?: readonly QuirkTolerance[]


DocumentIdInit​

A CDA R2 instance identifier (root OID with an optional extension) for a caller-supplied document id or setId in a RevisionInit.

Example​

import type { DocumentIdInit } from "@cosyte/ccda";
const id: DocumentIdInit = { root: "2.16.840.1.113883.19.5", extension: "DOC-2" };

Properties​

extension?​

readonly optional extension?: string

root​

readonly root: string


ED​

Parsed HL7 v3 Encapsulated Data. value is the inline content (verbatim, never base64-decoded); reference is the <reference @value> URI pointing at out-of-line content (e.g. a narrative #id or an external image).

Example​

import type { ED } from "@cosyte/ccda";
const ref: ED = { mediaType: "image/png", representation: "B64", reference: "#img1" };

Properties​

mediaType?​

readonly optional mediaType?: string

nullFlavor?​

readonly optional nullFlavor?: string

reference?​

readonly optional reference?: string

representation?​

readonly optional representation?: string

value?​

readonly optional value?: string


EditCcdaOptions​

Options for editCcda: the ordered list of section edits to apply, and the revision behavior. revision defaults to an automatic RPLC revision; pass a RevisionInit to override its ids/version, or false to edit in place without stamping a new document version.

Example​

import type { EditCcdaOptions } from "@cosyte/ccda";
const opts: EditCcdaOptions = {
sections: [{ kind: "medications", content: [] }],
revision: false,
};

Properties​

revision?​

readonly optional revision?: false | RevisionInit

sections?​

readonly optional sections?: readonly SectionEdit[]

terminology?​

readonly optional terminology?: TerminologyAdapter

An optional consumer-supplied bring-your-own TerminologyAdapter, forwarded to the final re-parse of the edited document so it surfaces SEMANTIC_CODE_INVALID for any coded value the adapter rejects, the same semantic-validation tier parseCcda and buildCcda already offer, now reaching the edited output. editCcda never coerces a code to satisfy the adapter (it emits every value verbatim, byte-faithful on untouched sections and spec-clean on the one it rebuilds); the adapter can only ever add a flag. Omit for the default recognize-only behavior. @cosyte/ccda never imports a terminology library; you supply the adapter.


Encounter​

A single Encounter Activity. code is the encounter type; statusCode is the encounter status; effectiveTime is the visit/admission period; narrative is the resolved <text> reference.

Example​

import type { Encounter } from "@cosyte/ccda";
function encounterType(e: Encounter): string | undefined {
return e.code?.code;
}

Properties​

code?​

readonly optional code?: CD

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

moodCode?​

readonly optional moodCode?: string

narrative?​

readonly optional narrative?: string

statusCode?​

readonly optional statusCode?: string


FamilyHistory​

A Family History Organizer: one relative plus the conditions recorded for them. relative carries the structured family-member identity; observations are that relative's conditions.

Example​

import type { FamilyHistory } from "@cosyte/ccda";
function conditionCount(h: FamilyHistory): number {
return h.observations.length;
}

Properties​

ids​

readonly ids: readonly II[]

observations​

readonly observations: readonly FamilyHistoryObservation[]

relative​

readonly relative: FamilyMember


FamilyHistoryObservation​

A single condition in a relative's history. condition is the coded problem (SNOMED CT / ICD-10-CM); ageAtOnset is the relative's age (a PQ in years) from the nested Age Observation; causeOfDeath is true when a Family History Death Observation marks this condition as the cause of death. negated and nullFlavor are kept distinct, never collapsed.

Example​

import type { FamilyHistoryObservation } from "@cosyte/ccda";
function fatal(o: FamilyHistoryObservation): boolean {
return o.causeOfDeath === true;
}

Properties​

ageAtOnset?​

readonly optional ageAtOnset?: PQ

causeOfDeath?​

readonly optional causeOfDeath?: boolean

condition?​

readonly optional condition?: CD

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

narrative?​

readonly optional narrative?: string

negated?​

readonly optional negated?: boolean

nullFlavor?​

readonly optional nullFlavor?: string


FamilyMember​

The family member a FamilyHistory group describes. relationship is the coded relation (e.g. SNOMED/HL7 FTH father); gender the relative's administrative gender; birthTime their birth date; deceased the sdtc:deceasedInd flag. All optional, a document may name only the relation.

Example​

import type { FamilyMember } from "@cosyte/ccda";
const m: FamilyMember = { relationship: { code: "FTH", displayName: "Father" } };

Properties​

birthTime?​

readonly optional birthTime?: TS

deceased?​

readonly optional deceased?: boolean

gender?​

readonly optional gender?: CD

relationship?​

readonly optional relationship?: CD


HumanName​

A parsed C-CDA person name (<name>). Captures the structured parts plus the text fallback (the element's full trimmed text) for senders that put the whole name in a single node.

Example​

import type { HumanName } from "@cosyte/ccda";
const n: HumanName = { given: ["Jane"], family: "Doe", text: "Jane Doe" };

Properties​

family?​

readonly optional family?: string

given?​

readonly optional given?: readonly string[]

prefix?​

readonly optional prefix?: readonly string[]

suffix?​

readonly optional suffix?: readonly string[]

text?​

readonly optional text?: string


II​

Parsed HL7 v3 Instance Identifier. root is the namespace OID/UUID; extension is the local identifier within it. For a templateId, root (and optionally extension, the R2.1 version stamp) are the meaningful fields; for a patient id, root+extension form the full MRN.

Example​

import type { II } from "@cosyte/ccda";
const id: II = { root: "2.16.840.1.113883.19.5", extension: "12345" };

Properties​

assigningAuthorityName?​

readonly optional assigningAuthorityName?: string

extension?​

readonly optional extension?: string

nullFlavor?​

readonly optional nullFlavor?: string

root?​

readonly optional root?: string


Immunization​

An Immunization Activity. vaccine is the CVX coded product; dose is the amount administered; route is the administration route; effectiveTime is when it was given. refused is true for a negationInd not-administered record; nullFlavor carries an "unknown" marker, the two are kept distinct. moodCode distinguishes an actual administration (EVN) from a planned one.

Example​

import type { Immunization } from "@cosyte/ccda";
function cvx(i: Immunization): string | undefined {
return i.vaccine?.code;
}

Properties​

dose?​

readonly optional dose?: PQ

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

moodCode?​

readonly optional moodCode?: string

narrative?​

readonly optional narrative?: string

nullFlavor?​

readonly optional nullFlavor?: string

refused?​

readonly optional refused?: boolean

route?​

readonly optional route?: CD

statusCode?​

readonly optional statusCode?: string

vaccine?​

readonly optional vaccine?: CD


IVL_PQ​

Parsed HL7 v3 Interval of Physical Quantity. Any subset of the bound fields may be present; nullFlavor is set when the interval element declared one.

Example​

import type { IVL_PQ } from "@cosyte/ccda";
const range: IVL_PQ = { low: { value: 1, unit: "mg" }, high: { value: 2, unit: "mg" } };

Properties​

center?​

readonly optional center?: PQ

high?​

readonly optional high?: PQ

low?​

readonly optional low?: PQ

nullFlavor?​

readonly optional nullFlavor?: string

width?​

readonly optional width?: PQ


IVL_TS​

Parsed HL7 v3 Interval of Point in Time. low/high are the bounds; value captures the degenerate case where the interval element itself carries a @value (a point expressed as an interval). nullFlavor is set when the element declared one.

Example​

import type { IVL_TS } from "@cosyte/ccda";
const period: IVL_TS = { low: { raw: "20260101" }, high: { raw: "20261231" } };

Properties​

high?​

readonly optional high?: TS

low?​

readonly optional low?: TS

nullFlavor?​

readonly optional nullFlavor?: string

value?​

readonly optional value?: TS


Medication​

A Medication Activity. drug is the RxNorm coded product; dose/doseRange is the amount per administration; route is the administration route; duration is the therapy window (IVL_TS) and frequency the periodic timing (PIVL_TS). moodCode distinguishes an actual administration (EVN) from a planned/ordered one (INT/RQO), never conflated.

Example​

import type { Medication } from "@cosyte/ccda";
function rxnorm(m: Medication): string | undefined {
return m.drug?.code;
}

Properties​

dose?​

readonly optional dose?: PQ

doseRange?​

readonly optional doseRange?: IVL_PQ

drug?​

readonly optional drug?: CD

duration?​

readonly optional duration?: IVL_TS

frequency?​

readonly optional frequency?: MedicationFrequency

ids​

readonly ids: readonly II[]

moodCode?​

readonly optional moodCode?: string

narrative?​

readonly optional narrative?: string

negated?​

readonly optional negated?: boolean

nullFlavor?​

readonly optional nullFlavor?: string

route?​

readonly optional route?: CD

statusCode?​

readonly optional statusCode?: string


MedicationFrequency​

A periodic dosing frequency (HL7 v3 PIVL_TS). period is the interval between administrations (e.g. 8 hours); institutionSpecified marks an institution-defined timing (e.g. "with meals" rather than a fixed clock).

Example​

import type { MedicationFrequency } from "@cosyte/ccda";
const f: MedicationFrequency = { period: { value: 8, unit: "h" } };

Properties​

institutionSpecified?​

readonly optional institutionSpecified?: boolean

period?​

readonly optional period?: PQ


ParentDocument​

A CDA R2 parentDocument, the earlier document a RelatedDocument points back at. Carries the parent's id(s), optional code, and the setId/versionNumber revision pair (the version this document supersedes).

Example​

import type { ParentDocument } from "@cosyte/ccda";
function priorVersion(p: ParentDocument): number | undefined {
return p.versionNumber;
}

Properties​

code?​

readonly optional code?: CD

ids​

readonly ids: readonly II[]

setId?​

readonly optional setId?: II

versionNumber?​

readonly optional versionNumber?: number


ParseCcdaOptions​

Options accepted by parseCcda to tune lenient/strict behaviour and the security limits. Every field is optional; parseCcda(raw, {}) is valid and produces the library defaults (lenient parse, default safety caps).

Remarks​

With exactOptionalPropertyTypes: true, callers cannot pass { strict: undefined }, either omit the key or pass a boolean.

Example​

import { parseCcda, type ParseCcdaOptions } from "@cosyte/ccda";
const opts: ParseCcdaOptions = {
strict: false,
onWarning: (w) => console.warn(w.code),
};
parseCcda(raw, opts);

Properties​

limits?​

readonly optional limits?: CcdaParseLimits

Override one or more of the default safety caps applied before DOM construction.

onWarning?​

readonly optional onWarning?: OnWarningCallback

Inline callback fired for each Tier-2 warning, in emission order (see OnWarningCallback).

profile?​

readonly optional profile?: CcdaProfile | null

The vendor/conformance CcdaProfile to apply. A profile downgrades the non-safety-critical deviations it expects to PROFILE_QUIRK_APPLIED (flagged expected), it never changes an extracted value and can never tolerate a safety-critical warning. Omit to consult the process-scoped default (setDefaultCcdaProfile); pass null to opt out of that default for this call.

strict?​

readonly optional strict?: boolean

When true, escalate every Tier-2 deviation to a thrown error instead of a warning.

terminology?​

readonly optional terminology?: TerminologyAdapter

An optional consumer-supplied bring-your-own TerminologyAdapter. When present, the parser semantically validates each recognized coded value (a problem, medication, allergen, route, or vaccine code) against it and emits SEMANTIC_CODE_INVALID on a negative verdict, the code preserved verbatim, never coerced. Omit it for the default recognize-only behavior. @cosyte/ccda never imports a terminology library; you supply the adapter.


ParseCtx​

Parse context threaded into every datatype parser so it can surface a Tier-2 warning (e.g. INVALID_NULL_FLAVOR, MALFORMED_DATETIME) in discovery order. Datatypes that have nothing to warn about simply never call emit.

Example​

import { type ParseCtx, parsePq } from "@cosyte/ccda";
const ctx: ParseCtx = { emit: (w) => console.warn(w.code) };
parsePq(el, ctx);

Properties​

emit​

readonly emit: (warning) => void

Parameters​
warning​

CcdaWarning

Returns​

void

terminology?​

readonly optional terminology?: TerminologyAdapter

The optional consumer-supplied TerminologyAdapter. When present, the code-system recognition layer (checkCodeSlot) calls it to semantically validate coded values; when absent, recognition falls back to structural checks only. @cosyte/ccda never constructs one, it only calls the adapter a consumer passed to parseCcda / buildCcda.


PlannedItem​

A single planned item from the Plan of Treatment. kind is the template variant; disposition is the performed-vs-planned reading of moodCode (normally "planned", never guessed); value carries the expected result for the observation variant. negated and nullFlavor are kept distinct, never collapsed.

code is the planned act's own <code> for five of the seven variants. For the two substanceAdministration variants, medicationActivity and immunizationActivity, it is the product (the drug, or the vaccine), read from consumable/manufacturedProduct, and never the substanceAdministration's own <code>: that element is an ActSubstanceAdministrationCode (the kind of administration act), not the substance. That [0..1] cardinality and that binding are base CDA R2's SubstanceAdministration class, not a C-CDA constraint: R2.1 constrains code on neither template, which is precisely why an act <code> is legal on both. An act <code> present on either variant is not read into this field; it round-trips through doc.toString().

Absence has three shapes there and only two of them are undefined, so do not test this field for truthiness and stop. It is undefined when no arm carries a <code> at all (beside MISSING_PRODUCT_CODE) and when the arms name different drugs (beside MEDICATION_PRODUCT_ARM_CONFLICT). But an arm whose <code> asserts neither a symbol nor a nullFlavor yields a truthy but empty CD, and a nullFlavor-only one yields a CD carrying just that marking. Neither is MISSING_PRODUCT_CODE, an arm did carry a <code>. Read code?.code, not code.

On the two substanceAdministration variants that empty shape is no longer silent: the field is slot-checked exactly as its performed twin's product is, so it draws MISSING_CODE_VALUE. medicationActivity is checked at the medication binding (RxNorm/NDC, as a performed Medication Activity's drug is) and immunizationActivity at the vaccine binding (CVX only, as an Immunization Activity's vaccine is), so a product code carrying no @codeSystem or one outside its binding draws MISSING_CODE_SYSTEM or UNEXPECTED_CODE_SYSTEM. The two bindings differ: NDC is expected on a drug and unexpected on a vaccine, so an NDC-coded planned vaccine draws UNEXPECTED_CODE_SYSTEM where an NDC-coded planned drug does not, matching each variant's performed twin rather than each other. A nullFlavor-only CD is a complete statement and stays silent, as it does everywhere else. The other five variants are not slot-checked: their code is the planned act, which is not one of the five bound CodeSlots.

Example​

import type { PlannedItem } from "@cosyte/ccda";
function isPlanned(p: PlannedItem): boolean {
return p.disposition === "planned";
}

Properties​

code?​

readonly optional code?: CD

disposition?​

readonly optional disposition?: EventDisposition

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

kind​

readonly kind: PlannedItemKind

moodCode?​

readonly optional moodCode?: string

narrative?​

readonly optional narrative?: string

negated?​

readonly optional negated?: boolean

nullFlavor?​

readonly optional nullFlavor?: string

statusCode?​

readonly optional statusCode?: string

value?​

readonly optional value?: ObservationValue


PQ​

Parsed HL7 v3 Physical Quantity. value is the parsed number (omitted when @value was non-numeric), raw is the verbatim @value string, and unit is the UCUM unit when present.

Example​

import type { PQ } from "@cosyte/ccda";
const dose: PQ = { value: 81, raw: "81", unit: "mg" };

Properties​

nullFlavor?​

readonly optional nullFlavor?: string

raw?​

readonly optional raw?: string

unit?​

readonly optional unit?: string

value?​

readonly optional value?: number


Problem​

A single Problem Observation. value is the coded condition (SNOMED CT / ICD-10-CM), the field most consumers want; code is the observation's problem-type code. negated (from @negationInd) and nullFlavor are distinct, a negated problem ("no chest pain") is not an unknown one.

Example​

import type { Problem } from "@cosyte/ccda";
const p: Problem = { ids: [], value: { code: "59621000", codeSystem: "2.16.840.1.113883.6.96" } };

Properties​

code?​

readonly optional code?: CD

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

narrative?​

readonly optional narrative?: string

negated?​

readonly optional negated?: boolean

nullFlavor?​

readonly optional nullFlavor?: string

value?​

readonly optional value?: CD


ProblemConcern​

A Problem Concern Act: the clinical-concern wrapper around one or more Problem observations. status is the resolved active/resolved/ inactive state (from the concern statusCode); effectiveTime is the concern window (onset → resolution).

Example​

import type { ProblemConcern } from "@cosyte/ccda";
function isActive(c: ProblemConcern): boolean {
return c.status === "active";
}

Properties​

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

problems​

readonly problems: readonly Problem[]

status​

readonly status: ConcernStatus


Procedure​

A single procedure. kind is the template variant; code is the procedure code (SNOMED CT / CPT / ICD-10-PCS / LOINC); disposition is the performed-vs-planned reading of moodCode; value carries the result for the observation variant. negated (a negationInd "did not happen") and nullFlavor ("unknown") are kept distinct, never collapsed.

Example​

import type { Procedure } from "@cosyte/ccda";
function wasPerformed(p: Procedure): boolean {
return p.disposition === "performed";
}

Properties​

code?​

readonly optional code?: CD

disposition?​

readonly optional disposition?: EventDisposition

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

kind​

readonly kind: ProcedureKind

moodCode?​

readonly optional moodCode?: string

narrative?​

readonly optional narrative?: string

negated?​

readonly optional negated?: boolean

nullFlavor?​

readonly optional nullFlavor?: string

statusCode?​

readonly optional statusCode?: string

value?​

readonly optional value?: ObservationValue


ProfileAttribution​

PHI-free attribution for the CcdaProfile a document was parsed under, just the profile's name and resolved lineage, not the whole profile object. Mirrors the sibling @cosyte/hl7 msg.profile shape.

Example​

import { parseCcda, ccdaProfiles } from "@cosyte/ccda";
const doc = parseCcda(xml, { profile: ccdaProfiles.smartScorecard });
console.log(doc.profile?.name); // "smartScorecard"

Properties​

lineage​

readonly lineage: readonly string[]

name​

readonly name: string


ProfileProvenance​

Provenance for a CcdaProfile, the real, cited public artifact a profile's quirks are grounded in. A quirk is encoded only when a real document (including a public HL7/ONC/IHE sample or a published conformance study) grounds it; this record is where that grounding is stated, so a reviewer can trace every tolerated deviation back to evidence rather than invention.

Example​

import type { ProfileProvenance } from "@cosyte/ccda";
const prov: ProfileProvenance = {
source: "SMART C-CDA Scorecard",
reference: "https://ccda-scorecard.smarthealthit.org/",
retrieved: "2026-07-18",
};

Properties​

note?​

readonly optional note?: string

Optional clarifying note about what in the source grounds the quirks.

reference​

readonly reference: string

A citation the grounding can be traced to, a URL, DOI, or repo+commit.

retrieved?​

readonly optional retrieved?: string

When the grounding was last verified (ISO date) or the pinned commit SHA.

source​

readonly source: string

Short human-readable name of the grounding source (corpus, study, or guide).


QuirkMatch​

Optional structural narrowing for a QuirkTolerance. When present, the tolerance applies only to warnings whose PHI-free CcdaPosition matches every provided field. Matching is on structural identifiers only (LOINC section code, template OID); there is no matching on clinical values, by construction.

Read which codes carry which field before keying on one. A position field a warning does not carry can never equal the value you match on, so the tolerance is inert rather than broad. sectionCode is carried by UNKNOWN_SECTION_CODE and SECTION_MATCHED_BY_LOINC_FALLBACK only; templateId is carried by those two plus TEMPLATE_EXTENSION_ABSENT. Those three are the deviations a structural identifier can locate today. Entry-level codes (DEPRECATED_LOINC, UNEXPECTED_CODE_SYSTEM, the medication-product codes) carry neither, and so do MISSING_TEMPLATE_ID and UNKNOWN_DOCUMENT_TEMPLATE, so narrowing any of those to a section or a template matches nothing at all. Omit match to tolerate a code wherever it fires, which is what every profile shipped in ccdaProfiles does.

Example​

import type { QuirkMatch } from "@cosyte/ccda";
// Tolerate the missing R2.1 version stamp on the CCD root template only.
const ccdRootOnly: QuirkMatch = { templateId: "2.16.840.1.113883.10.20.22.1.2" };

Properties​

sectionCode?​

readonly optional sectionCode?: string

Match only warnings carrying this section LOINC code in their position. Carried by UNKNOWN_SECTION_CODE and SECTION_MATCHED_BY_LOINC_FALLBACK.

templateId?​

readonly optional templateId?: string

Match only warnings carrying this template OID in their position. Carried by UNKNOWN_SECTION_CODE, SECTION_MATCHED_BY_LOINC_FALLBACK and TEMPLATE_EXTENSION_ABSENT.


QuirkTolerance​

One expected deviation declared by a profile. code names an existing, non-safety-critical WarningCode the profile expects; rationale documents why (grounded in the profile's ProfileProvenance); optional match narrows it to a structural location. defineCcdaProfile throws if code is safety-critical or not a real warning code.

Example​

import type { QuirkTolerance } from "@cosyte/ccda";
const t: QuirkTolerance = {
code: "DEPRECATED_LOINC",
rationale: "Scorecard-documented deprecated BMI LOINC 41909-3 in real docs.",
};

Properties​

code​

readonly code: WarningCode

The existing, non-safety-critical warning code this profile expects.

match?​

readonly optional match?: QuirkMatch

Optional structural narrowing (section code / template OID).

rationale​

readonly rationale: string

Why the profile expects this deviation, grounded in its provenance.


ReferenceRange​

A result's reference range. low/high are the structured numeric bounds (an IVL_PQ); text is the free-text form (preserved when present). A range with no structured bounds emits FREE_TEXT_REFERENCE_RANGE, it cannot be compared numerically against the result value.

Example​

import type { ReferenceRange } from "@cosyte/ccda";
const r: ReferenceRange = { low: { value: 3.5, unit: "g/dL" }, high: { value: 5, unit: "g/dL" } };

Properties​

high?​

readonly optional high?: PQ

low?​

readonly optional low?: PQ

text?​

readonly optional text?: string


RelatedDocument​

A CDA R2 relatedDocument, the header link that makes one document a revision of another. typeCode is the ActRelationshipType (RPLC replaces, APND appends, XFRM transforms); parentDocument names the prior version. A replacement (revision) carries typeCode="RPLC", the same setId as its parent, and an incremented versionNumber.

Example​

import type { RelatedDocument } from "@cosyte/ccda";
function replaces(r: RelatedDocument): boolean {
return r.typeCode === "RPLC";
}

Properties​

parentDocument​

readonly parentDocument: ParentDocument

typeCode?​

readonly optional typeCode?: string


RequiredSectionOptions​

How a required-section lookup should treat version-scoped SHALL constraints.

Properties​

r21Stamped?​

readonly optional r21Stamped?: boolean

Whether the document carries the R2.1 @extension="2015-08-01" stamp on its document-level templateId. Defaults to true, because these tables are written against C-CDA R2.1. Pass false for an R1.1-origin document (the condition that raises TEMPLATE_EXTENSION_ABSENT) to drop the SHALL keys whose normative constraint is scoped to the R2.1 stamp.


ResolvedLimits​

Internal

Fully-resolved safety caps, every field present (defaults merged in).

Properties​

maxDepth​

readonly maxDepth: number

maxEntityExpansions​

readonly maxEntityExpansions: number

maxInputBytes​

readonly maxInputBytes: number

maxNodeCount​

readonly maxNodeCount: number


Result​

A single Result Observation. code is the LOINC test; value is the typed result (a UCUM-checked quantity, coded value, string, or range); referenceRange is the normal interval; interpretation is the H/L/N flag.

Example​

import type { Result } from "@cosyte/ccda";
function highFlag(r: Result): boolean {
return r.interpretation?.code === "H";
}

Properties​

code?​

readonly optional code?: CD

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

interpretation?​

readonly optional interpretation?: CD

narrative?​

readonly optional narrative?: string

referenceRange?​

readonly optional referenceRange?: ReferenceRange

value?​

readonly optional value?: ObservationValue


ResultOrganizer​

A Result Organizer: the panel/battery wrapper around one or more Result observations. code is the panel LOINC; statusCode is the organizer status; results are the member observations.

Example​

import type { ResultOrganizer } from "@cosyte/ccda";
function panelSize(o: ResultOrganizer): number {
return o.results.length;
}

Properties​

code?​

readonly optional code?: CD

ids​

readonly ids: readonly II[]

results​

readonly results: readonly Result[]

statusCode?​

readonly optional statusCode?: string


RevisionInit​

Overrides for the CDA R2 revision an edit stamps. All fields are optional: omit documentId to mint a fresh id, omit setId to keep the source's version-series id (or mint a labelled synthetic one when the source has none, see SYNTHETIC_SETID_PREFIX; a setId supplied here is the caller's assertion and is never relabelled), and omit versionNumber to increment the prior version by one. Pass revision: false on EditCcdaOptions instead of a RevisionInit to skip revision stamping entirely.

Example​

import type { RevisionInit } from "@cosyte/ccda";
const rev: RevisionInit = { versionNumber: 5 };

Properties​

documentId?​

readonly optional documentId?: DocumentIdInit

setId?​

readonly optional setId?: DocumentIdInit

versionNumber?​

readonly optional versionNumber?: number


SectionInfo​

Recognized-section descriptor. key is a stable machine name, title a human label, loinc the section's LOINC code, and templateRoots the section templateId root OID(s) (entries-optional and entries-required variants) that identify it.

Example​

import type { SectionInfo } from "@cosyte/ccda";
const s: SectionInfo = {
key: "allergies",
title: "Allergies",
loinc: "48765-2",
templateRoots: ["2.16.840.1.113883.10.20.22.2.6.1"],
};

Properties​

key​

readonly key: string

loinc​

readonly loinc: string

templateRoots​

readonly templateRoots: readonly string[]

title​

readonly title: string


SmokingStatus​

A Smoking Status observation. value is the SNOMED CT smoking-status concept; unknown is true when the status is explicitly unknown (a nullFlavor or an "unknown" SNOMED concept), distinct from simply absent. effectiveTime is when the status was recorded.

Example​

import type { SmokingStatus } from "@cosyte/ccda";
function isFormerSmoker(s: SmokingStatus): boolean {
return s.value?.code === "8517006";
}

Properties​

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

narrative?​

readonly optional narrative?: string

statusCode?​

readonly optional statusCode?: string

unknown​

readonly unknown: boolean

value?​

readonly optional value?: CD


ST​

Parsed HL7 v3 Character String. value is the trimmed text content (omitted when empty); nullFlavor is set when the element declared one instead of a value.

Example​

import type { ST } from "@cosyte/ccda";
const title: ST = { value: "Allergies, Adverse Reactions, Alerts" };

Properties​

nullFlavor?​

readonly optional nullFlavor?: string

value?​

readonly optional value?: string


StatusObservation​

A single Functional/Mental Status finding. domain is the section it came from; assessmentScale is true when the finding is an Assessment Scale Observation (a scored scale) rather than a plain status observation; code is the finding code (usually LOINC), value the typed result. negated and nullFlavor are kept distinct, never collapsed.

Example​

import type { StatusObservation } from "@cosyte/ccda";
function isScale(o: StatusObservation): boolean {
return o.assessmentScale === true;
}

Properties​

assessmentScale?​

readonly optional assessmentScale?: boolean

code?​

readonly optional code?: CD

domain​

readonly domain: StatusDomain

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

narrative?​

readonly optional narrative?: string

negated?​

readonly optional negated?: boolean

nullFlavor?​

readonly optional nullFlavor?: string

statusCode?​

readonly optional statusCode?: string

supporting?​

readonly optional supporting?: readonly SupportingObservation[]

The scored component observations of an Assessment Scale Observation (…22.4.86), present only when assessmentScale is true and the scale carries components (e.g. the individual PHQ-9 questions under the total score). Absent for a plain status observation.

value?​

readonly optional value?: ObservationValue


SupportingObservation​

One scored component of an Assessment Scale Observation, an Assessment Scale Supporting Observation (…22.4.86), such as a single PHQ-9 question or a Glasgow Coma sub-score. code is the item code (LOINC/SNOMED), value its scored answer (usually an integer). Modeled so the scale's detail is never silently dropped on parse.

Example​

import type { SupportingObservation } from "@cosyte/ccda";
function itemScore(o: SupportingObservation): number | undefined {
return o.value?.kind === "integer" ? o.value.value : undefined;
}

Properties​

code?​

readonly optional code?: CD

ids​

readonly ids: readonly II[]

narrative?​

readonly optional narrative?: string

value?​

readonly optional value?: ObservationValue


TerminologyAdapter​

The bring-your-own terminology contract a consumer supplies to parseCcda (via ParseCcdaOptions.terminology) or buildCcda (via BuildCcdaOptions.terminology). @cosyte/ccda never implements or imports one, it only calls the one you supply, and only where a coded value carries both a code and a system.

validateCode is the one method the parser consumes. For each recognized coded slot (problem, medication, allergen, route, vaccine), the parser calls validateCode and, on a result: false, emits SEMANTIC_CODE_INVALID with the code preserved verbatim, it never rewrites the value. Returning undefined means the adapter has no opinion (e.g. the system is outside its coverage); the parser then stays silent and falls back to recognize-only, so an adapter that only covers some systems adds no noise for the rest.

translate is consumed on build and optional. buildCcda calls it at each clinical coded slot and emits any returned coding as a <translation> alternate beside the primary code (never a substitution), see CodeTranslationResult.

Example​

import { parseCcda, type TerminologyAdapter } from "@cosyte/ccda";

// A tiny BYO adapter, ccda imports no terminology library; you supply one.
const adapter: TerminologyAdapter = {
validateCode: (coding) =>
coding.system === "2.16.840.1.113883.6.96"
? { result: mySnomedService.has(coding.code) }
: undefined, // no opinion on other systems
};

const doc = parseCcda(xml, { terminology: adapter });
// A structurally-valid but non-member SNOMED code now carries SEMANTIC_CODE_INVALID.

Properties​

translate?​

readonly optional translate?: (coding) => CodeTranslationResult | undefined

Translate coding through the consumer's map, returning declared targets verbatim (empty ⇒ unmapped, never fabricated). buildCcda emits each returned coding as a <translation> alternate beside the primary code, never a substitution. Optional, a validation-only adapter may omit it, and its absence yields byte-identical output.

Parameters​
coding​

TerminologyCoding

Returns​

CodeTranslationResult | undefined

validateCode​

readonly validateCode: (coding) => CodeValidationResult | undefined

Validate that coding is a real member of its code system. Return { result: true } when it is, { result: false } when it is not, or undefined when the adapter cannot judge (the system is out of its scope), undefined produces no warning and no change.

Parameters​
coding​

TerminologyCoding

Returns​

CodeValidationResult | undefined


TerminologyCoding​

A single coded value handed to a TerminologyAdapter. Mirrors FHIR R4 Coding (and @cosyte/terminology's Coding), except system is the C-CDA @codeSystem OID exactly as it appears in the document (e.g. 2.16.840.1.113883.6.96 for SNOMED CT), not a canonical URI, the parser hands the adapter what the wire actually carries and never invents a URI. A consumer bridging to a URI-based engine (such as @cosyte/terminology's resolveSystem) performs that OID→URI mapping inside their adapter.

Example​

import type { TerminologyCoding } from "@cosyte/ccda";
const snomed: TerminologyCoding = {
system: "2.16.840.1.113883.6.96",
code: "38341003",
display: "Hypertension",
};

Properties​

code​

readonly code: string

The symbol within the code system (the C-CDA @code). Required, a coding without one is meaningless.

display?​

readonly optional display?: string

The human-readable label (the C-CDA @displayName), when present. Carried verbatim.

system?​

readonly optional system?: string

The code system's OID, as carried by the C-CDA @codeSystem (never a URI). May be absent.

version?​

readonly optional version?: string

The code-system version the code is drawn from, when known.


TS​

Parsed HL7 v3 Point in Time. raw is the verbatim @value; date is the resolved JS Date (UTC when the value carried no offset), or omitted when the value was malformed. nullFlavor is set when the element declared one.

Example​

import type { TS } from "@cosyte/ccda";
const effective: TS = { raw: "20260628", date: new Date("2026-06-28T00:00:00Z") };

Properties​

date?​

readonly optional date?: Date

nullFlavor?​

readonly optional nullFlavor?: string

raw?​

readonly optional raw?: string


VitalSign​

A single Vital Sign Observation. code is the LOINC vital; value is the typed reading (normally a UCUM-checked quantity); interpretation is the H/L/N flag; effectiveTime is when the reading was taken.

Example​

import type { VitalSign } from "@cosyte/ccda";
function systolic(v: VitalSign): number | undefined {
return v.code?.code === "8480-6" && v.value?.kind === "physicalQuantity"
? v.value.quantity.value
: undefined;
}

Properties​

code?​

readonly optional code?: CD

effectiveTime?​

readonly optional effectiveTime?: IVL_TS

ids​

readonly ids: readonly II[]

interpretation?​

readonly optional interpretation?: CD

narrative?​

readonly optional narrative?: string

value?​

readonly optional value?: ObservationValue


VitalSignsOrganizer​

A Vital Signs Organizer: the cluster wrapper around one or more VitalSign observations taken together. code is the cluster code; statusCode is the organizer status; vitals are the member readings.

Example​

import type { VitalSignsOrganizer } from "@cosyte/ccda";
function clusterSize(o: VitalSignsOrganizer): number {
return o.vitals.length;
}

Properties​

code?​

readonly optional code?: CD

ids​

readonly ids: readonly II[]

statusCode?​

readonly optional statusCode?: string

vitals​

readonly vitals: readonly VitalSign[]

Type Aliases​

BuildCcdaPlannedItem​

BuildCcdaPlannedItem = BuildCcdaPlannedAct | BuildCcdaPlannedOrder | BuildCcdaPlannedObservation | BuildCcdaPlannedImmunization

A planned item for the Plan of Treatment section (…22.2.10), a discriminated union over the seven planned-entry templates the parser returns, split by which @moodCode domain each element admits and by which SHALL elements each template carries: BuildCcdaPlannedAct (act/encounter/procedure, which accept the appointment moods APT/ARQ), BuildCcdaPlannedOrder (medication/supply), BuildCcdaPlannedObservation (observation, which also carries an expected value), and BuildCcdaPlannedImmunization (immunization, whose effectiveTime is required rather than optional). The mood split is correct by construction: the base CDA R2 mood domains for substanceAdministration, supply, and observation exclude APT/ARQ, so those appointment moods are simply not representable on those kinds, the type prevents emitting a schema-invalid @moodCode, not merely a discouraged one.

Everything here is future/ordered, never performed. No variant admits the performed EVN; each entry's statusCode is fixed to "active" (the SHALL the planned templates require), never a performed "completed", and the planned @moodCode reads back through the parser's disposition as "planned"; the two dispositions are never conflated.

Example​

import type { BuildCcdaPlannedItem } from "@cosyte/ccda";
const plannedColonoscopy: BuildCcdaPlannedItem = {
kind: "procedure",
code: { code: "73761001", displayName: "Colonoscopy" }, // SNOMED CT
};

CcdaEditErrorCode​

CcdaEditErrorCode = "NO_SOURCE_DOCUMENT" | "NO_STRUCTURED_BODY" | "SECTION_ALREADY_PRESENT" | "SECTION_ABSENT" | "REQUIRED_SECTION_MISSING" | "SOURCE_MISSING_ID"

Stable string codes for every failure editCcda raises. Consumers narrow on err.code.

Example​

import type { CcdaEditErrorCode } from "@cosyte/ccda";
const code: CcdaEditErrorCode = "REQUIRED_SECTION_MISSING";

CodeSlot​

CodeSlot = typeof CODE_SLOTS[number]

Which coded slot a code-system warning is about. Closed by construction, so naming it in a message names a parser constant rather than document content.

Example​

import type { CodeSlot } from "@cosyte/ccda";
const slot: CodeSlot = "problem";

ConcernStatus​

ConcernStatus = "active" | "resolved" | "inactive" | "unknown"

The resolved active-vs-resolved state of a Problem/Allergy Concern Act, derived from its statusCode (with effectiveTime available for refinement).

Example​

import type { ConcernStatus } from "@cosyte/ccda";
const s: ConcernStatus = "active";

DocumentType​

DocumentType = "ccd" | "dischargeSummary" | "referralNote" | "consultationNote" | "historyAndPhysical" | "progressNote" | "procedureNote" | "operativeNote" | "carePlan" | "diagnosticImagingReport" | "unstructuredDocument" | "transferSummary"

Machine keys for the twelve recognized C-CDA R2.1 document types. Stable strings, consumers may branch on doc.documentType === "ccd". Renaming a key is a breaking change.

Example​

import type { DocumentType } from "@cosyte/ccda";
const t: DocumentType = "dischargeSummary";

EditableSectionKind​

EditableSectionKind = "problems" | "allergies" | "medications" | "results" | "vitalSigns" | "immunizations" | "procedures" | "encounters" | "socialHistory" | "pastMedicalHistory" | "planOfTreatment" | "familyHistory"

Internal

The section kinds buildSectionComponent can emit as a standalone <component>, the sections buildCcda builds from a single content list. The compound Functional/Mental Status sections (three content arrays each) and narrative-only sections are intentionally excluded from edit support.


EventDisposition​

EventDisposition = "performed" | "planned"

The performed-vs-planned disposition of a clinical act, derived from its @moodCode: EVN → "performed"; a planned mood (INT/RQO/PRMS/PRP/ APT/ARQ) → "planned". Shared by Procedures and the Plan of Treatment so a planned act is never read as performed (and vice versa).

Example​

import type { EventDisposition } from "@cosyte/ccda";
const d: EventDisposition = "planned";

FatalCode​

FatalCode = typeof FATAL_CODES[keyof typeof FATAL_CODES]

Discriminant type for CcdaParseError.code. Narrowing a caught error by this code lets consumers write exhaustive switch blocks (enabled by the switch-exhaustiveness-check lint rule) and guarantees a typo-free comparison against the FATAL_CODES registry.

Example​

import type { FatalCode } from "@cosyte/ccda";
function describe(code: FatalCode): string {
switch (code) {
case "XXE_OR_DTD_PRESENT":
return "document declared a DTD or external entity";
case "ENTITY_EXPANSION_LIMIT":
return "too many entity expansions";
case "INPUT_SIZE_LIMIT_EXCEEDED":
return "input too large";
case "ELEMENT_DEPTH_LIMIT_EXCEEDED":
return "nesting too deep";
case "NODE_COUNT_LIMIT_EXCEEDED":
return "too many elements";
case "NOT_WELL_FORMED_XML":
return "XML did not parse";
case "NOT_A_CLINICAL_DOCUMENT":
return "root element is not ClinicalDocument";
}
}

NullFlavor​

NullFlavor = typeof NULL_FLAVORS[number]

A valid HL7 v3 NullFlavor token. Datatype nullFlavor fields are typed as string (a non-conforming value is preserved verbatim and flagged with INVALID_NULL_FLAVOR); this union documents the conforming set, which is the whole code system rather than a working subset of it.

Example​

import type { NullFlavor } from "@cosyte/ccda";
const nf: NullFlavor = "ASKU";

ObservationValue​

ObservationValue = { kind: "physicalQuantity"; quantity: PQ; } | { code: CD; kind: "coded"; } | { kind: "string"; nullFlavor?: string; value: string; } | { kind: "integer"; nullFlavor?: string; raw?: string; value?: number; } | { kind: "range"; range: IVL_PQ; } | { kind: "unsupported"; raw?: string; xsiType?: string; }

A parsed observation value, discriminated on kind. physicalQuantity carries a UCUM-checked PQ; coded a CD; string a free-text value; integer a count/score (xsi:type="INT", the type C-CDA prefers for an assessment-scale score, units are not allowed on an INT); range an IVL_PQ. unsupported preserves an xsi:type the model does not specialize (with any raw text) so nothing is ever discarded. integer keeps value and nullFlavor distinct, a scored INT never collapses into an unknown one, and vice versa.

integer and string carry a nullFlavor beside their content for the same reason every v3 datatype does, and integer mirrors PQ exactly: raw is the verbatim @value token and value the parsed number, so when a nullFlavor contradicts the score the parser withholds value and keeps raw (see parsePq). These two arms are parsed inline here rather than through src/model/types/, so they route through the shared contradiction check explicitly.

Example​

import type { ObservationValue } from "@cosyte/ccda";
function numeric(v: ObservationValue): number | undefined {
if (v.kind === "physicalQuantity") return v.quantity.value;
return v.kind === "integer" ? v.value : undefined;
}

OnWarningCallback​

OnWarningCallback = (warning) => void

Callback invoked inline each time the parser emits a Tier-2 warning. Always fires BEFORE the warning is appended to CcdaDocument.warnings so consumers observe warnings in the same order the parser emitted them.

That is emission order, and for one code it is deliberately not discovery order: UNKNOWN_NAMESPACE_PREFIX is found during the pre-parse DOM walk and replayed last, after the model is built. It is a statement about the whole document, and emitting it where it is found would let it take the place of the NOT_A_CLINICAL_DOCUMENT fatal, or of the first safety-critical per-element warning, under { strict: true }, where the first warning is the one that throws. Nothing else is reordered.

Parameters​

warning​

CcdaWarning

Returns​

void

Example​

import { parseCcda, type OnWarningCallback } from "@cosyte/ccda";
const onWarning: OnWarningCallback = (w) => {
console.warn(w.code, w.message);
};
parseCcda(raw, { onWarning });

PlannedActMood​

PlannedActMood = "INT" | "RQO" | "PRMS" | "PRP" | "APT" | "ARQ"

The planned @moodCode for the act / encounter / procedure kinds, the Planned moodCode value set (2.16.840.1.113883.11.20.9.23): INT intent (default), RQO request/order, PRMS promise, PRP proposal, APT appointment, ARQ appointment request. The appointment moods (APT/ARQ) are valid only on these three element domains (x_DocumentActMood / x_DocumentEncounterMood / x_DocumentProcedureMood). EVN (a performed event) is deliberately not a member, the plan carries only future/ordered items, so a performed act can never be emitted into it.

Example​

import type { PlannedActMood } from "@cosyte/ccda";
const appointment: PlannedActMood = "APT";

PlannedItemKind​

PlannedItemKind = "act" | "encounter" | "procedure" | "medicationActivity" | "supply" | "observation" | "immunizationActivity"

Which planned-entry template a PlannedItem came from. Preserved so a consumer can tell a planned medication apart from a planned procedure without re-reading the DOM.

Example​

import type { PlannedItemKind } from "@cosyte/ccda";
const k: PlannedItemKind = "procedure";

PlannedOrderMood​

PlannedOrderMood = "INT" | "RQO" | "PRMS" | "PRP"

The planned @moodCode for the medication / supply / observation kinds. The base CDA R2 mood domains for these elements, x_DocumentSubstanceMood (substanceAdministration/supply) and x_ActMoodDocumentObservation (observation), exclude the appointment moods (APT/ARQ), so those are not representable here (you cannot "appoint" a drug order or a lab). EVN is likewise excluded, the plan is future/ordered, never performed.

Example​

import type { PlannedOrderMood } from "@cosyte/ccda";
const order: PlannedOrderMood = "RQO";

ProblemStatus​

ProblemStatus = ConcernStatus

Resolved active-vs-resolved state of a ProblemConcern.


ProcedureDisposition​

ProcedureDisposition = EventDisposition

The performed-vs-planned disposition of a procedure, derived from its @moodCode: EVN → "performed"; a planned mood (INT/RQO/PRMS/PRP/ APT/ARQ) → "planned". Absent when the mood is missing or unrecognized, never guessed, so a planned procedure is never read as performed.

Example​

import type { ProcedureDisposition } from "@cosyte/ccda";
const d: ProcedureDisposition = "performed";

ProcedureKind​

ProcedureKind = "procedure" | "act" | "observation"

Which of the three Procedure Activity templates an extracted procedure came from, "procedure" (altering/operative), "act" (non-altering service), or "observation" (assessment). Preserved so a consumer can tell an operative act apart from a diagnostic observation without re-reading the DOM.

Example​

import type { ProcedureKind } from "@cosyte/ccda";
const k: ProcedureKind = "procedure";

SectionEdit​

SectionEdit = SectionInput & object

One section add/replace operation: a SectionInput (the section kind plus its typed builder content) with an optional SectionEditMode (default "upsert"). The union is discriminated on kind, so content is typed to exactly that section's BuildCcda* shape.

Type Declaration​

mode?​

readonly optional mode?: SectionEditMode

Example​

import type { SectionEdit } from "@cosyte/ccda";
const addAProblem: SectionEdit = {
kind: "problems",
mode: "replace",
content: [{ problem: { code: "38341003", displayName: "Hypertension" }, status: "active" }],
};

SectionEditMode​

SectionEditMode = "add" | "replace" | "upsert"

How a SectionEdit reconciles with the section already in the document: "add" requires the section be absent (else CcdaEditError SECTION_ALREADY_PRESENT), "replace" requires it be present (else SECTION_ABSENT), and "upsert" (the default) replaces it when present and adds it when absent.

Example​

import type { SectionEditMode } from "@cosyte/ccda";
const mode: SectionEditMode = "add";

StatusDomain​

StatusDomain = "functional" | "mental"

Which status section a StatusObservation came from, "functional" (ADLs, mobility, self-care) or "mental" (cognition, mood). Preserved so a consumer can tell the two apart without re-reading the DOM; the two are never conflated.

Example​

import type { StatusDomain } from "@cosyte/ccda";
const d: StatusDomain = "functional";

WarningCode​

WarningCode = typeof WARNING_CODES[keyof typeof WARNING_CODES]

Discriminant type for CcdaWarning.code. Narrowing a warning by this code lets consumers write exhaustive switch blocks (enabled by the switch-exhaustiveness-check lint rule) and guarantees a typo-free comparison against the WARNING_CODES registry.

Example​

import type { CcdaWarning, WarningCode } from "@cosyte/ccda";
function describe(w: CcdaWarning): string {
const code: WarningCode = w.code;
switch (code) {
case "UNKNOWN_DOCUMENT_TEMPLATE":
return "unrecognized document type";
default:
return `warning: ${code}`;
}
}

Variables​

ccdaProfiles​

const ccdaProfiles: object

Namespace object exposing the built-in profiles: the conservative default baseline plus the two evidence-backed conformance profiles (smartScorecard, legacyR11), each authored via the public defineCcdaProfile() API and carrying its cited public provenance.

Type Declaration​

default​

readonly default: CcdaProfile

legacyR11​

readonly legacyR11: CcdaProfile

smartScorecard​

readonly smartScorecard: CcdaProfile

Example​

import { parseCcda, ccdaProfiles } from "@cosyte/ccda";
const doc = parseCcda(raw, { profile: ccdaProfiles.smartScorecard });
console.log(doc.profile?.name); // "smartScorecard"

CDA_DOCUMENT_OID​

const CDA_DOCUMENT_OID: "2.16.840.1.113883.10.20.22.1.1" = "2.16.840.1.113883.10.20.22.1.1"

Internal

The CDA R2 ClinicalDocument root class code (POCD_MT000040).


CVX​

const CVX: "2.16.840.1.113883.12.292" = "2.16.840.1.113883.12.292"

CVX, CDC vaccine administered code system (immunizations).


DEFAULT_LIMITS​

const DEFAULT_LIMITS: ResolvedLimits

Library-default safety caps applied before DOM construction. Tuned to admit real C-CDA documents (which can embed sizeable base64 images) while still bounding hostile input. Callers tighten or loosen via ParseCcdaOptions.limits.

Example​

import { DEFAULT_LIMITS } from "@cosyte/ccda";
console.log(DEFAULT_LIMITS.maxInputBytes); // 30000000

FATAL_CODES​

const FATAL_CODES: object

Stable string codes for every Tier-3 fatal the parser may throw. Consumers narrow on err.code to react to specific structural or safety failures. Each code is its own value (key === value) so the set survives Object.values(...) into a snapshot tripwire. Renaming a code is a breaking change.

Type Declaration​

ELEMENT_DEPTH_LIMIT_EXCEEDED​

readonly ELEMENT_DEPTH_LIMIT_EXCEEDED: "ELEMENT_DEPTH_LIMIT_EXCEEDED" = "ELEMENT_DEPTH_LIMIT_EXCEEDED"

ENTITY_EXPANSION_LIMIT​

readonly ENTITY_EXPANSION_LIMIT: "ENTITY_EXPANSION_LIMIT" = "ENTITY_EXPANSION_LIMIT"

INPUT_SIZE_LIMIT_EXCEEDED​

readonly INPUT_SIZE_LIMIT_EXCEEDED: "INPUT_SIZE_LIMIT_EXCEEDED" = "INPUT_SIZE_LIMIT_EXCEEDED"

NODE_COUNT_LIMIT_EXCEEDED​

readonly NODE_COUNT_LIMIT_EXCEEDED: "NODE_COUNT_LIMIT_EXCEEDED" = "NODE_COUNT_LIMIT_EXCEEDED"

NOT_A_CLINICAL_DOCUMENT​

readonly NOT_A_CLINICAL_DOCUMENT: "NOT_A_CLINICAL_DOCUMENT" = "NOT_A_CLINICAL_DOCUMENT"

NOT_WELL_FORMED_XML​

readonly NOT_WELL_FORMED_XML: "NOT_WELL_FORMED_XML" = "NOT_WELL_FORMED_XML"

XXE_OR_DTD_PRESENT​

readonly XXE_OR_DTD_PRESENT: "XXE_OR_DTD_PRESENT" = "XXE_OR_DTD_PRESENT"

Example​

import { parseCcda, FATAL_CODES, CcdaParseError } from "@cosyte/ccda";
try {
parseCcda(hostileXml);
} catch (err) {
if (err instanceof CcdaParseError && err.code === FATAL_CODES.XXE_OR_DTD_PRESENT) {
// reject the document, it declared a DTD / external entity
}
}

ICD10_CM​

const ICD10_CM: "2.16.840.1.113883.6.90" = "2.16.840.1.113883.6.90"

ICD-10-CM, US diagnosis coding.


ICD10_PCS​

const ICD10_PCS: "2.16.840.1.113883.6.4" = "2.16.840.1.113883.6.4"

ICD-10-PCS, US inpatient procedure coding.


ICD9_CM_DX​

const ICD9_CM_DX: "2.16.840.1.113883.6.103" = "2.16.840.1.113883.6.103"

ICD-9-CM diagnosis, deprecated in US contexts (replaced by ICD-10-CM).


ICD9_CM_PROC​

const ICD9_CM_PROC: "2.16.840.1.113883.6.104" = "2.16.840.1.113883.6.104"

ICD-9-CM procedure, deprecated (replaced by ICD-10-PCS).


INTERPRETATION​

const INTERPRETATION: "2.16.840.1.113883.5.83" = "2.16.840.1.113883.5.83"

HL7 ObservationInterpretation, the interpretationCode value set source.


LOINC​

const LOINC: "2.16.840.1.113883.6.1" = "2.16.840.1.113883.6.1"

LOINC, observations, lab tests, section/document codes.


NCI_ROUTE​

const NCI_ROUTE: "2.16.840.1.113883.3.26.1.1" = "2.16.840.1.113883.3.26.1.1"

NCI Thesaurus, the C-CDA routeCode value set source.


NDC​

const NDC: "2.16.840.1.113883.6.69" = "2.16.840.1.113883.6.69"

NDC, National Drug Code (packaged products).


NULL_FLAVORS​

const NULL_FLAVORS: readonly ["NI", "INV", "DER", "OTH", "NINF", "PINF", "UNC", "MSK", "NA", "UNK", "ASKU", "NAV", "NASK", "NAVU", "QS", "TRC", "NP"]

The HL7 v3 NullFlavor code system (2.16.840.1.113883.5.1008), which CDA R2 binds @nullFlavor to. All seventeen concepts, transcribed from the published HL7 Terminology CodeSystem/v3-NullFlavor (content: complete, caseSensitive: true, code-system version 4.0.0, THO release 7.3.0): NI, INV, DER, OTH, NINF, PINF, UNC, MSK, NA, UNK, ASKU, NAV, NASK, NAVU, QS, TRC, NP.

It is the whole code system, deliberately, and it used to be eight of the seventeen. A conforming nullFlavor="PINF" on a PQ, or the nullFlavor="NP" a real Plan of Treatment carries on a <code>, drew a false INVALID_NULL_FLAVOR on the published 0.0.4, because the list held only the eight tokens the header and the common datatypes use. Membership here is also the bound that decides whether a templateId's or an ED's nullFlavor is echoed or <withheld> (./ii.ts, ./ed.ts), and widening does not weaken it: every entry is a fixed literal this package owns, so the bound is still "a member of a closed set", now the same closed set the standard defines.

NP carries status: retired in THO. It is admitted anyway, because it is a concept of the code system and INVALID_NULL_FLAVOR says a token is not: saying so about a real code is the false positive, and this package has no deprecation signal for nullFlavor to say anything narrower with.

Example​

import { NULL_FLAVORS } from "@cosyte/ccda";
console.log(NULL_FLAVORS.includes("UNK")); // true

R21_EXTENSION​

const R21_EXTENSION: "2015-08-01" = "2015-08-01"

The C-CDA R2.1 version stamp carried in a recognized templateId/@extension.


RXNORM​

const RXNORM: "2.16.840.1.113883.6.88" = "2.16.840.1.113883.6.88"

RxNorm, clinical drugs and ingredients.


SAFETY_CRITICAL_CODES​

const SAFETY_CRITICAL_CODES: ReadonlySet<WarningCode>

Warning codes no profile may list in its tolerate set. Genuinely immutable: it exposes only the read half of the Set surface and is frozen, so a safety-critical code cannot be deleted at runtime to smuggle it past the gate. (Object.freeze(new Set(...)) would not achieve this, delete mutates an internal slot a freeze does not reach.)

Example​

import { SAFETY_CRITICAL_CODES } from "@cosyte/ccda";
console.log(SAFETY_CRITICAL_CODES.has("MISSING_DOSE_QUANTITY")); // true

SDTC_NS​

const SDTC_NS: "urn:hl7-org:sdtc" = "urn:hl7-org:sdtc"

The HL7 standards-development-organization extension namespace (sdtc), used for attributes/elements the base CDA schema does not define but C-CDA permits (e.g. sdtc:raceCode, sdtc:deceasedInd).

Example​

import { SDTC_NS } from "@cosyte/ccda";
console.log(SDTC_NS); // "urn:hl7-org:sdtc"

SNOMED_CT​

const SNOMED_CT: "2.16.840.1.113883.6.96" = "2.16.840.1.113883.6.96"

SNOMED CT, clinical findings, problems, allergen substances.


SYNTHETIC_SETID_PREFIX​

const SYNTHETIC_SETID_PREFIX: "SYNTHETIC-SETID" = "SYNTHETIC-SETID"

The @extension prefix every setId editCcda mints carries, so a minted version-series identifier is recognisable as one on sight and in code.

A minted setId looks like SYNTHETIC-SETID-e1 under the synthetic assigning-authority root 2.16.840.1.113883.19.5.99999 (an OID in HL7's own example arc, which is not an organisation's real namespace). Together those two are the whole scheme; isSyntheticSetId is the check.

A setId the source already carried, or one the caller supplied through revision.setId, is never relabelled. The prefix marks what this library invented, and only that.

The residual, stated rather than implied: nothing forces a receiving system to read the label. A receiver that ignores both the prefix and the root will treat a minted setId exactly as it treats a real one, and this library cannot make it do otherwise. Making it obvious is the whole of what a label can do; it does not make the identifier true. The alternative considered and rejected was to stop minting, which would emit a replacement whose setId does not match its own parentDocument's, and CDA R2 requires that it does.

Example​

import { SYNTHETIC_SETID_PREFIX } from "@cosyte/ccda";
console.log(SYNTHETIC_SETID_PREFIX); // "SYNTHETIC-SETID"

UNII​

const UNII: "2.16.840.1.113883.4.9" = "2.16.840.1.113883.4.9"

UNII, FDA Unique Ingredient Identifier (substances/allergens).


V3_NS​

const V3_NS: "urn:hl7-org:v3" = "urn:hl7-org:v3"

The HL7 v3 / CDA R2 default namespace. Every structural C-CDA element (ClinicalDocument, recordTarget, section, …) lives here.

Example​

import { V3_NS } from "@cosyte/ccda";
console.log(V3_NS); // "urn:hl7-org:v3"

VERSION​

const VERSION: string = "0.0.14"

Library version string, synced with package.json#version at build time.

Example​

import { VERSION } from "@cosyte/ccda";
console.log(VERSION);

WARNING_CODES​

const WARNING_CODES: object

Stable string codes for every Tier-2 warning the parser may emit. The registry is frozen via as const so TypeScript infers the exact string literal union for WarningCode, there is zero runtime cost and no magic-string comparisons for consumers. Each code is its own value (key === value) so the set survives Object.values(...) into a snapshot tripwire. Renaming a code is a breaking change.

Type Declaration​

ALLERGEN_GRANULARITY_SUSPECT​

readonly ALLERGEN_GRANULARITY_SUSPECT: "ALLERGEN_GRANULARITY_SUSPECT" = "ALLERGEN_GRANULARITY_SUSPECT"

CODE_NARRATIVE_MISMATCH​

readonly CODE_NARRATIVE_MISMATCH: "CODE_NARRATIVE_MISMATCH" = "CODE_NARRATIVE_MISMATCH"

CONTRADICTORY_NULL_FLAVOR​

readonly CONTRADICTORY_NULL_FLAVOR: "CONTRADICTORY_NULL_FLAVOR" = "CONTRADICTORY_NULL_FLAVOR"

DEPRECATED_CODE_SYSTEM​

readonly DEPRECATED_CODE_SYSTEM: "DEPRECATED_CODE_SYSTEM" = "DEPRECATED_CODE_SYSTEM"

DEPRECATED_LOINC​

readonly DEPRECATED_LOINC: "DEPRECATED_LOINC" = "DEPRECATED_LOINC"

ENCODING_BOM_STRIPPED​

readonly ENCODING_BOM_STRIPPED: "ENCODING_BOM_STRIPPED" = "ENCODING_BOM_STRIPPED"

FREE_TEXT_REFERENCE_RANGE​

readonly FREE_TEXT_REFERENCE_RANGE: "FREE_TEXT_REFERENCE_RANGE" = "FREE_TEXT_REFERENCE_RANGE"

IMMUNIZATION_REFUSED​

readonly IMMUNIZATION_REFUSED: "IMMUNIZATION_REFUSED" = "IMMUNIZATION_REFUSED"

INVALID_NULL_FLAVOR​

readonly INVALID_NULL_FLAVOR: "INVALID_NULL_FLAVOR" = "INVALID_NULL_FLAVOR"

MALFORMED_DATETIME​

readonly MALFORMED_DATETIME: "MALFORMED_DATETIME" = "MALFORMED_DATETIME"

MEDICATION_PRODUCT_ARM_CONFLICT​

readonly MEDICATION_PRODUCT_ARM_CONFLICT: "MEDICATION_PRODUCT_ARM_CONFLICT" = "MEDICATION_PRODUCT_ARM_CONFLICT"

MEDICATION_PRODUCT_ARM_REPEATED​

readonly MEDICATION_PRODUCT_ARM_REPEATED: "MEDICATION_PRODUCT_ARM_REPEATED" = "MEDICATION_PRODUCT_ARM_REPEATED"

MEDICATION_PRODUCT_ARM_UNEXPECTED​

readonly MEDICATION_PRODUCT_ARM_UNEXPECTED: "MEDICATION_PRODUCT_ARM_UNEXPECTED" = "MEDICATION_PRODUCT_ARM_UNEXPECTED"

MEDICATION_PRODUCT_CODE_REPEATED​

readonly MEDICATION_PRODUCT_CODE_REPEATED: "MEDICATION_PRODUCT_CODE_REPEATED" = "MEDICATION_PRODUCT_CODE_REPEATED"

MEDICATION_PRODUCT_CODE_TRANSLATION_ONLY​

readonly MEDICATION_PRODUCT_CODE_TRANSLATION_ONLY: "MEDICATION_PRODUCT_CODE_TRANSLATION_ONLY" = "MEDICATION_PRODUCT_CODE_TRANSLATION_ONLY"

MISSING_ASSIGNING_AUTHORITY​

readonly MISSING_ASSIGNING_AUTHORITY: "MISSING_ASSIGNING_AUTHORITY" = "MISSING_ASSIGNING_AUTHORITY"

MISSING_CODE_SYSTEM​

readonly MISSING_CODE_SYSTEM: "MISSING_CODE_SYSTEM" = "MISSING_CODE_SYSTEM"

MISSING_CODE_VALUE​

readonly MISSING_CODE_VALUE: "MISSING_CODE_VALUE" = "MISSING_CODE_VALUE"

MISSING_DOSE_QUANTITY​

readonly MISSING_DOSE_QUANTITY: "MISSING_DOSE_QUANTITY" = "MISSING_DOSE_QUANTITY"

MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME​

readonly MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME: "MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME" = "MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME"

MISSING_PRODUCT_CODE​

readonly MISSING_PRODUCT_CODE: "MISSING_PRODUCT_CODE" = "MISSING_PRODUCT_CODE"

MISSING_ROUTE_CODE​

readonly MISSING_ROUTE_CODE: "MISSING_ROUTE_CODE" = "MISSING_ROUTE_CODE"

MISSING_TEMPLATE_ID​

readonly MISSING_TEMPLATE_ID: "MISSING_TEMPLATE_ID" = "MISSING_TEMPLATE_ID"

MISSING_UNIT_ON_PQ​

readonly MISSING_UNIT_ON_PQ: "MISSING_UNIT_ON_PQ" = "MISSING_UNIT_ON_PQ"

MULTIPLE_EFFECTIVE_TIMES_UNRESOLVED​

readonly MULTIPLE_EFFECTIVE_TIMES_UNRESOLVED: "MULTIPLE_EFFECTIVE_TIMES_UNRESOLVED" = "MULTIPLE_EFFECTIVE_TIMES_UNRESOLVED"

MULTIPLE_RECORD_TARGETS​

readonly MULTIPLE_RECORD_TARGETS: "MULTIPLE_RECORD_TARGETS" = "MULTIPLE_RECORD_TARGETS"

NARRATIVE_REFERENCE_BROKEN​

readonly NARRATIVE_REFERENCE_BROKEN: "NARRATIVE_REFERENCE_BROKEN" = "NARRATIVE_REFERENCE_BROKEN"

NEGATION_VS_NULLFLAVOR_AMBIGUOUS​

readonly NEGATION_VS_NULLFLAVOR_AMBIGUOUS: "NEGATION_VS_NULLFLAVOR_AMBIGUOUS" = "NEGATION_VS_NULLFLAVOR_AMBIGUOUS"

NON_UCUM_UNIT​

readonly NON_UCUM_UNIT: "NON_UCUM_UNIT" = "NON_UCUM_UNIT"

PLAN_ENTRY_NOT_MODELED​

readonly PLAN_ENTRY_NOT_MODELED: "PLAN_ENTRY_NOT_MODELED" = "PLAN_ENTRY_NOT_MODELED"

PLANNED_VS_PERFORMED_AMBIGUOUS​

readonly PLANNED_VS_PERFORMED_AMBIGUOUS: "PLANNED_VS_PERFORMED_AMBIGUOUS" = "PLANNED_VS_PERFORMED_AMBIGUOUS"

PROBLEM_STATUS_INDETERMINATE​

readonly PROBLEM_STATUS_INDETERMINATE: "PROBLEM_STATUS_INDETERMINATE" = "PROBLEM_STATUS_INDETERMINATE"

PROCEDURE_MOOD_UNEXPECTED​

readonly PROCEDURE_MOOD_UNEXPECTED: "PROCEDURE_MOOD_UNEXPECTED" = "PROCEDURE_MOOD_UNEXPECTED"

PROFILE_QUIRK_APPLIED​

readonly PROFILE_QUIRK_APPLIED: "PROFILE_QUIRK_APPLIED" = "PROFILE_QUIRK_APPLIED"

REQUIRED_SECTION_MISSING​

readonly REQUIRED_SECTION_MISSING: "REQUIRED_SECTION_MISSING" = "REQUIRED_SECTION_MISSING"

RESULT_VALUE_TYPE_UNHANDLED​

readonly RESULT_VALUE_TYPE_UNHANDLED: "RESULT_VALUE_TYPE_UNHANDLED" = "RESULT_VALUE_TYPE_UNHANDLED"

SECTION_MATCHED_BY_LOINC_FALLBACK​

readonly SECTION_MATCHED_BY_LOINC_FALLBACK: "SECTION_MATCHED_BY_LOINC_FALLBACK" = "SECTION_MATCHED_BY_LOINC_FALLBACK"

SECTION_PLACEMENT_SUSPECT​

readonly SECTION_PLACEMENT_SUSPECT: "SECTION_PLACEMENT_SUSPECT" = "SECTION_PLACEMENT_SUSPECT"

SEMANTIC_CODE_INVALID​

readonly SEMANTIC_CODE_INVALID: "SEMANTIC_CODE_INVALID" = "SEMANTIC_CODE_INVALID"

SMOKING_STATUS_CODE_UNRECOGNIZED​

readonly SMOKING_STATUS_CODE_UNRECOGNIZED: "SMOKING_STATUS_CODE_UNRECOGNIZED" = "SMOKING_STATUS_CODE_UNRECOGNIZED"

SMOKING_STATUS_UNKNOWN​

readonly SMOKING_STATUS_UNKNOWN: "SMOKING_STATUS_UNKNOWN" = "SMOKING_STATUS_UNKNOWN"

TEMPLATE_EXTENSION_ABSENT​

readonly TEMPLATE_EXTENSION_ABSENT: "TEMPLATE_EXTENSION_ABSENT" = "TEMPLATE_EXTENSION_ABSENT"

UCUM_CASE_SUSPECT​

readonly UCUM_CASE_SUSPECT: "UCUM_CASE_SUSPECT" = "UCUM_CASE_SUSPECT"

UNEXPECTED_CODE_SYSTEM​

readonly UNEXPECTED_CODE_SYSTEM: "UNEXPECTED_CODE_SYSTEM" = "UNEXPECTED_CODE_SYSTEM"

UNKNOWN_DOCUMENT_TEMPLATE​

readonly UNKNOWN_DOCUMENT_TEMPLATE: "UNKNOWN_DOCUMENT_TEMPLATE" = "UNKNOWN_DOCUMENT_TEMPLATE"

UNKNOWN_NAMESPACE_PREFIX​

readonly UNKNOWN_NAMESPACE_PREFIX: "UNKNOWN_NAMESPACE_PREFIX" = "UNKNOWN_NAMESPACE_PREFIX"

UNKNOWN_SECTION_CODE​

readonly UNKNOWN_SECTION_CODE: "UNKNOWN_SECTION_CODE" = "UNKNOWN_SECTION_CODE"

Example​

import { parseCcda, WARNING_CODES } from "@cosyte/ccda";
const doc = parseCcda(raw);
if (doc.warnings.some((w) => w.code === WARNING_CODES.UNKNOWN_DOCUMENT_TEMPLATE)) {
// handle an unrecognized document type
}

XSI_NS​

const XSI_NS: "http://www.w3.org/2001/XMLSchema-instance" = "http://www.w3.org/2001/XMLSchema-instance"

The XML Schema Instance namespace. Carries the xsi:type attribute that selects a concrete HL7 v3 datatype for a polymorphic element (e.g. value xsi:type="PQ").

Example​

import { XSI_NS } from "@cosyte/ccda";
console.log(XSI_NS); // "http://www.w3.org/2001/XMLSchema-instance"

Functions​

applyProfile()​

applyProfile(profile, warning): CcdaWarning

Apply a profile to a single warning. Returns a downgraded PROFILE_QUIRK_APPLIED warning when the profile expects this deviation; otherwise returns the original warning unchanged (referential identity preserved, so an un-tolerated warning is never reallocated). A warning that is already expected (e.g. re-processed) is passed through untouched.

Parameters​

profile​

CcdaProfile

warning​

CcdaWarning

Returns​

CcdaWarning

Example​

import { applyProfile, ccdaProfiles, parseCcda } from "@cosyte/ccda";
const w = parseCcda(raw).warnings[0]!;
const out = applyProfile(ccdaProfiles.smartScorecard, w);
console.log(out.code); // "PROFILE_QUIRK_APPLIED"
console.log(out.toleratedCode); // "DEPRECATED_LOINC"

attr()​

attr(el, name): string | undefined

Read an unprefixed attribute, returning undefined (never null or "") when the attribute is absent or empty, matches the exactOptionalPropertyTypes "omit, don't set undefined" discipline used throughout the model.

Parameters​

el​

Element

name​

string

Returns​

string | undefined

Example​

import { attr } from "@cosyte/ccda";
const root = attr(el, "root"); // string | undefined

buildCcda()​

buildCcda(init, options?): CcdaDocument

Build a spec-clean C-CDA R2.1 document from structured input and return the parsed CcdaDocument. Emits a CCD by default, or a Referral Note when documentType: "referralNote", each with its own US Realm Header specialization (document templateId + LOINC code) and SHALL section set. The emitted document round-trips through parseCcda by construction (see the module doc); a clean build carries zero warnings.

Parameters​

init​

BuildCcdaInit

The document content; see BuildCcdaInit. patient is required.

options?​

BuildCcdaOptions = {}

Optional BuildCcdaOptions; pass a bring-your-own terminology adapter to have the returned document flag adapter-rejected codes (SEMANTIC_CODE_INVALID) and to emit <translation> alternate codings from its optional translate. The builder never coerces a code to satisfy the adapter, every primary value is emitted verbatim and a <translation> is only ever an additional alternate coding.

Returns​

CcdaDocument

The parsed document, the parse of the spec-clean XML just emitted, carrying the re-parse's warnings plus any build-time diagnostic about the input (today: MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME, appended last).

Throws​

When documentType is anything other than "ccd" or "referralNote" (the only two types this builder supports), when an allergy is neither an allergen nor noKnownAllergy, when a result does not carry exactly one value form (quantity / codedValue / stringValue), when a "observation"-variant procedure omits its SHALL value, when a family-history entry carries an empty observations list, or when a problem or allergy supplies a resolution date without status: "resolved".

Example​

import { buildCcda, serializeCcda } from "@cosyte/ccda";
const doc = buildCcda({
patient: { mrn: "MRN001", given: ["Jane"], family: "Doe", gender: "F" },
problems: [{ problem: { code: "59621000", displayName: "Essential hypertension" } }],
allergies: [{ allergen: { code: "7980", displayName: "Penicillin G" } }],
});
console.log(doc.getMrn()); // "MRN001"
console.log(doc.getProblems().length); // 1
const xml = serializeCcda(doc); // spec-clean C-CDA R2.1

buildDocument()​

buildDocument(root, ctx): Omit<CcdaDocumentInit, "warnings">

Build the CcdaDocumentInit parts (everything except warnings) from a ClinicalDocument root element. Recognizes the document type, parses the header, and frames the body, a structuredBody yields sections; a nonXMLBody yields the quarantined nonXmlBody content. Never throws; the orchestrator supplies warnings and constructs the CcdaDocument.

Parameters​

root​

Element

ctx​

ParseCtx

Returns​

Omit<CcdaDocumentInit, "warnings">

Example​

import { buildDocument, CcdaDocument } from "@cosyte/ccda";
const parts = buildDocument(root, ctx);
const doc = new CcdaDocument({ ...parts, warnings: [] });

buildHeader()​

buildHeader(root, ctx): CcdaHeader

Extract the CcdaHeader from a ClinicalDocument root element. Never throws; omits any field the document does not carry. Emits MULTIPLE_RECORD_TARGETS when more than one recordTarget is present.

Parameters​

root​

Element

ctx​

ParseCtx

Returns​

CcdaHeader

Example​

import { buildHeader } from "@cosyte/ccda";
const header = buildHeader(rootEl, { emit: () => {} });
console.log(header.title, header.recordTargets.length);

buildNarrativeIndex()​

buildNarrativeIndex(textEl): ReadonlyMap<string, string>

Index a narrative <text> block by the ID attributes carried on its descendant elements, mapping each ID to that node's trimmed text. C-CDA entries reference narrative via <reference value="#id">; this index lets the entry layer resolve those references without re-walking the DOM.

Parameters​

textEl​

Element

Returns​

ReadonlyMap<string, string>

Example​

import { buildNarrativeIndex, child } from "@cosyte/ccda";
const index = buildNarrativeIndex(child(sectionEl, "text")!);
console.log(index.get("problem1"));

buildSection()​

buildSection(el, ctx): CcdaSection

Frame a <section> element into a CcdaSection. Recognizes the section by templateId root (primary) or LOINC code (fallback, emitting SECTION_MATCHED_BY_LOINC_FALLBACK); an unrecognized coded section emits UNKNOWN_SECTION_CODE and is retained as narrative-only. Recurses into nested <component><section> subsections. Never throws.

Parameters​

el​

Element

ctx​

ParseCtx

Returns​

CcdaSection

Example​

import { buildSection } from "@cosyte/ccda";
const section = buildSection(sectionEl, { emit: () => {} });
console.log(section.key, section.subsections.length);

checkCodeSlot()​

checkCodeSlot(code, slot, position, ctx): void

Validate a coded value's @codeSystem against the terminologies expected for its CodeSlot. Emits DEPRECATED_CODE_SYSTEM for a known-deprecated system (ICD-9) and UNEXPECTED_CODE_SYSTEM for any other unexpected OID.

A CD that asserts a @code with no @codeSystem emits MISSING_CODE_SYSTEM: the symbol names no terminology, so it can be neither read nor checked. No system is ever inferred for it (not from the slot's expected list, not from a @codeSystemName label), and it is therefore never handed to a TerminologyAdapter, which validates a system + code pair.

The mirror shape emits MISSING_CODE_VALUE: a CD that is present but asserts no usable @code (absent, empty, or whitespace) and declares no @nullFlavor, e.g. a system-only <value codeSystem="…6.96"/>. A code system without a symbol identifies a concept no better than a symbol without a system does. The nullFlavor is what separates the two cases: a nullFlavor-only CD is a complete statement ("this concept is unknown") and stays silent, while a CD that says nothing at all leaves a reader unable to tell an absent concept from one lost in transformation. An absent value stays silent too, there is no element to judge.

The value is preserved verbatim in every case, and no code, system, or nullFlavor is ever inferred.

Parameters​

code​

CD | undefined

slot​

"problem" | "medication" | "allergen" | "route" | "vaccine"

position​
column?​

number

line?​

number

path?​

string

ctx​

ParseCtx

Returns​

void

Example​

import { checkCodeSlot } from "@cosyte/ccda";
checkCodeSlot(problemValue, "problem", { path: "value" }, ctx);

checkLoincDeprecation()​

checkLoincDeprecation(code, position, ctx): void

Flag a result/vital observation code that is a known-deprecated LOINC. Emits DEPRECATED_LOINC (code preserved) only when the value is in the LOINC code system and a recognized-deprecated code; otherwise silent. A value with no code or a non-LOINC system is left unchecked.

Parameters​

code​

CD | undefined

position​

CcdaPosition

ctx​

ParseCtx

Returns​

void

Example​

import { checkLoincDeprecation } from "@cosyte/ccda";
checkLoincDeprecation(observationCode, { path: "code" }, ctx);

checkUcumUnit()​

checkUcumUnit(quantity, position, ctx): void

Validate a PQ's @unit with the computable UCUM grammar, emitting the appropriate Tier-2 warning: MISSING_UNIT_ON_PQ (numeric value, no unit), UCUM_CASE_SUSPECT (a letter-case slip of a canonical unit), or NON_UCUM_UNIT (not well-formed UCUM). The quantity itself is never mutated, the raw unit is always preserved.

Parameters​

quantity​

PQ

position​

CcdaPosition

ctx​

ParseCtx

Returns​

void

Example​

import { checkUcumUnit } from "@cosyte/ccda";
checkUcumUnit({ value: 5, unit: "cc" }, { path: "value" }, ctx);

child()​

child(el, localName): any

Return the first direct child element in the HL7 v3 namespace with the given local name, or undefined. Only direct children are considered (no descendant search), so structurally distinct same-named elements at deeper levels are not accidentally matched.

Parameters​

el​

Element

localName​

string

Returns​

any

Example​

import { child } from "@cosyte/ccda";
const code = child(sectionEl, "code"); // Element | undefined

childElements()​

childElements(el): readonly Element[]

Return all direct child elements (any namespace), in document order. Used where the caller wants to enumerate structure without filtering by name.

Parameters​

el​

Element

Returns​

readonly Element[]

Example​

import { childElements } from "@cosyte/ccda";
const kids = childElements(el);

children()​

children(el, localName): readonly Element[]

Return all direct child elements in the HL7 v3 namespace with the given local name, in document order. Empty array when none match.

Parameters​

el​

Element

localName​

string

Returns​

readonly Element[]

Example​

import { children } from "@cosyte/ccda";
for (const comp of children(bodyEl, "component")) {
// ...
}

defineCcdaProfile()​

defineCcdaProfile(opts): CcdaProfile

Build a frozen CcdaProfile from a validated options object. Throws CcdaProfileDefinitionError on a bad name, an unknown option key, or an invalid tolerate entry, including the safety rule: a profile may never tolerate a safety-critical warning code.

extends composes profiles: lineage, tolerate, provenance, and description merge (parents left-to-right, then self; scalars are child-wins). The merged tolerate set is re-validated so a safety-critical code cannot sneak in via a hand-crafted parent.

Parameters​

opts​

DefineCcdaProfileOptions

The profile definition; see DefineCcdaProfileOptions.

Returns​

CcdaProfile

A frozen, immutable profile with describe() attached.

Throws​

CcdaProfileDefinitionError on any invalid definition.

Example​

import { defineCcdaProfile } from "@cosyte/ccda";
const site = defineCcdaProfile({
name: "acme-hospital",
description: "Acme's inbound-CCD tolerances",
tolerate: [
{ code: "TEMPLATE_EXTENSION_ABSENT", rationale: "receives R1.1-origin CCDs" },
],
provenance: { source: "Acme integration corpus", reference: "internal-2026" },
});
console.log(site.lineage); // ["acme-hospital"]
console.log(site.describe?.());

documentTypeForOid()​

documentTypeForOid(oid): DocumentType | undefined

Resolve a document-template OID to its DocumentType, or undefined when the OID is not one of the twelve recognized C-CDA R2.1 types.

Parameters​

oid​

string

Returns​

DocumentType | undefined

Example​

import { documentTypeForOid } from "@cosyte/ccda";
documentTypeForOid("2.16.840.1.113883.10.20.22.1.2"); // "ccd"
documentTypeForOid("1.2.3"); // undefined

editCcda()​

editCcda(source, options?): CcdaDocument

Re-emit a parsed C-CDA document with sections added or replaced, preserving every unedited section byte-faithfully and (by default) stamping a CDA R2 revision that supersedes the source. See the module overview for the full contract.

Parameters​

source​

CcdaDocument

A document produced by parseCcda (it must retain its source XML, a hand-constructed document throws NO_SOURCE_DOCUMENT).

options?​

EditCcdaOptions = {}

The section edits to apply, the revision behavior, and an optional bring-your-own terminology adapter forwarded to the final re-parse so the edited document flags adapter-rejected codes (SEMANTIC_CODE_INVALID).

Returns​

CcdaDocument

A new CcdaDocument, the re-parse of the edited XML, plus any emit-time diagnostic about what this call grafted (today only MISSING_PLANNED_MEDICATION_EFFECTIVE_TIME, appended last). The source is never mutated.

Throws​

CcdaEditError when the source has no retained XML, has no structuredBody to edit, violates an add/replace precondition, would drop a SHALL required section, or (when stamping a revision) has no usable ClinicalDocument.id for the RPLC link to name, absent or nullFlavor-marked (SOURCE_MISSING_ID).

Throws​

when a section's content violates a builder guard (an invalid timestamp, a resolved problem without a resolution date, …).

Example​

import { parseCcda, editCcda } from "@cosyte/ccda";
const doc = parseCcda(xml);
const revised = editCcda(doc, {
sections: [
{
kind: "problems",
content: [{ problem: { code: "38341003", displayName: "Hypertension" }, status: "active" }],
},
],
});
console.log(revised.header.versionNumber); // incremented from the source

extractAllergies()​

extractAllergies(sectionEl, narrativeById, ctx): readonly AllergyConcern[]

Extract every Allergy Concern Act from an Allergies <section> element. Each <entry> whose act carries the Allergy Concern Act template becomes an AllergyConcern; the nested Allergy-Intolerance Observations become Allergys (including the "No Known Allergies" negated form). Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly AllergyConcern[]

Example​

import { extractAllergies } from "@cosyte/ccda";
const concerns = extractAllergies(sectionEl, section.narrativeById, ctx);

extractClinical()​

extractClinical(structuredBody, ctx): ClinicalEntries

Extract the reconciliation triad from a structuredBody element. Walks every section, runs each triad extractor, and flags misplaced entries. Never throws; an unstructured document (no structuredBody) is handled by the caller and never reaches here.

Parameters​

structuredBody​

Element

ctx​

ParseCtx

Returns​

ClinicalEntries

Example​

import { extractClinical } from "@cosyte/ccda";
const entries = extractClinical(structuredBodyEl, ctx);
console.log(entries.problems.length);

extractEncounters()​

extractEncounters(sectionEl, narrativeById, ctx): readonly Encounter[]

Extract every Encounter Activity from an Encounters <section> element. Each <entry> whose encounter carries the Encounter Activity template becomes an Encounter. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly Encounter[]

Example​

import { extractEncounters } from "@cosyte/ccda";
const encounters = extractEncounters(sectionEl, section.narrativeById, ctx);

extractFamilyHistory()​

extractFamilyHistory(sectionEl, narrativeById, ctx): readonly FamilyHistory[]

Extract every Family History Organizer from a Family History <section> element. Each <entry> whose organizer carries the Family History Organizer template becomes a FamilyHistory; its component/observation members become FamilyHistoryObservations. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly FamilyHistory[]

Example​

import { extractFamilyHistory } from "@cosyte/ccda";
const history = extractFamilyHistory(sectionEl, section.narrativeById, ctx);

extractFunctionalStatus()​

extractFunctionalStatus(sectionEl, narrativeById, ctx): readonly StatusObservation[]

Extract every Functional Status finding from a Functional Status <section> element, standalone Functional Status Observations plus the members (observations and assessment scales) of any Functional Status Organizer. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly StatusObservation[]

Example​

import { extractFunctionalStatus } from "@cosyte/ccda";
const findings = extractFunctionalStatus(sectionEl, section.narrativeById, ctx);

extractImmunizations()​

extractImmunizations(sectionEl, narrativeById, ctx): readonly Immunization[]

Extract every Immunization Activity from an Immunizations <section> element. Each <entry> whose substanceAdministration carries the Immunization Activity template becomes an Immunization. A negationInd record is flagged IMMUNIZATION_REFUSED. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly Immunization[]

Example​

import { extractImmunizations } from "@cosyte/ccda";
const shots = extractImmunizations(sectionEl, section.narrativeById, ctx);

extractMedications()​

extractMedications(sectionEl, narrativeById, ctx): readonly Medication[]

Extract every Medication Activity from a Medications <section> element. Each <entry> whose substanceAdministration carries the Medication Activity template becomes a Medication. Flags a missing doseQuantity / routeCode and an unclassifiable effectiveTime. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly Medication[]

Example​

import { extractMedications } from "@cosyte/ccda";
const meds = extractMedications(sectionEl, section.narrativeById, ctx);

extractMentalStatus()​

extractMentalStatus(sectionEl, narrativeById, ctx): readonly StatusObservation[]

Extract every Mental Status finding from a Mental Status <section> element, standalone Mental Status Observations plus the members (observations and assessment scales) of any Mental Status Organizer. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly StatusObservation[]

Example​

import { extractMentalStatus } from "@cosyte/ccda";
const findings = extractMentalStatus(sectionEl, section.narrativeById, ctx);

extractPastMedicalHistory()​

extractPastMedicalHistory(sectionEl, narrativeById, ctx): readonly Problem[]

Extract every bare Problem Observation from a Past Medical History <section> element. Each <entry> whose direct observation carries the Problem Observation template becomes a Problem. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly Problem[]

Example​

import { extractPastMedicalHistory } from "@cosyte/ccda";
const history = extractPastMedicalHistory(sectionEl, section.narrativeById, ctx);

extractPlannedItems()​

extractPlannedItems(sectionEl, narrativeById, ctx): readonly PlannedItem[]

Extract every planned item from a <section> element: each <entry> whose act carries one of the seven templates in PLANNED_VARIANTS, and each of the seven nested inside a Planned Intervention Act (PLANNED_INTERVENTION_ACT, …22.4.146). Never throws.

The container is named rather than inferred, and it is the only one. R2.1 gives the Planned Intervention Act an entryRelationship for every one of the seven, each holding the planned act inline, so before this a planned entry sitting there was returned as nothing with nothing said, for all seven kinds. A Planned Intervention Act nested in a Planned Intervention Act is descended into too, because the walk is the same walk; the DOM is a tree, so it terminates.

It is the only container descended into, and R2.1 has others, so this does NOT solve nesting in general. A Nutrition Recommendation (…22.4.130) inline-holds six of the seven by the identical entryRelationship pattern (every planned template except …22.4.120), and an Intervention Act (…22.4.131, the performed sibling and the SHOULD entry of an Interventions Section) inline-holds a Planned Intervention Act. A planned entry in either is still returned as nothing with nothing said. That is left as it was found: the scope taken here is the one container, and widening it is a decision with its own base-measured matrix, not a tidy-up. A test pins both as unreached so the bound is measured rather than asserted.

An entryRelationship is read for what it CONTAINS, never followed for what it REFERENCES. The template's [1..*] typeCode="RSON" relationship holds an Entry Reference (…22.4.122) whose own SHALL points at a Goal Observation. That act carries no planned template root, so it is walked past rather than resolved: its target lives elsewhere in the document and is reached on its own terms, and resolving a pointer here would return an item the container does not hold.

Which acts a Planned Intervention Act holds and this still does not return: the performed ones (MedicationActivity, ImmunizationActivity, ProcedureActivityProcedure, EncounterActivity, and the rest, none of which is planned and none of which carries a planned root), and the same three non-item templates the section itself admits (Instruction …22.4.20, Handoff Communication Participants …22.4.141, Nutrition Recommendation …22.4.130). Those three are now REPORTED at both levels (PLAN_ENTRY_NOT_MODELED), still not returned. The performed acts are not, and must not be: they are modelled elsewhere and reached by their own extractors, so a "not modelled" report on one would be false.

The two levels are scoped differently, and the scope is a BOUND this package chose, not a catalog of which sections C-CDA admits these templates in. A direct <entry> is reported in the two sections named on PLAN_ENTRY_REPORT_SECTION_KEYS: planOfTreatment, the section this accessor is named for, and interventions, the Interventions Section (V3), which admits a Handoff as a direct entry in as many words (CONF:1198-32402 / 1198-32403, quoted on that constant) and is where R2.1 puts the container the nested half already reads. Inside a Planned Intervention Act there is no section condition at all, because the container is what the report is relative to there and it is read wherever it sits.

An Instruction sitting in the Instructions Section (…22.2.45) is deliberately still silent: it is that section's own required entry, and reporting a conformant document's required entry as "not modelled" would be noise rather than a finding.

The residual, stated rather than implied: these three templates appear in more places than the report covers, and an occurrence outside them is still dropped in silence. Two are measured and pinned by test. A Handoff nested in an Intervention Act (…22.4.131) is silent, because that act is not a container this package descends into. Any of the three as a direct entry of a section this catalog does not recognize at all is silent, because there is no key to match. Widening further is its own decision with its own base-measured matrix, not a tidy-up.

A returned item does not say whether it was a direct <entry> or nested. The Planned Intervention Act is not modelled: this package carries no container type, no goal linkage, and no nested flag, so the grouping toward a goal is available only from doc.toString(). What getPlannedItems() answers is which acts are planned for this patient, and a nested one is planned on exactly the same terms as a direct one. Each item keeps its own ids, so a caller that needs the grouping can correlate.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly PlannedItem[]

Example​

import { extractPlannedItems } from "@cosyte/ccda";
const planned = extractPlannedItems(sectionEl, section.narrativeById, ctx);

extractProblems()​

extractProblems(sectionEl, narrativeById, ctx): readonly ProblemConcern[]

Extract every Problem Concern Act from a Problems <section> element. Each <entry> whose act carries the Problem Concern Act template becomes a ProblemConcern; the nested Problem Observations become Problems. Reconciles each problem's coded value against its narrative reference. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly ProblemConcern[]

Example​

import { extractProblems } from "@cosyte/ccda";
const concerns = extractProblems(sectionEl, section.narrativeById, ctx);

extractProcedures()​

extractProcedures(sectionEl, narrativeById, ctx): readonly Procedure[]

Extract every procedure from a Procedures <section> element. Each <entry> whose procedure/act/observation carries one of the three Procedure Activity templates becomes a Procedure. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly Procedure[]

Example​

import { extractProcedures } from "@cosyte/ccda";
const procedures = extractProcedures(sectionEl, section.narrativeById, ctx);

extractResults()​

extractResults(sectionEl, narrativeById, ctx): readonly ResultOrganizer[]

Extract every Result Organizer from a Results <section> element. Each <entry> whose organizer carries the Result Organizer template becomes a ResultOrganizer; its component/observation members become Results. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly ResultOrganizer[]

Example​

import { extractResults } from "@cosyte/ccda";
const panels = extractResults(sectionEl, section.narrativeById, ctx);

extractSmokingStatus()​

extractSmokingStatus(sectionEl, narrativeById, ctx): readonly SmokingStatus[]

Extract every Smoking Status observation from a Social History <section> element. Each <entry> whose observation carries the Smoking Status, Meaningful Use template becomes a SmokingStatus. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly SmokingStatus[]

Example​

import { extractSmokingStatus } from "@cosyte/ccda";
const statuses = extractSmokingStatus(sectionEl, section.narrativeById, ctx);

extractVitals()​

extractVitals(sectionEl, narrativeById, ctx): readonly VitalSignsOrganizer[]

Extract every Vital Signs Organizer from a Vital Signs <section> element. Each <entry> whose organizer carries the Vital Signs Organizer template becomes a VitalSignsOrganizer; its component/observation members become VitalSigns. Never throws.

Parameters​

sectionEl​

Element

narrativeById​

ReadonlyMap<string, string>

ctx​

ParseCtx

Returns​

readonly VitalSignsOrganizer[]

Example​

import { extractVitals } from "@cosyte/ccda";
const clusters = extractVitals(sectionEl, section.narrativeById, ctx);

getCcdaProfile()​

getCcdaProfile(name): CcdaProfile | undefined

Look up a built-in profile by name. Returns undefined when no built-in has that name (a user-defined profile is not in this registry, pass it directly).

Parameters​

name​

string

Returns​

CcdaProfile | undefined

Example​

import { getCcdaProfile } from "@cosyte/ccda";
const p = getCcdaProfile("smartScorecard");
console.log(p?.provenance?.source);

getDefaultCcdaProfile()​

getDefaultCcdaProfile(): CcdaProfile | undefined

Return the current process-scoped default profile, or undefined if none is registered.

Returns​

CcdaProfile | undefined

Example​

import { getDefaultCcdaProfile } from "@cosyte/ccda";
const p = getDefaultCcdaProfile();
if (p !== undefined) console.log("default profile:", p.name);

isNullFlavor()​

isNullFlavor(value): value is "NI" | "INV" | "DER" | "OTH" | "NINF" | "PINF" | "UNC" | "MSK" | "NA" | "UNK" | "ASKU" | "NAV" | "NASK" | "NAVU" | "QS" | "TRC" | "NP"

Return true when a string is a conforming NullFlavor token.

Parameters​

value​

string

Returns​

value is "NI" | "INV" | "DER" | "OTH" | "NINF" | "PINF" | "UNC" | "MSK" | "NA" | "UNK" | "ASKU" | "NAV" | "NASK" | "NAVU" | "QS" | "TRC" | "NP"

Example​

import { isNullFlavor } from "@cosyte/ccda";
isNullFlavor("UNK"); // true
isNullFlavor("nope"); // false

isRecognizedNamespace()​

isRecognizedNamespace(namespaceUri): boolean

Return true when a namespace URI is one the parser recognizes (urn:hl7-org:v3, the XSI namespace, or urn:hl7-org:sdtc). A null URI, an element with no namespace at all, counts as unrecognized.

Parameters​

namespaceUri​

string | null

Returns​

boolean

Example​

import { isRecognizedNamespace, V3_NS } from "@cosyte/ccda";
isRecognizedNamespace(V3_NS); // true
isRecognizedNamespace("urn:vendor"); // false
isRecognizedNamespace(null); // false

isSafetyCriticalCode()​

isSafetyCriticalCode(code): boolean

True when code is safety-critical and therefore forbidden in a profile's tolerate set.

Parameters​

code​

WarningCode

Returns​

boolean

Example​

import { isSafetyCriticalCode } from "@cosyte/ccda";
console.log(isSafetyCriticalCode("DEPRECATED_LOINC")); // false
console.log(isSafetyCriticalCode("CODE_NARRATIVE_MISMATCH")); // true

isSyntheticSetId()​

isSyntheticSetId(setId): boolean

Whether a setId was minted by editCcda rather than carried by the source document or supplied by the caller. True only when the identifier matches the whole documented scheme: the synthetic assigning-authority root and an @extension beginning SYNTHETIC_SETID_PREFIX. Both, because either alone is something a real document could carry by coincidence.

A false is not a promise that the identifier is real. It says only that this library did not mint it under this scheme: a setId minted by some other tool, or by a version of this library before the scheme existed (setid-e1, unprefixed), reads false here. Use it to recognise a synthetic id, never to certify a real one.

Parameters​

setId​

II | undefined

The setId to test, e.g. doc.header.setId. undefined is false (a document with no setId has nothing to recognise).

Returns​

boolean

true when the identifier matches the minted scheme.

Example​

import { parseCcda, isSyntheticSetId } from "@cosyte/ccda";
const doc = parseCcda(xml);
if (isSyntheticSetId(doc.header.setId)) {
// the version series was invented by an editor, not asserted by a source system
}

isUcumCaseSuspect()​

isUcumCaseSuspect(unit): boolean

Detect the case-confusion trap: a unit that is not a canonical clinical spelling but whose case-folded form is one, Mg/MG for mg, ML for mL, mEq for meq. These are reported as UCUM_CASE_SUSPECT (more actionable than NON_UCUM_UNIT) because the likely fix is a single letter-case change. A unit already spelled canonically returns false.

Parameters​

unit​

string

Returns​

boolean

Example​

import { isUcumCaseSuspect } from "@cosyte/ccda";
isUcumCaseSuspect("ML"); // true (meant mL; ML is megaliter)
isUcumCaseSuspect("mEq"); // true (meant meq)
isUcumCaseSuspect("mg"); // false (already canonical)

isValidUcumUnit()​

isValidUcumUnit(unit): boolean

Validate a string as a well-formed UCUM unit (case-sensitive). Returns true only when the entire string parses, mg/dL, mm[Hg], 10*3/uL, Cel, %, /min, kg/m2, 1 are valid; mcg, cc, mg//dL and partial garbage are not. This is a grammatical check: a case slip like Mg/dL is well-formed UCUM (megagram/deciliter) so it validates here, isUcumCaseSuspect catches the clinical case-confusion separately. Never throws.

Parameters​

unit​

string

Returns​

boolean

Example​

import { isValidUcumUnit } from "@cosyte/ccda";
isValidUcumUnit("mg/dL"); // true
isValidUcumUnit("mm[Hg]"); // true
isValidUcumUnit("cc"); // false

listCcdaProfiles()​

listCcdaProfiles(): readonly string[]

The names of every built-in profile, in registration order.

Returns​

readonly string[]

Example​

import { listCcdaProfiles } from "@cosyte/ccda";
console.log(listCcdaProfiles()); // ["default", "smartScorecard", "legacyR11"]

looksProductLevel()​

looksProductLevel(displayName): boolean

Heuristic: does an RxNorm displayName look like a product/branded concept (carries a dose form or strength) rather than a bare ingredient? Used only to flag ALLERGEN_GRANULARITY_SUSPECT, a best-effort signal, never a hard rule. Returns false when there is no display text to inspect.

Parameters​

displayName​

string | undefined

Returns​

boolean

Example​

import { looksProductLevel } from "@cosyte/ccda";
looksProductLevel("amoxicillin 500 MG Oral Tablet"); // true
looksProductLevel("amoxicillin"); // false

missingRequiredSections()​

missingRequiredSections(documentType, presentKeys, options?): readonly string[]

The SHALL section keys a DocumentType requires that are absent from presentKeys, preserving the type's declared order. The parser passes the set of recognized section keys it framed; each returned key becomes one REQUIRED_SECTION_MISSING warning. Returns an empty array when every required section is present (or the type asserts none).

Parameters​

documentType​

DocumentType

presentKeys​

ReadonlySet<string>

options?​

RequiredSectionOptions

Returns​

readonly string[]

Example​

import { missingRequiredSections } from "@cosyte/ccda";
missingRequiredSections("ccd", new Set(["allergies", "problems"]));
// ["medications", "results", "socialHistory", "vitalSigns"]

// The same document without the R2.1 stamp:
missingRequiredSections("ccd", new Set(["allergies", "problems"]), { r21Stamped: false });
// ["medications", "results"]

parseBl()​

parseBl(el, ctx): BL | undefined

Parse a BL element (one carrying a @value) into a typed BL. Returns undefined when the element is absent. Never throws.

A @nullFlavor declared beside a @value emits CONTRADICTORY_NULL_FLAVOR. The parsed boolean is kept: BL retains no verbatim copy of its token, so withholding value would delete the assertion rather than decline to embellish it (see parsePq).

Parameters​

el​

any

ctx​

ParseCtx

Returns​

BL | undefined

Example​

import { parseBl } from "@cosyte/ccda";
const bl = parseBl(el, { emit: () => {} });
console.log(bl?.value);

parseBlAttr()​

parseBlAttr(el, name): boolean | undefined

Read a named BL-valued attribute (e.g. negationInd) off an element, returning the parsed boolean or undefined when absent or non-boolean. This is the distinct path for attributes like @negationInd that are booleans on an element rather than a child BL element.

Parameters​

el​

Element

name​

string

Returns​

boolean | undefined

Example​

import { parseBlAttr } from "@cosyte/ccda";
const negated = parseBlAttr(observationEl, "negationInd"); // boolean | undefined

parseCcda()​

parseCcda(raw, options?): CcdaDocument

Parse a C-CDA XML payload into an immutable CcdaDocument.

Lenient by default, real-world, vendor-quirky documents parse rather than throw, accruing CcdaWarnings on doc.warnings. Only unrecoverable structural problems throw a CcdaParseError (a Tier-3 FatalCode): a declared DTD/external entity, a size/entity/depth limit breach, malformed XML, or a root that is not ClinicalDocument. With { strict: true }, every Tier-2 deviation is escalated to a thrown CcdaParseError instead of a warning.

Parameters​

raw​

string

The raw C-CDA XML document text.

options?​

ParseCcdaOptions = {}

Parse options; see ParseCcdaOptions. Lenient unless strict is set.

Returns​

CcdaDocument

The parsed document plus any recovered Tier-2 warnings.

Throws​

CcdaParseError on any Tier-3 fatal, or, when options.strict is true, on the first Tier-2 deviation.

Example​

import { parseCcda } from "@cosyte/ccda";
const doc = parseCcda(xml);
console.log(doc.documentType, doc.getPatient()?.name?.text);
for (const w of doc.warnings) console.warn(w.code, w.position);

parseCd()​

parseCd(el, ctx): CD | undefined

Parse a CD/CE element into a typed CD. Returns undefined when the element is absent. Resolves a child <originalText> to its trimmed text and parses each <translation> recursively (translations of a translation are ignored, C-CDA does not nest them). Never throws.

A @nullFlavor declared beside a populated @code emits CONTRADICTORY_NULL_FLAVOR: the element says both "this concept is unknown" and "this concept is X". Only @code counts as the contradicting assertion. A nullFlavor beside originalText, a <translation>, a displayName or a bare @codeSystem is the documented C-CDA idiom for "not codable in the bound value set, here is the source text or an alternate coding", which is coherent rather than contradictory and stays silent.

Unlike PQ/TS, the code is kept: it is the document's own text rather than a reading this parser manufactured, and there is no verbatim copy to fall back on, so withholding it would delete what the document said. See parsePq for the full argument.

Parameters​

el​

any

ctx​

ParseCtx

Returns​

CD | undefined

Example​

import { parseCd } from "@cosyte/ccda";
const code = parseCd(codeEl, { emit: () => {} });
console.log(code?.code, code?.displayName);

parseEd()​

parseEd(el, ctx): ED | undefined

Parse an ED element into a typed ED. Returns undefined when the element is absent. Captures inline content verbatim (base64 is not decoded) and resolves a child <reference>'s @value. Never throws.

A @nullFlavor declared beside inline content or a <reference> emits CONTRADICTORY_NULL_FLAVOR; a @mediaType or @representation alone describes a null value rather than contradicting it and stays silent. Content and reference are kept verbatim (see parsePq).

Parameters​

el​

any

ctx​

ParseCtx

Returns​

ED | undefined

Example​

import { parseEd } from "@cosyte/ccda";
const ed = parseEd(el, { emit: () => {} });
console.log(ed?.reference ?? ed?.value);

parseIi()​

parseIi(el, ctx): II | undefined

Parse an II element into a typed II. Returns undefined when the element itself is absent. Never throws; omits any field the element does not carry.

A @nullFlavor declared beside an @extension emits CONTRADICTORY_NULL_FLAVOR: the element says both "this identifier is unknown" and "this identifier is 12345". Only @extension counts as the contradicted assertion; a @root alone is a namespace without a local identifier, so no identifier value is produced and the shape stays silent.

The @extension itself is kept. It is the document's own text, with no second copy the way PQ.raw sits beside PQ.value, so withholding it here would delete what the document said rather than decline to embellish it (see parsePq for the rule and its limit). Nor is there a derived reading to withhold: at this layer extension is the datum, not something the parser manufactured from it.

Where the withholding happens instead. The dangerous act is not reporting an II whole, with its nullFlavor attached, it is selecting one and handing back a naked string that no longer carries the marking. This model does that in exactly one place, pickMrn (behind getMrn()), and that is where a null-marked identifier is declined. The identity slots, ClinicalDocument.id, setId, relatedDocument/parentDocument/id and every entry-level <id>, are only ever reported as the whole datatype beside the warning, so the nullFlavor never goes missing and there is nothing to withhold. The emit side is guarded separately: editCcda refuses to build an RPLC parentDocument out of a null-marked source <id>, because copying root/extension forward would launder a disowned identifier into an asserted one.

templateId is the stated exception, and it is deliberate. Document- and section-type recognition does derive a reading from templateId.@root, so <templateId root="…22.1.2" nullFlavor="NA"/> still resolves the document type and its required-section SHALL set. That is left alone on purpose: a templateId is a conformance assertion about the document's shape, not an identifier for a person or a record, so a mis-read costs a spurious or missing REQUIRED_SECTION_MISSING rather than a misattributed clinical fact. Declining to recognize would also make the parser less informative, not safer, replacing a working document type with UNKNOWN_DOCUMENT_TEMPLATE. Note too that the shape stays silent here by the rule above: @root is not the contradicted assertion, only @extension is.

Parameters​

el​

any

ctx​

ParseCtx

Returns​

II | undefined

Example​

import { parseIi } from "@cosyte/ccda";
const id = parseIi(idEl, { emit: () => {} });
console.log(id?.root);

parseIvlPq()​

parseIvlPq(el, ctx): IVL_PQ | undefined

Parse an IVL_PQ element into a typed IVL_PQ. Returns undefined when the element is absent. Never throws; omits any bound the element lacks.

A @nullFlavor on the interval itself beside bounds that carry values is the same contradiction parsePq resolves one level down, and gets the same treatment: CONTRADICTORY_NULL_FLAVOR is emitted once for the interval, every bound is preserved verbatim, and the derived value number is withheld from each of them. Without this a dose range declared unknown would still hand doseRange.low.value back to a caller, which is the scalar-dose harm by another route.

Parameters​

el​

any

ctx​

ParseCtx

Returns​

IVL_PQ | undefined

Example​

import { parseIvlPq } from "@cosyte/ccda";
const range = parseIvlPq(el, { emit: () => {} });
console.log(range?.low?.value, range?.high?.value);

parseIvlTs()​

parseIvlTs(el, ctx): IVL_TS | undefined

Parse an IVL_TS element into a typed IVL_TS. Returns undefined when the element is absent. Handles both the <low>/<high> bound form and the degenerate @value point form. Never throws.

A @nullFlavor on the interval beside its own @value or a bound that carries one is a contradiction: CONTRADICTORY_NULL_FLAVOR is emitted once, every raw is preserved, and the derived date is withheld from the point value and from each bound. See parsePq for the rule and its limits.

Parameters​

el​

any

ctx​

ParseCtx

Returns​

IVL_TS | undefined

Example​

import { parseIvlTs } from "@cosyte/ccda";
const period = parseIvlTs(effectiveTimeEl, { emit: () => {} });
console.log(period?.low?.date?.toISOString());

parsePq()​

parsePq(el, ctx): PQ | undefined

Parse a PQ element into a typed PQ. Returns undefined when the element is absent. A non-numeric @value is preserved in raw with value omitted. Never throws.

A @nullFlavor beside a populated @value is a contradiction, and the parser resolves it against the number. <doseQuantity nullFlavor="UNK" value="10" unit="mg"/> asserts both "this quantity is unknown" and "this quantity is 10 mg". The parser emits CONTRADICTORY_NULL_FLAVOR, preserves raw ("10"), unit ("mg") and nullFlavor ("UNK") verbatim, and omits value, so med.dose.value is undefined rather than 10.

The reasoning, because the choice is not obvious and a warning alone was the alternative. A warning alone keeps the house rule (never coerce, surface verbatim, flag) but leaves the dangerous affordance intact: dose.value still hands back 10 to the many consumers who do not read warnings on a first integration, and of the two readings the reassuring one is the one that can hurt a patient. Withholding costs nothing, because value is not the document's bytes, it is a number this parser manufactured by interpreting raw, and raw is still right there. So nothing the document said is lost, and the type now forces a caller to look at what it said.

That is also exactly what MALFORMED_DATETIME already does one datatype over, TS keeps raw and drops the parsed date, so this is the existing rule applied to a second reason for not trusting an interpretation, not a new one.

The limit, stated rather than implied. Withholding applies only where a verbatim copy survives beside the derived reading, which in this model is PQ.value and TS.date and nothing else. On CD, II, ST, ED and BL the value-bearing field is the document's own text (@code, @extension, the element's content), with no second copy, so withholding it would delete what the document said rather than decline to embellish it. Those datatypes therefore warn and keep the field: a naive consumer reading allergy.allergen.code still gets the code, with nullFlavor on the same object and CONTRADICTORY_NULL_FLAVOR in warnings.

One consequence worth naming: a contradictory PQ no longer reaches MISSING_UNIT_ON_PQ (which keys off a defined value). That is not a new silence, the stronger CONTRADICTORY_NULL_FLAVOR fires in its place, and a missing unit on a value the document declared null is moot.

Parameters​

el​

any

ctx​

ParseCtx

Returns​

PQ | undefined

Example​

import { parsePq } from "@cosyte/ccda";
const pq = parsePq(el, { emit: () => {} });
console.log(pq?.value, pq?.unit);

parseSecureXml()​

parseSecureXml(raw, limits, emit, reportForeignNamespace?): Document

Strip a leading UTF-8 BOM and run the pre-parse safety gauntlet (size, DTD/DOCTYPE, entity-reference cap), then build a DOM with a hardened @xmldom/xmldom DOMParser, then enforce the depth / node-count caps on the constructed tree. Returns the root Document. Emits ENCODING_BOM_STRIPPED via emit when a BOM was removed.

Throws a CcdaParseError carrying a PHI-free CcdaPosition for any safety violation or malformed XML, never returns a partially-built document.

UNKNOWN_NAMESPACE_PREFIX goes to reportForeignNamespace rather than to emit, and that separation is load-bearing rather than tidy. This function runs before parseCcda's root gate and before any clinical parsing, and in strict mode the emitter escalates the first warning it is handed. Routing a whole-document observation through emit here would therefore let it preempt NOT_A_CLINICAL_DOCUMENT on a document that is not a C-CDA at all, and preempt a safety-critical per-element code such as MISSING_CODE_SYSTEM on one that is. parseCcda passes a collector and replays it after the model is built, so those keep their precedence. The parameter defaults to emit for a caller using this function on its own, where there is no later stage to defer to.

Parameters​

raw​

string

limits​

ResolvedLimits

emit​

(warning) => void

reportForeignNamespace?​

(warning) => void

Returns​

Document

Example​

import { parseSecureXml, resolveLimits } from "@cosyte/ccda";
const doc = parseSecureXml("<ClinicalDocument/>", resolveLimits(), () => {});
console.log(doc.documentElement?.localName); // "ClinicalDocument"

parseSt()​

parseSt(el, ctx): ST | undefined

Parse an ST element into a typed ST. Returns undefined when the element is absent. Never throws.

A @nullFlavor declared beside non-empty text emits CONTRADICTORY_NULL_FLAVOR. The text is kept: it is the document's own content with no verbatim copy elsewhere, so withholding it would delete what the document said (see parsePq).

Parameters​

el​

any

ctx​

ParseCtx

Returns​

ST | undefined

Example​

import { parseSt } from "@cosyte/ccda";
const title = parseSt(titleEl, { emit: () => {} });
console.log(title?.value);

parseTs()​

parseTs(el, ctx): TS | undefined

Parse a TS element into a typed TS. Returns undefined when the element is absent. Emits MALFORMED_DATETIME (and omits date) when a non-empty @value does not parse. Never throws.

A @nullFlavor declared beside a populated @value is a contradiction: CONTRADICTORY_NULL_FLAVOR is emitted, raw and nullFlavor are preserved verbatim, and the derived date is withheld. That is the same treatment MALFORMED_DATETIME already gives an unparseable value, and the same rule parsePq applies to value: the parser declines to manufacture a computable reading it has been told is not the document's value, while never dropping the document's own bytes.

Parameters​

el​

any

ctx​

ParseCtx

Returns​

TS | undefined

Example​

import { parseTs } from "@cosyte/ccda";
const ts = parseTs(effectiveTimeEl, { emit: () => {} });
console.log(ts?.date?.toISOString());

parseV3DateTime()​

parseV3DateTime(value): Date | undefined

Parse a variable-precision HL7 v3 timestamp string to a JS Date. Accepts year through second precision plus optional fractional seconds and an optional ±HHMM (or ±HH) timezone offset. Per the CDA R2 / HL7 v3 TS literal YYYYMMDDHHMMSS.UUUU[±ZZzz], a fraction or offset is accepted only on a value that carries the time-of-day (at least the hour): a fraction or offset hung on a bare YYYY/YYYYMM/YYYYMMDD value, e.g. the dropped-dash "2026-0721", is rejected rather than silently misread. A value with no offset resolves to UTC for determinism; truncated values resolve to the first instant of the stated precision (e.g. 2026 → 2026-01-01T00:00:00Z). Returns undefined when the value does not match the shape or is calendar-invalid, never throws.

Parameters​

value​

string

Returns​

Date | undefined

Example​

import { parseV3DateTime } from "@cosyte/ccda";
parseV3DateTime("20260628")?.toISOString(); // "2026-06-28T00:00:00.000Z"
parseV3DateTime("20260628153045-0500")?.toISOString();
parseV3DateTime("not-a-date"); // undefined

pickMrn()​

pickMrn(identifiers): string | undefined

Pick the MRN string from a list of patientRole/id II identifiers.

Returns the first identifier's extension, or undefined when the list is empty, when that identifier has no extension (a root-only id names an assigning authority, not a patient), or when it carries a nullFlavor.

Why a nullFlavor-marked <id> is withheld rather than read. In HL7 v3, nullFlavor is a property of ANY: it marks an exceptional value, one with no proper value. An <id nullFlavor="UNK" extension="X"/> therefore says both "this identifier is unknown" and "this identifier is X", and parseIi already flags that contradiction as CONTRADICTORY_NULL_FLAVOR (safety-critical). Reading X out of it anyway is how a record gets filed against the wrong patient, which is silent, persistent, and contaminates everything downstream, so it sits alongside a wrong dose and a wrong code system in this package's harm ordering.

And why it is not skipped past, either. Falling through to the next <id> looks like the helpful move and is a worse one. CDA R2 makes patientRole/id 1..* and neither it nor C-CDA R2.1 says which entry is the MRN, so nothing in the document ranks them: the second id is not "another MRN", it is whatever the sending system listed second, commonly a plan member number, an account number, or the SSN under 2.16.840.1.113883.4.1. Substituting it would answer the MRN question confidently from a different assigning authority, with no signal naming the substitution, which trades one wrong-identifier failure for a quieter one. The rule this helper is applying declines a manufactured reading; it does not manufacture a replacement. Same slot, same position, reading withheld.

This is the PQ.value rule, applied one layer up rather than abandoned. parsePq withholds value on a contradicted quantity because value is a number the parser manufactured from raw, and raw survives, so nothing the document said is lost. II.extension is not like that: it is the document's own text, with no second copy, so parseIi keeps it and a caller reading patient.identifiers[0].extension still gets it with the nullFlavor sitting on the same object. What is manufactured here is the selection: picking one <id> out of a list and handing back a bare string strips away the nullFlavor that qualified it. So the derived act declines, and the verbatim data stays reachable. Both properties, rather than a trade between them.

A caller whose assigning authority genuinely carries the MRN on a later <id>, or who treats a given nullFlavor as tolerable, can walk patient.identifiers and branch on each root. That decision needs the authority OIDs, which this helper does not have and must not guess.

Provenance: no normative SHALL is cited. CDA R2 declares @nullFlavor and @extension on II independently, and neither CDA R2 nor C-CDA R2.1 states which patientRole/id is the MRN. The rule rests on v3 datatype semantics plus the harm ordering above.

Parameters​

identifiers​

readonly II[]

Returns​

string | undefined

Example​

import { pickMrn } from "@cosyte/ccda";
pickMrn([{ root: "2.16.840.1.113883.19.5", extension: "MRN001" }]);
// → "MRN001"

pickMrn([{ nullFlavor: "UNK", extension: "MRN001" }]);
// → undefined (the document disowned that identifier)

// A second id under a different authority is NOT a fallback MRN:
pickMrn([{ nullFlavor: "UNK", extension: "MRN001" }, { root: "2.16.840.1.113883.4.1", extension: "SYNTH-9" }]);
// → undefined (still the first id, withheld; never the next authority's number)

pickMrn([]);
// → undefined

positionOf()​

positionOf(el): CcdaPosition

Build a structural position for an element: its local name as a path hint plus the locator line/column @xmldom/xmldom recorded (when present). Never includes attribute values or text content.

path is bounded on membership, not copied. A local name is an XML NCName, so a sender can call an element anything, and enforceStructureLimits in ../parser/secure-xml.ts positions on arbitrary elements from a hostile document. Only a name in the CDA vocabulary this parser navigates is echoed; anything else becomes <withheld> (see ../parser/tokens.ts). Line and column still locate it exactly.

Parameters​

el​

Element

Returns​

CcdaPosition

Example​

import { positionOf } from "@cosyte/ccda";
const pos = positionOf(sectionEl); // { path: "section", line: 42, ... }

profileQuirkApplied()​

profileQuirkApplied(original, profileName): CcdaWarning

Build a PROFILE_QUIRK_APPLIED warning, the downgraded form an active CcdaProfile produces from a deviation it expects. The original warning is not dropped: its code moves to toleratedCode, the deviation is re-badged PROFILE_QUIRK_APPLIED, expected is set, and the tolerating profile is named, so a consumer can filter known, grounded noise while the fact of the deviation, and where it was, survive. A profile can only ever reach this path for a non-safety-critical code (enforced at profile- definition time); safety-critical warnings can never be tolerated.

The original message is not carried forward, and profileName is not interpolated. Both used to be, which made this the one factory whose output was assembled rather than looked up. What the deviation was is on toleratedCode, who tolerated it is on profile, and where it was is on position, all typed fields.

Say what that costs rather than "nothing is lost". Two things do not survive the re-badge. The tolerated code's own message is not reachable from the returned warning, because WARNING_MESSAGES is internal and is not on the package entry point. And where the original carried a per-closed-key variant, the key is not recoverable from toleratedCode alone: a tolerated UNEXPECTED_CODE_SYSTEM no longer says which CodeSlot it was about. The trade is deliberate, and narrow because a profile may only ever tolerate a non-safety-critical code, but it is a trade.

Parameters​

original​

CcdaWarning

profileName​

string

Returns​

CcdaWarning

Example​

import { profileQuirkApplied, deprecatedLoinc } from "@cosyte/ccda";
const original = deprecatedLoinc({ path: "code" });
const w = profileQuirkApplied(original, "smartScorecard");

readObservationValue()​

readObservationValue(valueEl, ctx): ObservationValue | undefined

Read a polymorphic observation <value> into an ObservationValue, branching on xsi:type. A PQ is UCUM-checked; an untyped value with a @code/@value is treated leniently as coded/quantity; an unrecognized xsi:type is preserved as unsupported and flagged with RESULT_VALUE_TYPE_UNHANDLED. Returns undefined when the element is absent.

Parameters​

valueEl​

any

ctx​

ParseCtx

Returns​

ObservationValue | undefined

Example​

import { readObservationValue } from "@cosyte/ccda";
const v = readObservationValue(child(obs, "value"), ctx);

readReferenceRange()​

readReferenceRange(obs, ctx): ReferenceRange | undefined

Read a result's reference range from a Result Observation. Prefers the structured observationRange/value xsi:type="IVL_PQ" bounds; falls back to the free-text form (emitting FREE_TEXT_REFERENCE_RANGE). Returns undefined when the observation carries no referenceRange.

Parameters​

obs​

Element

ctx​

ParseCtx

Returns​

ReferenceRange | undefined

Example​

import { readReferenceRange } from "@cosyte/ccda";
const range = readReferenceRange(resultObs, ctx);

requiredSectionKeys()​

requiredSectionKeys(documentType, options?): readonly string[]

The catalog section keys a DocumentType SHALL contain, in a stable order. Returns an empty array when no unconditional in-catalog SHALL section is asserted for that type (see the module note, empty ≠ "no requirements").

Parameters​

documentType​

DocumentType

options?​

RequiredSectionOptions

Returns​

readonly string[]

Example​

import { requiredSectionKeys } from "@cosyte/ccda";
requiredSectionKeys("ccd");
// ["allergies", "medications", "problems", "results", "socialHistory", "vitalSigns"]
requiredSectionKeys("progressNote"); // []

// An R1.1-origin CCD (no R2.1 stamp) drops the R2.1-scoped keys:
requiredSectionKeys("ccd", { r21Stamped: false });
// ["allergies", "medications", "problems", "results"]

resolveLimits()​

resolveLimits(overrides?): ResolvedLimits

Merge caller-supplied limit overrides over DEFAULT_LIMITS. Honors exactOptionalPropertyTypes, an omitted override key falls back to the default rather than producing undefined.

Parameters​

overrides?​

CcdaParseLimits

Returns​

ResolvedLimits

Example​

import { resolveLimits } from "@cosyte/ccda";
const limits = resolveLimits({ maxDepth: 200 });
console.log(limits.maxDepth); // 200

sectionForLoinc()​

sectionForLoinc(loinc): SectionInfo | undefined

Resolve a section LOINC code to its SectionInfo, or undefined when unrecognized. This is the fallback section-recognition path used when no recognized templateId is present.

Parameters​

loinc​

string

Returns​

SectionInfo | undefined

Example​

import { sectionForLoinc } from "@cosyte/ccda";
sectionForLoinc("11450-4")?.key; // "problems"

sectionForTemplateRoot()​

sectionForTemplateRoot(root): SectionInfo | undefined

Resolve a section templateId root OID to its SectionInfo, or undefined when unrecognized. This is the primary section-recognition path.

Parameters​

root​

string

Returns​

SectionInfo | undefined

Example​

import { sectionForTemplateRoot } from "@cosyte/ccda";
sectionForTemplateRoot("2.16.840.1.113883.10.20.22.2.6.1")?.key; // "allergies"

semanticCodeInvalid()​

semanticCodeInvalid(position, slot): CcdaWarning

Build a SEMANTIC_CODE_INVALID warning. Emitted only when a consumer-supplied bring-your-own TerminologyAdapter reports (via validateCode) that a coded value is not a valid, active member of its code system, the semantic validation tier structural recognition cannot reach without a licensed terminology. The code is preserved verbatim (never coerced to a "corrected" value); this surfaces the adapter's negative verdict so a structurally-valid but wrong code, the highest-severity real-world defect, is not silently trusted. The message names the CodeSlot and nothing else. It used to carry the observed @codeSystem OID as a "structural identifier"; a sender controls that attribute exactly as it controls the code beside it, so it is gone. The adapter's own message has never been interpolated and still is not: it is consumer text about a coded value.

Parameters​

position​

CcdaPosition

slot​

"problem" | "medication" | "allergen" | "route" | "vaccine"

Returns​

CcdaWarning

Example​

import { semanticCodeInvalid } from "@cosyte/ccda";
const w = semanticCodeInvalid({ path: "value" }, "problem");

serializeCcda()​

serializeCcda(doc): string

Serialize a parsed CcdaDocument back to spec-clean C-CDA XML.

The output is the faithful re-emission of the document the parser read, no silent loss of unmodeled content, with a guaranteed XML declaration. Serialization is a fixed point: parseCcda(serializeCcda(doc)) re-serializes to the identical string. Equivalent to doc.toString().

Parameters​

doc​

CcdaDocument

A document produced by parseCcda.

Returns​

string

The spec-clean XML text.

Throws​

If doc was hand-constructed (neither produced by parseCcda nor by buildCcda) and therefore retains no source document to emit. To construct a document from scratch, use buildCcda, whose result is the parse of the XML it emitted and so serializes normally.

Example​

import { parseCcda, serializeCcda } from "@cosyte/ccda";
const doc = parseCcda(xml);
const xmlOut = serializeCcda(doc); // spec-clean, declaration-prefixed

setDefaultCcdaProfile()​

setDefaultCcdaProfile(profile): void

Register a process-scoped default profile that parseCcda(raw) applies when no explicit profile option is passed. Pass null (or undefined) to clear. An explicit parseCcda(raw, { profile }) always wins; { profile: null } opts out of the default for a single call.

Test hygiene: the only mutable module-scoped state here, tests that call this MUST clear it in teardown or default-profile bleed infects later tests.

Parameters​

profile​

CcdaProfile | null

Returns​

void

Example​

import { setDefaultCcdaProfile, ccdaProfiles, parseCcda } from "@cosyte/ccda";
setDefaultCcdaProfile(ccdaProfiles.legacyR11);
const doc = parseCcda(xml); // uses legacyR11
setDefaultCcdaProfile(null); // clear

text()​

text(el): string | undefined

Concatenated text content of an element with leading/trailing whitespace trimmed, or undefined when there is no non-whitespace text. Does not decode or interpret embedded base64, base64 stays quarantined as inert text.

Parameters​

el​

Element

Returns​

string | undefined

Example​

import { text } from "@cosyte/ccda";
text(titleEl); // "Allergies" | undefined

wrapEmitterWithProfile()​

wrapEmitterWithProfile(next, profile): (warning) => void

Wrap a downstream warning sink so every warning first passes through profile's tolerance transform. Returned unchanged (next) when profile is undefined, so the no-profile path pays nothing.

Parameters​

next​

(warning) => void

profile​

CcdaProfile | undefined

Returns​

(warning) => void

Example​

import { wrapEmitterWithProfile } from "@cosyte/ccda";
const emit = wrapEmitterWithProfile(baseEmit, activeProfile);

xsiType()​

xsiType(el): string | undefined

Read the xsi:type attribute (namespace-qualified) that selects a concrete HL7 v3 datatype for a polymorphic element. Returns undefined when absent. A leading namespace prefix (e.g. hl7:PQ) is stripped to the local type name.

Parameters​

el​

Element

Returns​

string | undefined

Example​

import { xsiType } from "@cosyte/ccda";
xsiType(valueEl); // "PQ" | "CD" | ... | undefined