@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
Returns
Properties
allergies
readonlyallergies: readonlyAllergyConcern[]
Extracted Allergy Concern Acts (across all sections). Empty when none.
documentType
readonlydocumentType:DocumentType|undefined
The recognized document type, or undefined when the root templateId is unrecognized/absent.
encounters
readonlyencounters: readonlyEncounter[]
Extracted Encounter Activities, visits/admissions (across all sections). Empty when none.
familyHistory
readonlyfamilyHistory: readonlyFamilyHistory[]
Extracted Family History Organizers, one per relative (across all sections). Empty when none.
functionalStatus
readonlyfunctionalStatus: readonlyStatusObservation[]
Extracted Functional Status findings (across all sections). Empty when none.
header
readonlyheader:CcdaHeader
The parsed US Realm Header.
immunizations
readonlyimmunizations: readonlyImmunization[]
Extracted Immunization Activities (across all sections). Empty when none.
medications
readonlymedications: readonlyMedication[]
Extracted Medication Activities (across all sections). Empty when none.
mentalStatus
readonlymentalStatus: readonlyStatusObservation[]
Extracted Mental Status findings (across all sections). Empty when none.
nonXmlBody
readonlynonXmlBody:ED|undefined
The quarantined nonXMLBody content for an unstructured document (base64 never decoded).
pastMedicalHistory
readonlypastMedicalHistory: readonlyProblem[]
Extracted Past Medical History problems, bare historical Problem Observations. Empty when none.
plannedItems
readonlyplannedItems: readonlyPlannedItem[]
Extracted planned items from the Plan of Treatment, all future/ordered (across all sections). Empty when none.
problems
readonlyproblems: readonlyProblemConcern[]
Extracted Problem Concern Acts (across all sections). Empty when none.
procedures
readonlyprocedures: readonlyProcedure[]
Extracted procedures, performed or planned (across all sections). Empty when none.
profile
readonlyprofile:ProfileAttribution|undefined
The profile applied at parse time (name + lineage), or undefined when none was active.
results
readonlyresults: readonlyResultOrganizer[]
Extracted Result Organizers, lab/diagnostic panels (across all sections). Empty when none.
sections
readonlysections: readonlyCcdaSection[]
Top-level framed sections from the structuredBody. Empty for an unstructured document.
smokingStatus
readonlysmokingStatus: readonlySmokingStatus[]
Extracted Smoking Status observations from Social History. Empty when none.
templateIds
readonlytemplateIds: readonlyII[]
The root templateIds, in document order (raw recognition signal).
vitals
readonlyvitals: readonlyVitalSignsOrganizer[]
Extracted Vital Signs Organizers, vital-reading clusters (across all sections). Empty when none.
warnings
readonlywarnings: readonlyCcdaWarning[]
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
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
The stable failure code.
message
string
A human-readable, PHI-free explanation.
Returns
Overrides
Error.constructor
Properties
code
readonlycode: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
message
string
position
Returns
Overrides
Error.constructor
Properties
code
readonlycode:FatalCode
position
readonlyposition: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
Overrides
Error.constructor
Properties
profileName
readonlyprofileName: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?
readonlyoptionalallergen?:CD
allergenLevelSuspect?
readonlyoptionalallergenLevelSuspect?:boolean
criticality?
readonlyoptionalcriticality?:CD
ids
readonlyids: readonlyII[]
narrative?
readonlyoptionalnarrative?:string
negated?
readonlyoptionalnegated?:boolean
noKnownAllergy
readonlynoKnownAllergy:boolean
nullFlavor?
readonlyoptionalnullFlavor?:string
reactions
readonlyreactions: readonlyAllergyReaction[]
type?
readonlyoptionaltype?: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
readonlyallergies: readonlyAllergy[]
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
status
readonlystatus: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?
readonlyoptionalmanifestation?:CD
severity?
readonlyoptionalseverity?: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?
readonlyoptionalnullFlavor?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionalallergen?:BuildCode
The offending substance (RxNorm ingredient default, or UNII / SNOMED CT).
criticality?
readonlyoptionalcriticality?:BuildCode
The propensity criticality (HL7 ObservationValue by default), optional.
noKnownAllergy?
readonlyoptionalnoKnownAllergy?:boolean
Assert "No Known Allergies" (negationInd="true"), mutually exclusive with allergen.
onset?
readonlyoptionalonset?: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?
readonlyoptionalreaction?:BuildCode
The reaction manifestation (SNOMED CT by default), optional.
resolution?
readonlyoptionalresolution?: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?
readonlyoptionalseverity?:BuildCode
The reaction's severity (SNOMED CT by default), optional.
status?
readonlyoptionalstatus?:"active"|"resolved"|"inactive"
Active / resolved / inactive; defaults to "active".
type?
readonlyoptionaltype?: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?
readonlyoptionalperiod?: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?
readonlyoptionalhigh?:string
low?
readonlyoptionallow?:string
status?
readonlyoptionalstatus?:string
The encounter statusCode; defaults to "completed".
type
readonlytype: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
readonlyobservations: readonlyBuildCcdaFamilyHistoryObservation[]
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
readonlyrelative: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?
readonlyoptionalageAtOnset?:number
The relative's age at onset in whole years, a nested Age Observation, emitted only when supplied.
causeOfDeath?
readonlyoptionalcauseOfDeath?:boolean
When true, marks this condition as the relative's cause of death (Family History Death Observation).
condition?
readonlyoptionalcondition?:BuildCode
The coded condition the relative had (SNOMED CT default). Omit for an explicit
unknown (value nullFlavor="UNK"), never guessed.
effectiveTime?
readonlyoptionaleffectiveTime?: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?
readonlyoptionalbirthTime?:string
The relative's birth date (HL7 date string); emitted only when supplied.
deceased?
readonlyoptionaldeceased?:boolean
Whether the relative is deceased (sdtc:deceasedInd); emitted only when supplied.
gender?
readonlyoptionalgender?:string
The relative's HL7 AdministrativeGender code (e.g. "M"/"F"); emitted only when supplied.
relationship?
readonlyoptionalrelationship?: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?
readonlyoptionaleffectiveTime?:string
The date the status was assessed (HL7 date string); nullFlavor="UNK" when omitted.
value?
readonlyoptionalvalue?: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?
readonlyoptionalcode?: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?
readonlyoptionaleffectiveTime?:string
When the grouped assessment was performed (HL7 date string); omitted (not fabricated) when absent.
findings
readonlyfindings: readonlyBuildCcdaFunctionalStatus[]
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?
readonlyoptionaldose?:BuildQuantity
The amount administered (doseQuantity), optional, never defaulted.
effectiveTime?
readonlyoptionaleffectiveTime?:string
The administration date as an HL7 date string; nullFlavor="UNK" when omitted.
refused?
readonlyoptionalrefused?:boolean
Emit a refused / not-administered record (negationInd="true"); parser flags IMMUNIZATION_REFUSED.
route?
readonlyoptionalroute?:BuildCode
The administration route (routeCode); NCI Thesaurus by default.
status?
readonlyoptionalstatus?:string
The statusCode; defaults to "completed".
vaccine
readonlyvaccine:BuildCode
The CVX-coded vaccine product (CVX by default).
BuildCcdaInit
Input to buildCcda. patient is required; each clinical collection
(problems, allergies, medications, results, vitalSigns) 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?
readonlyoptionalallergies?: readonlyBuildCcdaAllergy[]
Allergy Concerns for the Allergies section; empty section when omitted.
assessment?
readonlyoptionalassessment?: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?
readonlyoptionalconfidentiality?:string
The confidentiality code; defaults to "N" (normal).
custodianName?
readonlyoptionalcustodianName?:string
The custodian organization name; defaults to a synthetic label.
documentId?
readonlyoptionaldocumentId?:string
The document id's extension; a synthetic id is generated when omitted.
documentType?
readonlyoptionaldocumentType?:"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?
readonlyoptionaleffectiveTime?:string|Date
The document effectiveTime (a Date is formatted to UTC); defaults to now.
encounters?
readonlyoptionalencounters?: readonlyBuildCcdaEncounter[]
Encounter Activities; the Encounters section is emitted only when non-empty (a CCD SHOULD section).
familyHistory?
readonlyoptionalfamilyHistory?: readonlyBuildCcdaFamilyHistory[]
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?
readonlyoptionalfunctionalStatus?: readonlyBuildCcdaFunctionalStatus[]
Standalone Functional Status findings; the Functional Status section is emitted when this or functionalStatusOrganizers is non-empty (a CCD SHOULD section).
functionalStatusOrganizers?
readonlyoptionalfunctionalStatusOrganizers?: readonlyBuildCcdaFunctionalStatusOrganizer[]
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?
readonlyoptionalfunctionalStatusScales?: readonlyBuildCcdaAssessmentScale[]
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?
readonlyoptionalimmunizations?: readonlyBuildCcdaImmunization[]
Immunization Activities; the Immunizations section is emitted only when non-empty.
languageCode?
readonlyoptionallanguageCode?:string
The document language; defaults to "en-US".
medications?
readonlyoptionalmedications?: readonlyBuildCcdaMedication[]
Medication Activities for the Medications section; empty section when omitted.
mentalStatus?
readonlyoptionalmentalStatus?: readonlyBuildCcdaMentalStatus[]
Standalone Mental Status findings; the Mental Status section is emitted when this or mentalStatusOrganizers is non-empty (a CCD SHOULD section).
mentalStatusOrganizers?
readonlyoptionalmentalStatusOrganizers?: readonlyBuildCcdaMentalStatusOrganizer[]
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?
readonlyoptionalmentalStatusScales?: readonlyBuildCcdaAssessmentScale[]
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?
readonlyoptionalpastMedicalHistory?: readonlyBuildCcdaProblem[]
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
readonlypatient:BuildCcdaPatient
The single record-target patient (required).
planOfTreatment?
readonlyoptionalplanOfTreatment?: readonlyBuildCcdaPlannedItem[]
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?
readonlyoptionalproblems?: readonlyBuildCcdaProblem[]
Problem Concerns for the Problems section; empty section when omitted.
procedures?
readonlyoptionalprocedures?: readonlyBuildCcdaProcedure[]
Procedures; the Procedures section is emitted only when non-empty (a CCD SHOULD section).
reasonForReferral?
readonlyoptionalreasonForReferral?: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?
readonlyoptionalresults?: readonlyBuildCcdaResultPanel[]
Result panels for the Results section; empty section when omitted.
smokingStatus?
readonlyoptionalsmokingStatus?: readonlyBuildCcdaSmokingStatus[]
Smoking Status observations for the Social History section; emitted only when non-empty (a CCD SHOULD section).
title?
readonlyoptionaltitle?:string
The document title; defaults to the CCD document-code display name.
vitalSigns?
readonlyoptionalvitalSigns?: readonlyBuildCcdaVitalsPanel[]
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?
readonlyoptionaldose?:BuildQuantity
The dose per administration (doseQuantity); absent → parser flags it.
drug
readonlydrug:BuildCode
The coded drug product (RxNorm by default, or NDC).
duration?
readonlyoptionalduration?:object
The therapy window (IVL_TS) as HL7 date strings; either bound optional.
high?
readonlyoptionalhigh?:string
low?
readonlyoptionallow?:string
frequency?
readonlyoptionalfrequency?:BuildQuantity
The periodic dosing frequency, a PIVL_TS period (e.g. { value: 8, unit: "h" }).
route?
readonlyoptionalroute?:BuildCode
The administration route (routeCode); NCI Thesaurus by default.
status?
readonlyoptionalstatus?:"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?
readonlyoptionaleffectiveTime?:string
The date the status was assessed (HL7 date string); nullFlavor="UNK" when omitted.
value?
readonlyoptionalvalue?: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?
readonlyoptionalcode?: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?
readonlyoptionaleffectiveTime?:string
When the grouped assessment was performed (HL7 date string); omitted (not fabricated) when absent.
findings
readonlyfindings: readonlyBuildCcdaMentalStatus[]
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?
readonlyoptionalterminology?: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?
readonlyoptionalbirthTime?:string
Birth time as an HL7 date/datetime string (e.g. "19800101").
family?
readonlyoptionalfamily?:string
gender?
readonlyoptionalgender?:string
Administrative gender code (M / F / UN), HL7 AdministrativeGender.
given?
readonlyoptionalgiven?: readonlystring[]
mrn?
readonlyoptionalmrn?:string
The medical record number (the patientRole/id/@extension).
mrnAssigningAuthority?
readonlyoptionalmrnAssigningAuthority?:string
The assigning-authority name for the MRN; defaults to a synthetic label.
mrnRoot?
readonlyoptionalmrnRoot?:string
The assigning-authority OID for the MRN; defaults to a synthetic root.
prefix?
readonlyoptionalprefix?: readonlystring[]
suffix?
readonlyoptionalsuffix?: readonlystring[]
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
readonlycode:BuildCode
The planned act/observation/drug code; default code system varies by kind.
Inherited from
BuildCcdaPlannedItemBase.code
effectiveTime?
readonlyoptionaleffectiveTime?: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.
That gap is known and deliberately still open: closing it means making
the field required on a published input type, which is a breaking change and
a decision of its own rather than a patch.
Inherited from
BuildCcdaPlannedItemBase.effectiveTime
kind
readonlykind:"procedure"|"act"|"encounter"
mood?
readonlyoptionalmood?: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 gap stands.
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
readonlycode:BuildCode
The planned act/observation/drug code; default code system varies by kind.
Inherited from
BuildCcdaPlannedItemBase.code
effectiveTime
readonlyeffectiveTime:string
When the immunization should occur. Required: the template makes it [1..1].
Overrides
BuildCcdaPlannedItemBase.effectiveTime
kind
readonlykind:"immunizationActivity"
mood?
readonlyoptionalmood?: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
readonlycode:BuildCode
The planned act/observation/drug code; default code system varies by kind.
Inherited from
BuildCcdaPlannedItemBase.code
effectiveTime?
readonlyoptionaleffectiveTime?: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.
That gap is known and deliberately still open: closing it means making
the field required on a published input type, which is a breaking change and
a decision of its own rather than a patch.
Inherited from
BuildCcdaPlannedItemBase.effectiveTime
kind
readonlykind:"observation"
mood?
readonlyoptionalmood?:PlannedOrderMood
The planned @moodCode; defaults to "INT". Appointment moods not representable.
value?
readonlyoptionalvalue?: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
readonlycode:BuildCode
The planned act/observation/drug code; default code system varies by kind.
Inherited from
BuildCcdaPlannedItemBase.code
effectiveTime?
readonlyoptionaleffectiveTime?: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.
That gap is known and deliberately still open: closing it means making
the field required on a published input type, which is a breaking change and
a decision of its own rather than a patch.
Inherited from
BuildCcdaPlannedItemBase.effectiveTime
kind
readonlykind:"medicationActivity"|"supply"
mood?
readonlyoptionalmood?: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?
readonlyoptionalonset?:string
Onset date as an HL7 date string (e.g. "20210101"), the effectiveTime/low, optional.
problem
readonlyproblem:BuildCode
The coded condition (SNOMED CT default, or ICD-10-CM).
resolution?
readonlyoptionalresolution?: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?
readonlyoptionalstatus?:"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
readonlycode:BuildCode
The coded procedure (SNOMED CT by default, or CPT / ICD-10-PCS / LOINC).
disposition?
readonlyoptionaldisposition?:"performed"|"planned"
Performed (EVN) or planned (INT); defaults to "performed". Never conflated.
effectiveTime?
readonlyoptionaleffectiveTime?:string
The procedure date as an HL7 date string; emitted only when supplied (SHOULD [0..1]).
kind?
readonlyoptionalkind?:ProcedureKind
The Procedure Activity variant; defaults to "procedure" (operative).
status?
readonlyoptionalstatus?:string
The statusCode; defaults per disposition (performed → "completed",
planned → "active"). SHALL [1..1] on the template, so always emitted.
value?
readonlyoptionalvalue?: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?
readonlyoptionalcodedValue?:BuildCode
A CD value. Exactly one of quantity/codedValue/stringValue.
effectiveTime?
readonlyoptionaleffectiveTime?:string
The observation time as an HL7 date string, optional.
interpretation?
readonlyoptionalinterpretation?:BuildCode
The H/L/N interpretation (HL7 ObservationInterpretation by default), optional.
quantity?
readonlyoptionalquantity?:BuildQuantity
A PQ value (UCUM). Exactly one of quantity/codedValue/stringValue.
referenceRange?
readonlyoptionalreferenceRange?:object
The normal interval, emitted as a structured IVL_PQ; either bound optional.
high?
readonlyoptionalhigh?:BuildQuantity
low?
readonlyoptionallow?:BuildQuantity
stringValue?
readonlyoptionalstringValue?:string
A free-text (ST) value. Exactly one of quantity/codedValue/stringValue.
test
readonlytest: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
readonlycode:BuildCode
The panel/battery LOINC code.
effectiveTime?
readonlyoptionaleffectiveTime?: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
readonlyresults: readonlyBuildCcdaResult[]
The member Result Observations (at least one for a populated panel).
status?
readonlyoptionalstatus?: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?
readonlyoptionaleffectiveTime?:string
The date the status was recorded (HL7 date string); nullFlavor="UNK" when omitted.
status?
readonlyoptionalstatus?:string
The observation statusCode; defaults to "completed".
value?
readonlyoptionalvalue?: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
readonlycode:BuildCode
The LOINC vital-sign code.
effectiveTime?
readonlyoptionaleffectiveTime?:string
The reading time as an HL7 date string, optional.
interpretation?
readonlyoptionalinterpretation?:BuildCode
The H/L/N interpretation (HL7 ObservationInterpretation by default), optional.
quantity
readonlyquantity: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?
readonlyoptionaleffectiveTime?: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?
readonlyoptionalstatus?:string
The organizer statusCode; defaults to "completed".
vitals
readonlyvitals: readonlyBuildCcdaVital[]
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
readonlycode:string
The code within its system (e.g. a SNOMED CT concept id).
codeSystem?
readonlyoptionalcodeSystem?:string
The code system OID; defaults per slot when omitted.
codeSystemName?
readonlyoptionalcodeSystemName?:string
The code system's human name (e.g. "SNOMED CT"), optional.
displayName
readonlydisplayName: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
readonlyunit:string
The UCUM unit (emitted verbatim, must be valid, case-correct UCUM).
value
readonlyvalue: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
readonlyallergies: readonlyAllergyConcern[]
documentType?
readonlyoptionaldocumentType?:DocumentType
encounters
readonlyencounters: readonlyEncounter[]
familyHistory
readonlyfamilyHistory: readonlyFamilyHistory[]
functionalStatus
readonlyfunctionalStatus: readonlyStatusObservation[]
header
readonlyheader:CcdaHeader
immunizations
readonlyimmunizations: readonlyImmunization[]
medications
readonlymedications: readonlyMedication[]
mentalStatus
readonlymentalStatus: readonlyStatusObservation[]
nonXmlBody?
readonlyoptionalnonXmlBody?:ED
pastMedicalHistory
readonlypastMedicalHistory: readonlyProblem[]
plannedItems
readonlyplannedItems: readonlyPlannedItem[]
problems
readonlyproblems: readonlyProblemConcern[]
procedures
readonlyprocedures: readonlyProcedure[]
profile?
readonlyoptionalprofile?: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
readonlyresults: readonlyResultOrganizer[]
sections
readonlysections: readonlyCcdaSection[]
serialized?
readonlyoptionalserialized?: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
readonlysmokingStatus: readonlySmokingStatus[]
templateIds
readonlytemplateIds: readonlyII[]
vitals
readonlyvitals: readonlyVitalSignsOrganizer[]
warnings
readonlywarnings: readonlyCcdaWarning[]
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?
readonlyoptionalcode?:CD
confidentialityCode?
readonlyoptionalconfidentialityCode?:CD
documentId?
readonlyoptionaldocumentId?:II
effectiveTime?
readonlyoptionaleffectiveTime?:TS
languageCode?
readonlyoptionallanguageCode?:string
recordTargets
readonlyrecordTargets: readonlyCcdaPatient[]
relatedDocuments
readonlyrelatedDocuments: readonlyRelatedDocument[]
setId?
readonlyoptionalsetId?:II
title?
readonlyoptionaltitle?:string
versionNumber?
readonlyoptionalversionNumber?: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?
readonlyoptionalmaxDepth?:number
Maximum element nesting depth. Exceeding it throws ELEMENT_DEPTH_LIMIT_EXCEEDED.
maxEntityExpansions?
readonlyoptionalmaxEntityExpansions?:number
Maximum count of &...; entity references permitted in the raw input.
maxInputBytes?
readonlyoptionalmaxInputBytes?:number
Maximum decoded input size in bytes. Exceeding it throws INPUT_SIZE_LIMIT_EXCEEDED.
maxNodeCount?
readonlyoptionalmaxNodeCount?: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?
readonlyoptionalbirthTime?:TS
ethnicGroupCode?
readonlyoptionalethnicGroupCode?:CD
genderCode?
readonlyoptionalgenderCode?:CD
identifiers
readonlyidentifiers: readonlyII[]
maritalStatusCode?
readonlyoptionalmaritalStatusCode?:CD
name?
readonlyoptionalname?:HumanName
raceCode?
readonlyoptionalraceCode?: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?
readonlyoptionalcolumn?:number
line?
readonlyoptionalline?:number
path?
readonlyoptionalpath?:string
sectionCode?
readonlyoptionalsectionCode?:string
templateId?
readonlyoptionaltemplateId?: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?
readonlyoptionaldescribe?: () =>string
Multi-line human-readable summary; always present on factory-built profiles.
Returns
string
description?
readonlyoptionaldescription?:string
Optional human-readable description.
lineage
readonlylineage: readonlystring[]
Resolved lineage, [...parents, name], first-occurrence deduped.
name
readonlyname:string
The profile's unique name (registry key / attribution label).
provenance?
readonlyoptionalprovenance?:ProfileProvenance
The cited public grounding for this profile's quirks (absent for default).
tolerate
readonlytolerate: readonlyQuirkTolerance[]
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?
readonlyoptionalcode?:CD
key?
readonlyoptionalkey?:string
narrativeById
readonlynarrativeById:ReadonlyMap<string,string>
narrativeText?
readonlyoptionalnarrativeText?:string
recognizedBy?
readonlyoptionalrecognizedBy?:"templateId"|"loinc"
subsections
readonlysubsections: readonlyCcdaSection[]
templateIds
readonlytemplateIds: readonlyII[]
title?
readonlyoptionaltitle?: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
readonlycode:WarningCode
expected?
readonlyoptionalexpected?: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
readonlymessage:string
position
readonlyposition:CcdaPosition
profile?
readonlyoptionalprofile?:string
The name of the CcdaProfile that tolerated this warning, when expected.
toleratedCode?
readonlyoptionaltoleratedCode?: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?
readonlyoptionalcode?:string
codeSystem?
readonlyoptionalcodeSystem?:string
codeSystemName?
readonlyoptionalcodeSystemName?:string
displayName?
readonlyoptionaldisplayName?:string
nullFlavor?
readonlyoptionalnullFlavor?:string
originalText?
readonlyoptionaloriginalText?:string
translation?
readonlyoptionaltranslation?: readonlyCD[]
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
readonlyallergies: readonlyAllergyConcern[]
encounters
readonlyencounters: readonlyEncounter[]
familyHistory
readonlyfamilyHistory: readonlyFamilyHistory[]
functionalStatus
readonlyfunctionalStatus: readonlyStatusObservation[]
immunizations
readonlyimmunizations: readonlyImmunization[]
medications
readonlymedications: readonlyMedication[]
mentalStatus
readonlymentalStatus: readonlyStatusObservation[]
pastMedicalHistory
readonlypastMedicalHistory: readonlyProblem[]
plannedItems
readonlyplannedItems: readonlyPlannedItem[]
problems
readonlyproblems: readonlyProblemConcern[]
procedures
readonlyprocedures: readonlyProcedure[]
results
readonlyresults: readonlyResultOrganizer[]
smokingStatus
readonlysmokingStatus: readonlySmokingStatus[]
vitals
readonlyvitals: readonlyVitalSignsOrganizer[]
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
readonlymatches: readonlyTerminologyCoding[]
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?
readonlyoptionaldisplay?:string
The authoritative display the adapter knows for the code, when it has one. Advisory, never applied.
message?
readonlyoptionalmessage?:string
A human-readable reason (e.g. why a code is invalid). Advisory, never placed in a warning.
result
readonlyresult: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?
readonlyoptionaldescription?:string
extends?
readonlyoptionalextends?:CcdaProfile| readonlyCcdaProfile[]
name
readonlyname:string
provenance?
readonlyoptionalprovenance?:ProfileProvenance
tolerate?
readonlyoptionaltolerate?: readonlyQuirkTolerance[]
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?
readonlyoptionalextension?:string
root
readonlyroot: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?
readonlyoptionalmediaType?:string
nullFlavor?
readonlyoptionalnullFlavor?:string
reference?
readonlyoptionalreference?:string
representation?
readonlyoptionalrepresentation?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionalrevision?:false|RevisionInit
sections?
readonlyoptionalsections?: readonlySectionEdit[]
terminology?
readonlyoptionalterminology?: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?
readonlyoptionalcode?:CD
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
moodCode?
readonlyoptionalmoodCode?:string
narrative?
readonlyoptionalnarrative?:string
statusCode?
readonlyoptionalstatusCode?: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
readonlyids: readonlyII[]
observations
readonlyobservations: readonlyFamilyHistoryObservation[]
relative
readonlyrelative: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?
readonlyoptionalageAtOnset?:PQ
causeOfDeath?
readonlyoptionalcauseOfDeath?:boolean
condition?
readonlyoptionalcondition?:CD
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
narrative?
readonlyoptionalnarrative?:string
negated?
readonlyoptionalnegated?:boolean
nullFlavor?
readonlyoptionalnullFlavor?: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?
readonlyoptionalbirthTime?:TS
deceased?
readonlyoptionaldeceased?:boolean
gender?
readonlyoptionalgender?:CD
relationship?
readonlyoptionalrelationship?: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?
readonlyoptionalfamily?:string
given?
readonlyoptionalgiven?: readonlystring[]
prefix?
readonlyoptionalprefix?: readonlystring[]
suffix?
readonlyoptionalsuffix?: readonlystring[]
text?
readonlyoptionaltext?: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?
readonlyoptionalassigningAuthorityName?:string
extension?
readonlyoptionalextension?:string
nullFlavor?
readonlyoptionalnullFlavor?:string
root?
readonlyoptionalroot?: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?
readonlyoptionaldose?:PQ
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
moodCode?
readonlyoptionalmoodCode?:string
narrative?
readonlyoptionalnarrative?:string
nullFlavor?
readonlyoptionalnullFlavor?:string
refused?
readonlyoptionalrefused?:boolean
route?
readonlyoptionalroute?:CD
statusCode?
readonlyoptionalstatusCode?:string
vaccine?
readonlyoptionalvaccine?: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?
readonlyoptionalcenter?:PQ
high?
readonlyoptionalhigh?:PQ
low?
readonlyoptionallow?:PQ
nullFlavor?
readonlyoptionalnullFlavor?:string
width?
readonlyoptionalwidth?: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?
readonlyoptionalhigh?:TS
low?
readonlyoptionallow?:TS
nullFlavor?
readonlyoptionalnullFlavor?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionaldose?:PQ
doseRange?
readonlyoptionaldoseRange?:IVL_PQ
drug?
readonlyoptionaldrug?:CD
duration?
readonlyoptionalduration?:IVL_TS
frequency?
readonlyoptionalfrequency?:MedicationFrequency
ids
readonlyids: readonlyII[]
moodCode?
readonlyoptionalmoodCode?:string
narrative?
readonlyoptionalnarrative?:string
negated?
readonlyoptionalnegated?:boolean
nullFlavor?
readonlyoptionalnullFlavor?:string
route?
readonlyoptionalroute?:CD
statusCode?
readonlyoptionalstatusCode?: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?
readonlyoptionalinstitutionSpecified?:boolean
period?
readonlyoptionalperiod?: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?
readonlyoptionalcode?:CD
ids
readonlyids: readonlyII[]
setId?
readonlyoptionalsetId?:II
versionNumber?
readonlyoptionalversionNumber?: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?
readonlyoptionallimits?:CcdaParseLimits
Override one or more of the default safety caps applied before DOM construction.
onWarning?
readonlyoptionalonWarning?:OnWarningCallback
Inline callback fired for each Tier-2 warning, in emission order (see OnWarningCallback).
profile?
readonlyoptionalprofile?: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?
readonlyoptionalstrict?:boolean
When true, escalate every Tier-2 deviation to a thrown error instead of a warning.
terminology?
readonlyoptionalterminology?: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
readonlyemit: (warning) =>void
Parameters
warning
Returns
void
terminology?
readonlyoptionalterminology?: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?
readonlyoptionalcode?:CD
disposition?
readonlyoptionaldisposition?:EventDisposition
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
kind
readonlykind:PlannedItemKind
moodCode?
readonlyoptionalmoodCode?:string
narrative?
readonlyoptionalnarrative?:string
negated?
readonlyoptionalnegated?:boolean
nullFlavor?
readonlyoptionalnullFlavor?:string
statusCode?
readonlyoptionalstatusCode?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionalnullFlavor?:string
raw?
readonlyoptionalraw?:string
unit?
readonlyoptionalunit?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionalcode?:CD
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
narrative?
readonlyoptionalnarrative?:string
negated?
readonlyoptionalnegated?:boolean
nullFlavor?
readonlyoptionalnullFlavor?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
problems
readonlyproblems: readonlyProblem[]
status
readonlystatus: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?
readonlyoptionalcode?:CD
disposition?
readonlyoptionaldisposition?:EventDisposition
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
kind
readonlykind:ProcedureKind
moodCode?
readonlyoptionalmoodCode?:string
narrative?
readonlyoptionalnarrative?:string
negated?
readonlyoptionalnegated?:boolean
nullFlavor?
readonlyoptionalnullFlavor?:string
statusCode?
readonlyoptionalstatusCode?:string
value?
readonlyoptionalvalue?: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
readonlylineage: readonlystring[]
name
readonlyname: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?
readonlyoptionalnote?:string
Optional clarifying note about what in the source grounds the quirks.
reference
readonlyreference:string
A citation the grounding can be traced to, a URL, DOI, or repo+commit.
retrieved?
readonlyoptionalretrieved?:string
When the grounding was last verified (ISO date) or the pinned commit SHA.
source
readonlysource: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?
readonlyoptionalsectionCode?:string
Match only warnings carrying this section LOINC code in their position.
Carried by UNKNOWN_SECTION_CODE and SECTION_MATCHED_BY_LOINC_FALLBACK.
templateId?
readonlyoptionaltemplateId?: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
readonlycode:WarningCode
The existing, non-safety-critical warning code this profile expects.
match?
readonlyoptionalmatch?:QuirkMatch
Optional structural narrowing (section code / template OID).
rationale
readonlyrationale: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?
readonlyoptionalhigh?:PQ
low?
readonlyoptionallow?:PQ
text?
readonlyoptionaltext?: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
readonlyparentDocument:ParentDocument
typeCode?
readonlyoptionaltypeCode?:string
ResolvedLimits
Internal
Fully-resolved safety caps, every field present (defaults merged in).
Properties
maxDepth
readonlymaxDepth:number
maxEntityExpansions
readonlymaxEntityExpansions:number
maxInputBytes
readonlymaxInputBytes:number
maxNodeCount
readonlymaxNodeCount: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?
readonlyoptionalcode?:CD
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
interpretation?
readonlyoptionalinterpretation?:CD
narrative?
readonlyoptionalnarrative?:string
referenceRange?
readonlyoptionalreferenceRange?:ReferenceRange
value?
readonlyoptionalvalue?: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?
readonlyoptionalcode?:CD
ids
readonlyids: readonlyII[]
results
readonlyresults: readonlyResult[]
statusCode?
readonlyoptionalstatusCode?: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 one when the source has none), 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?
readonlyoptionaldocumentId?:DocumentIdInit
setId?
readonlyoptionalsetId?:DocumentIdInit
versionNumber?
readonlyoptionalversionNumber?: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
readonlykey:string
loinc
readonlyloinc:string
templateRoots
readonlytemplateRoots: readonlystring[]
title
readonlytitle: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?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
narrative?
readonlyoptionalnarrative?:string
statusCode?
readonlyoptionalstatusCode?:string
unknown
readonlyunknown:boolean
value?
readonlyoptionalvalue?: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?
readonlyoptionalnullFlavor?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionalassessmentScale?:boolean
code?
readonlyoptionalcode?:CD
domain
readonlydomain:StatusDomain
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
narrative?
readonlyoptionalnarrative?:string
negated?
readonlyoptionalnegated?:boolean
nullFlavor?
readonlyoptionalnullFlavor?:string
statusCode?
readonlyoptionalstatusCode?:string
supporting?
readonlyoptionalsupporting?: readonlySupportingObservation[]
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?
readonlyoptionalvalue?: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?
readonlyoptionalcode?:CD
ids
readonlyids: readonlyII[]
narrative?
readonlyoptionalnarrative?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionaltranslate?: (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
Returns
CodeTranslationResult | undefined
validateCode
readonlyvalidateCode: (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
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
readonlycode:string
The symbol within the code system (the C-CDA @code). Required, a coding without one is meaningless.
display?
readonlyoptionaldisplay?:string
The human-readable label (the C-CDA @displayName), when present. Carried verbatim.
system?
readonlyoptionalsystem?:string
The code system's OID, as carried by the C-CDA @codeSystem (never a URI). May be absent.
version?
readonlyoptionalversion?: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?
readonlyoptionaldate?:Date
nullFlavor?
readonlyoptionalnullFlavor?:string
raw?
readonlyoptionalraw?: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?
readonlyoptionalcode?:CD
effectiveTime?
readonlyoptionaleffectiveTime?:IVL_TS
ids
readonlyids: readonlyII[]
interpretation?
readonlyoptionalinterpretation?:CD
narrative?
readonlyoptionalnarrative?:string
value?
readonlyoptionalvalue?: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?
readonlyoptionalcode?:CD
ids
readonlyids: readonlyII[]
statusCode?
readonlyoptionalstatusCode?:string
vitals
readonlyvitals: readonlyVitalSign[]
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 typeofFATAL_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
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?
readonlyoptionalmode?: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 typeofWARNING_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
constccdaProfiles: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
readonlydefault:CcdaProfile
legacyR11
readonlylegacyR11:CcdaProfile
smartScorecard
readonlysmartScorecard:CcdaProfile
Example
import { parseCcda, ccdaProfiles } from "@cosyte/ccda";
const doc = parseCcda(raw, { profile: ccdaProfiles.smartScorecard });
console.log(doc.profile?.name); // "smartScorecard"
CDA_DOCUMENT_OID
constCDA_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
constCVX:"2.16.840.1.113883.12.292"="2.16.840.1.113883.12.292"
CVX, CDC vaccine administered code system (immunizations).
DEFAULT_LIMITS
constDEFAULT_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
constFATAL_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
readonlyELEMENT_DEPTH_LIMIT_EXCEEDED:"ELEMENT_DEPTH_LIMIT_EXCEEDED"="ELEMENT_DEPTH_LIMIT_EXCEEDED"
ENTITY_EXPANSION_LIMIT
readonlyENTITY_EXPANSION_LIMIT:"ENTITY_EXPANSION_LIMIT"="ENTITY_EXPANSION_LIMIT"
INPUT_SIZE_LIMIT_EXCEEDED
readonlyINPUT_SIZE_LIMIT_EXCEEDED:"INPUT_SIZE_LIMIT_EXCEEDED"="INPUT_SIZE_LIMIT_EXCEEDED"
NODE_COUNT_LIMIT_EXCEEDED
readonlyNODE_COUNT_LIMIT_EXCEEDED:"NODE_COUNT_LIMIT_EXCEEDED"="NODE_COUNT_LIMIT_EXCEEDED"
NOT_A_CLINICAL_DOCUMENT
readonlyNOT_A_CLINICAL_DOCUMENT:"NOT_A_CLINICAL_DOCUMENT"="NOT_A_CLINICAL_DOCUMENT"
NOT_WELL_FORMED_XML
readonlyNOT_WELL_FORMED_XML:"NOT_WELL_FORMED_XML"="NOT_WELL_FORMED_XML"
XXE_OR_DTD_PRESENT
readonlyXXE_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
constICD10_CM:"2.16.840.1.113883.6.90"="2.16.840.1.113883.6.90"
ICD-10-CM, US diagnosis coding.
ICD10_PCS
constICD10_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
constICD9_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
constICD9_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
constINTERPRETATION:"2.16.840.1.113883.5.83"="2.16.840.1.113883.5.83"
HL7 ObservationInterpretation, the interpretationCode value set source.
LOINC
constLOINC:"2.16.840.1.113883.6.1"="2.16.840.1.113883.6.1"
LOINC, observations, lab tests, section/document codes.
NCI_ROUTE
constNCI_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
constNDC:"2.16.840.1.113883.6.69"="2.16.840.1.113883.6.69"
NDC, National Drug Code (packaged products).
NULL_FLAVORS
constNULL_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
constR21_EXTENSION:"2015-08-01"="2015-08-01"
The C-CDA R2.1 version stamp carried in a recognized templateId/@extension.
RXNORM
constRXNORM:"2.16.840.1.113883.6.88"="2.16.840.1.113883.6.88"
RxNorm, clinical drugs and ingredients.
SAFETY_CRITICAL_CODES
constSAFETY_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
constSDTC_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
constSNOMED_CT:"2.16.840.1.113883.6.96"="2.16.840.1.113883.6.96"
SNOMED CT, clinical findings, problems, allergen substances.
UNII
constUNII:"2.16.840.1.113883.4.9"="2.16.840.1.113883.4.9"
UNII, FDA Unique Ingredient Identifier (substances/allergens).
V3_NS
constV3_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
constVERSION:string="0.0.11"
Library version string, synced with package.json#version at build time.
Example
import { VERSION } from "@cosyte/ccda";
console.log(VERSION);
WARNING_CODES
constWARNING_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
readonlyALLERGEN_GRANULARITY_SUSPECT:"ALLERGEN_GRANULARITY_SUSPECT"="ALLERGEN_GRANULARITY_SUSPECT"
CODE_NARRATIVE_MISMATCH
readonlyCODE_NARRATIVE_MISMATCH:"CODE_NARRATIVE_MISMATCH"="CODE_NARRATIVE_MISMATCH"
CONTRADICTORY_NULL_FLAVOR
readonlyCONTRADICTORY_NULL_FLAVOR:"CONTRADICTORY_NULL_FLAVOR"="CONTRADICTORY_NULL_FLAVOR"
DEPRECATED_CODE_SYSTEM
readonlyDEPRECATED_CODE_SYSTEM:"DEPRECATED_CODE_SYSTEM"="DEPRECATED_CODE_SYSTEM"
DEPRECATED_LOINC
readonlyDEPRECATED_LOINC:"DEPRECATED_LOINC"="DEPRECATED_LOINC"
ENCODING_BOM_STRIPPED
readonlyENCODING_BOM_STRIPPED:"ENCODING_BOM_STRIPPED"="ENCODING_BOM_STRIPPED"
FREE_TEXT_REFERENCE_RANGE
readonlyFREE_TEXT_REFERENCE_RANGE:"FREE_TEXT_REFERENCE_RANGE"="FREE_TEXT_REFERENCE_RANGE"
IMMUNIZATION_REFUSED
readonlyIMMUNIZATION_REFUSED:"IMMUNIZATION_REFUSED"="IMMUNIZATION_REFUSED"
INVALID_NULL_FLAVOR
readonlyINVALID_NULL_FLAVOR:"INVALID_NULL_FLAVOR"="INVALID_NULL_FLAVOR"
MALFORMED_DATETIME
readonlyMALFORMED_DATETIME:"MALFORMED_DATETIME"="MALFORMED_DATETIME"
MEDICATION_PRODUCT_ARM_CONFLICT
readonlyMEDICATION_PRODUCT_ARM_CONFLICT:"MEDICATION_PRODUCT_ARM_CONFLICT"="MEDICATION_PRODUCT_ARM_CONFLICT"
MEDICATION_PRODUCT_ARM_REPEATED
readonlyMEDICATION_PRODUCT_ARM_REPEATED:"MEDICATION_PRODUCT_ARM_REPEATED"="MEDICATION_PRODUCT_ARM_REPEATED"
MEDICATION_PRODUCT_ARM_UNEXPECTED
readonlyMEDICATION_PRODUCT_ARM_UNEXPECTED:"MEDICATION_PRODUCT_ARM_UNEXPECTED"="MEDICATION_PRODUCT_ARM_UNEXPECTED"
MEDICATION_PRODUCT_CODE_REPEATED
readonlyMEDICATION_PRODUCT_CODE_REPEATED:"MEDICATION_PRODUCT_CODE_REPEATED"="MEDICATION_PRODUCT_CODE_REPEATED"
MEDICATION_PRODUCT_CODE_TRANSLATION_ONLY
readonlyMEDICATION_PRODUCT_CODE_TRANSLATION_ONLY:"MEDICATION_PRODUCT_CODE_TRANSLATION_ONLY"="MEDICATION_PRODUCT_CODE_TRANSLATION_ONLY"
MISSING_ASSIGNING_AUTHORITY
readonlyMISSING_ASSIGNING_AUTHORITY:"MISSING_ASSIGNING_AUTHORITY"="MISSING_ASSIGNING_AUTHORITY"
MISSING_CODE_SYSTEM
readonlyMISSING_CODE_SYSTEM:"MISSING_CODE_SYSTEM"="MISSING_CODE_SYSTEM"
MISSING_CODE_VALUE
readonlyMISSING_CODE_VALUE:"MISSING_CODE_VALUE"="MISSING_CODE_VALUE"
MISSING_DOSE_QUANTITY
readonlyMISSING_DOSE_QUANTITY:"MISSING_DOSE_QUANTITY"="MISSING_DOSE_QUANTITY"
MISSING_PRODUCT_CODE
readonlyMISSING_PRODUCT_CODE:"MISSING_PRODUCT_CODE"="MISSING_PRODUCT_CODE"
MISSING_ROUTE_CODE
readonlyMISSING_ROUTE_CODE:"MISSING_ROUTE_CODE"="MISSING_ROUTE_CODE"
MISSING_TEMPLATE_ID
readonlyMISSING_TEMPLATE_ID:"MISSING_TEMPLATE_ID"="MISSING_TEMPLATE_ID"
MISSING_UNIT_ON_PQ
readonlyMISSING_UNIT_ON_PQ:"MISSING_UNIT_ON_PQ"="MISSING_UNIT_ON_PQ"
MULTIPLE_EFFECTIVE_TIMES_UNRESOLVED
readonlyMULTIPLE_EFFECTIVE_TIMES_UNRESOLVED:"MULTIPLE_EFFECTIVE_TIMES_UNRESOLVED"="MULTIPLE_EFFECTIVE_TIMES_UNRESOLVED"
MULTIPLE_RECORD_TARGETS
readonlyMULTIPLE_RECORD_TARGETS:"MULTIPLE_RECORD_TARGETS"="MULTIPLE_RECORD_TARGETS"
NARRATIVE_REFERENCE_BROKEN
readonlyNARRATIVE_REFERENCE_BROKEN:"NARRATIVE_REFERENCE_BROKEN"="NARRATIVE_REFERENCE_BROKEN"
NEGATION_VS_NULLFLAVOR_AMBIGUOUS
readonlyNEGATION_VS_NULLFLAVOR_AMBIGUOUS:"NEGATION_VS_NULLFLAVOR_AMBIGUOUS"="NEGATION_VS_NULLFLAVOR_AMBIGUOUS"
NON_UCUM_UNIT
readonlyNON_UCUM_UNIT:"NON_UCUM_UNIT"="NON_UCUM_UNIT"
PLANNED_VS_PERFORMED_AMBIGUOUS
readonlyPLANNED_VS_PERFORMED_AMBIGUOUS:"PLANNED_VS_PERFORMED_AMBIGUOUS"="PLANNED_VS_PERFORMED_AMBIGUOUS"
PROBLEM_STATUS_INDETERMINATE
readonlyPROBLEM_STATUS_INDETERMINATE:"PROBLEM_STATUS_INDETERMINATE"="PROBLEM_STATUS_INDETERMINATE"
PROCEDURE_MOOD_UNEXPECTED
readonlyPROCEDURE_MOOD_UNEXPECTED:"PROCEDURE_MOOD_UNEXPECTED"="PROCEDURE_MOOD_UNEXPECTED"
PROFILE_QUIRK_APPLIED
readonlyPROFILE_QUIRK_APPLIED:"PROFILE_QUIRK_APPLIED"="PROFILE_QUIRK_APPLIED"
REQUIRED_SECTION_MISSING
readonlyREQUIRED_SECTION_MISSING:"REQUIRED_SECTION_MISSING"="REQUIRED_SECTION_MISSING"
RESULT_VALUE_TYPE_UNHANDLED
readonlyRESULT_VALUE_TYPE_UNHANDLED:"RESULT_VALUE_TYPE_UNHANDLED"="RESULT_VALUE_TYPE_UNHANDLED"
SECTION_MATCHED_BY_LOINC_FALLBACK
readonlySECTION_MATCHED_BY_LOINC_FALLBACK:"SECTION_MATCHED_BY_LOINC_FALLBACK"="SECTION_MATCHED_BY_LOINC_FALLBACK"
SECTION_PLACEMENT_SUSPECT
readonlySECTION_PLACEMENT_SUSPECT:"SECTION_PLACEMENT_SUSPECT"="SECTION_PLACEMENT_SUSPECT"
SEMANTIC_CODE_INVALID
readonlySEMANTIC_CODE_INVALID:"SEMANTIC_CODE_INVALID"="SEMANTIC_CODE_INVALID"
SMOKING_STATUS_CODE_UNRECOGNIZED
readonlySMOKING_STATUS_CODE_UNRECOGNIZED:"SMOKING_STATUS_CODE_UNRECOGNIZED"="SMOKING_STATUS_CODE_UNRECOGNIZED"
SMOKING_STATUS_UNKNOWN
readonlySMOKING_STATUS_UNKNOWN:"SMOKING_STATUS_UNKNOWN"="SMOKING_STATUS_UNKNOWN"
TEMPLATE_EXTENSION_ABSENT
readonlyTEMPLATE_EXTENSION_ABSENT:"TEMPLATE_EXTENSION_ABSENT"="TEMPLATE_EXTENSION_ABSENT"
UCUM_CASE_SUSPECT
readonlyUCUM_CASE_SUSPECT:"UCUM_CASE_SUSPECT"="UCUM_CASE_SUSPECT"
UNEXPECTED_CODE_SYSTEM
readonlyUNEXPECTED_CODE_SYSTEM:"UNEXPECTED_CODE_SYSTEM"="UNEXPECTED_CODE_SYSTEM"
UNKNOWN_DOCUMENT_TEMPLATE
readonlyUNKNOWN_DOCUMENT_TEMPLATE:"UNKNOWN_DOCUMENT_TEMPLATE"="UNKNOWN_DOCUMENT_TEMPLATE"
UNKNOWN_NAMESPACE_PREFIX
readonlyUNKNOWN_NAMESPACE_PREFIX:"UNKNOWN_NAMESPACE_PREFIX"="UNKNOWN_NAMESPACE_PREFIX"
UNKNOWN_SECTION_CODE
readonlyUNKNOWN_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
constXSI_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
warning
Returns
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
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
The parsed document, the parse of the spec-clean XML just emitted.
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
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
Returns
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
Returns
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
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
ctx
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
position
ctx
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): readonlyElement[]
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): readonlyElement[]
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
The profile definition; see DefineCcdaProfileOptions.
Returns
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
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
A new CcdaDocument, the re-parse of the edited XML. 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): readonlyAllergyConcern[]
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
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
Returns
Example
import { extractClinical } from "@cosyte/ccda";
const entries = extractClinical(structuredBodyEl, ctx);
console.log(entries.problems.length);
extractEncounters()
extractEncounters(
sectionEl,narrativeById,ctx): readonlyEncounter[]
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
Returns
readonly Encounter[]
Example
import { extractEncounters } from "@cosyte/ccda";
const encounters = extractEncounters(sectionEl, section.narrativeById, ctx);
extractFamilyHistory()
extractFamilyHistory(
sectionEl,narrativeById,ctx): readonlyFamilyHistory[]
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
Returns
readonly FamilyHistory[]
Example
import { extractFamilyHistory } from "@cosyte/ccda";
const history = extractFamilyHistory(sectionEl, section.narrativeById, ctx);
extractFunctionalStatus()
extractFunctionalStatus(
sectionEl,narrativeById,ctx): readonlyStatusObservation[]
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
Returns
readonly StatusObservation[]
Example
import { extractFunctionalStatus } from "@cosyte/ccda";
const findings = extractFunctionalStatus(sectionEl, section.narrativeById, ctx);
extractImmunizations()
extractImmunizations(
sectionEl,narrativeById,ctx): readonlyImmunization[]
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
Returns
readonly Immunization[]
Example
import { extractImmunizations } from "@cosyte/ccda";
const shots = extractImmunizations(sectionEl, section.narrativeById, ctx);
extractMedications()
extractMedications(
sectionEl,narrativeById,ctx): readonlyMedication[]
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
Returns
readonly Medication[]
Example
import { extractMedications } from "@cosyte/ccda";
const meds = extractMedications(sectionEl, section.narrativeById, ctx);
extractMentalStatus()
extractMentalStatus(
sectionEl,narrativeById,ctx): readonlyStatusObservation[]
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
Returns
readonly StatusObservation[]
Example
import { extractMentalStatus } from "@cosyte/ccda";
const findings = extractMentalStatus(sectionEl, section.narrativeById, ctx);
extractPastMedicalHistory()
extractPastMedicalHistory(
sectionEl,narrativeById,ctx): readonlyProblem[]
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
Returns
readonly Problem[]
Example
import { extractPastMedicalHistory } from "@cosyte/ccda";
const history = extractPastMedicalHistory(sectionEl, section.narrativeById, ctx);
extractPlannedItems()
extractPlannedItems(
sectionEl,narrativeById,ctx): readonlyPlannedItem[]
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).
Whether those three should be reported as dropped is an open decision, at both
levels, and it is still recorded rather than taken.
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
Returns
readonly PlannedItem[]
Example
import { extractPlannedItems } from "@cosyte/ccda";
const planned = extractPlannedItems(sectionEl, section.narrativeById, ctx);
extractProblems()
extractProblems(
sectionEl,narrativeById,ctx): readonlyProblemConcern[]
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
Returns
readonly ProblemConcern[]
Example
import { extractProblems } from "@cosyte/ccda";
const concerns = extractProblems(sectionEl, section.narrativeById, ctx);
extractProcedures()
extractProcedures(
sectionEl,narrativeById,ctx): readonlyProcedure[]
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
Returns
readonly Procedure[]
Example
import { extractProcedures } from "@cosyte/ccda";
const procedures = extractProcedures(sectionEl, section.narrativeById, ctx);
extractResults()
extractResults(
sectionEl,narrativeById,ctx): readonlyResultOrganizer[]
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
Returns
readonly ResultOrganizer[]
Example
import { extractResults } from "@cosyte/ccda";
const panels = extractResults(sectionEl, section.narrativeById, ctx);
extractSmokingStatus()
extractSmokingStatus(
sectionEl,narrativeById,ctx): readonlySmokingStatus[]
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
Returns
readonly SmokingStatus[]
Example
import { extractSmokingStatus } from "@cosyte/ccda";
const statuses = extractSmokingStatus(sectionEl, section.narrativeById, ctx);
extractVitals()
extractVitals(
sectionEl,narrativeById,ctx): readonlyVitalSignsOrganizer[]
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
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
Returns
boolean
Example
import { isSafetyCriticalCode } from "@cosyte/ccda";
console.log(isSafetyCriticalCode("DEPRECATED_LOINC")); // false
console.log(isSafetyCriticalCode("CODE_NARRATIVE_MISMATCH")); // true
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): readonlystring[]
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
presentKeys
ReadonlySet<string>
Returns
readonly string[]
Example
import { missingRequiredSections } from "@cosyte/ccda";
missingRequiredSections("ccd", new Set(["allergies", "problems"]));
// ["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
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
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
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
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
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
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
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
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
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
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
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
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
profileName
string
Returns
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
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
Returns
ReferenceRange | undefined
Example
import { readReferenceRange } from "@cosyte/ccda";
const range = readReferenceRange(resultObs, ctx);
requiredSectionKeys()
requiredSectionKeys(
documentType): readonlystring[]
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
Returns
readonly string[]
Example
import { requiredSectionKeys } from "@cosyte/ccda";
requiredSectionKeys("ccd"); // ["allergies", "medications", "problems", "results"]
requiredSectionKeys("progressNote"); // []
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?
Returns
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
slot
"problem" | "medication" | "allergen" | "route" | "vaccine"
Returns
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
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