@cosyte/terminology
Public entry point for @cosyte/terminology: a zero-dependency, developer-focused
terminology engine for US healthcare code systems.
Unlike its sibling @cosyte/* packages, this is not a wire-format parser: it mirrors the
FHIR Terminology Module ($translate, $lookup, $validate-code, $expand, …), operating
over consumer-supplied FHIR resources. It ships the engine and no code-system release
(SNOMED CT / CPT / LOINC / UMLS / RxNorm are strictly BYO). It is not content-free: see
What is bundled at the end of this note, which includes the UCUM unit table, the code-system
identities (OID ↔ URI), the SNOMED CT concepts the crosswalk resolver names and RxNorm's
relationship and term-type names, each with its copyright.
Code-system identity and ConceptMap translation:
- resolveSystem: the code-system identity / canonical-URI resolver (mnemonic | OID → URI).
- loadConceptMap + translate: the ConceptMap
$translateengine, with the never-fabricate / never-invert invariants: an unmapped source is a typed TranslateUnmapped, never a guessed target; a directional map is never run backwards.
The CodeSystem load layer, with the FHIR $lookup / $validate-code operations:
- loadCodeSystem: load a consumer-supplied release (RRF / CSV / fixed-width / FHIR
CodeSystemJSON) into an immutable model. Ships the loader; no code-system release. - lookup: code → display + properties, carrying status (deprecated / header-not-billable).
- validateCode: is a code a valid member of the system, with its status flags.
The never-fabricate invariant holds here too: an unknown code is a typed unknown / valid: false,
never a fabricated display or a guessed valid: true.
The ValueSet binding layer, FHIR $expand / $validate-code over a compose:
- loadValueSet: load a consumer-supplied FHIR
ValueSet(intensionalcomposeand/or a pre-computedexpansion) into an immutable model. - expand: flatten membership over the supplied CodeSystems (
include/exclude, explicitconceptlists,is-a/propertyfilters, referenced value sets), with an honestcompleteflag: an unresolvable part is a typedTERM_VALUESET_CANNOT_EXPAND, never a guess. - validateCodeInValueSet: binding membership, returning a decided
resultonly when proven and a typedundeterminedotherwise (a truncated expansion never reads as complete).
The UCUM unit layer: a hand-rolled UCUM grammar parser + validation + representation canonicalization (recognition only, no magnitude conversion):
- validateUcum: is a string a valid UCUM unit; if so, its canonical descriptor. An
invalid unit is a typed
TERM_UCUM_INVALID, never a guessed "nearest" unit. - ucumEqual: do two expressions denote the same unit (
N≡kg.m/s2), by reducing both to base dimensions. Not magnitude conversion (mg/dL→mmol/Lis refused). - parseUcum / reduce / loadUcumEssence: the underlying grammar parser, dimensional reducer, and the in-memory model of the vendored, verbatim UCUM table.
The crosswalk resolvers: the never-fabricate/never-invert invariant applied to the published, directional reference maps:
- loadGems + applyGem: the CMS ICD-9↔ICD-10 GEMs (public-domain reference mappings), honoring the steward's Approximate / No-Map / Combination (scenario→choice-list) flags. A No-Map source is a typed CrosswalkNoMap; a 1:many source returns the full candidate set.
- loadComplexMap + applyComplexMap: the NLM SNOMED CT → ICD-10-CM complex map
(BYO, no SNOMED CT refset bundled), evaluating Map Group / Priority /
IFARule / Advice / Category against caller-supplied PatientContext; a rule needing context the caller lacks is a typed ComplexMapContextRequired, never a guessed branch. - invertGem: the never-invert refusal made a first-class, thrown contract (FATAL_CODES.TERM_MAP_NOT_INVERTIBLE).
The RxNorm drug relationship graph: ingredient / brand / clinical-drug / dose-form navigation over a caller-supplied RxNorm RRF release:
- loadRxNormGraph: load
RXNCONSO(concepts, typed byTTY),RXNREL(directedRELAedges, normalized to the documentedRXCUI2 ⟶RELA⟶ RXCUI1direction), and optionallyRXNSAT(NDC attributes) into an immutable graph. Ships no RxNorm release: BYO. - ingredientsOf / genericFor / brandsFor / doseFormsOf /
consistsOf / relatedByRela: graph navigation following authored edges only
(the engine never synthesizes an inverse). An absent
RXCUIis a typed RxNormUnknown. - resolveNdc: NDC →
RXCUIcarrying the temporal status and the as-of release; an absent NDC is a typed NdcUnmapped, never a guess. - approximateMatch: the opt-in, explicitly labeled similarity path (never the default, never an exact code assertion).
What is bundled. No code-system release is. What is bundled includes the following, named with its copyright:
- the UCUM unit table (
ucum-essence.xml, version 2.2, revision-date 2024-06-17): copyright ©1999–2024 Regenstrief Institute, Inc., all rights reserved, reproduced verbatim under the UCUM Copyright Notice and License (https://ucum.org/license), embedded byte-for-byte in the published build and parsed at runtime; no modified or derivative copy is distributed. The UCUM Specification is provided "as is" without warranty of any kind: see the License for the full disclaimer. The complete notice ships with this package atvendor/ucum/NOTICE.md. - the code-system identity facts (SYSTEM_IDENTITIES): OID ↔ canonical-URI pairings, which identify the systems rather than listing any system's codes.
- the SNOMED CT concepts the crosswalk resolver names, each with its description: the four
map-category concepts (MAP_CATEGORIES) a complex-map row's
mapCategoryIdrefers to, and the two gender findings (248152002Female,248153007Male) a genderIFArule is written against. Further SNOMED CT identifiers, and ICD-10-CM codes, appear in the API documentation examples, which are distributed in the compiled declaration files and in the build's sourcemaps. SNOMED CT is copyright © International Health Terminology Standards Development Organisation. - the RxNorm relationship and term-type names the drug-graph API is written against: the
relationship names in RELA / RELA_INVERSE (
has_ingredient,tradename_of, …), and the term-type codes in TERM_TYPES, each with its name as published by the U.S. National Library of Medicine (SCDreads "Semantic Clinical Drug"). Individual RxNorm identifiers also appear in the API documentation examples, with their RxNorm names and term types (for instanceRXCUI316151, "lisinopril 10 MG"), and inREADME.mdas well as the places named above. RxNorm is produced by the National Library of Medicine; no RxNorm release is bundled.
The LICENSE file that ships with this package carries the MIT text for the package's own code
and a third-party notices section naming each of the above.
The content packs that would change this (the CMS GEM files, the RxNorm Current Prescribable subset) are not bundled; a caller supplies them, as they do a SNOMED CT, CPT, LOINC, UMLS or VSAC release, under whatever terms its steward sets. This states what is distributed and under whose copyright; it is not legal advice, and makes no claim about whether a particular use is permitted to you.
Classes
TerminologyError
The engine's typed error. Carries a stable FatalCode so callers branch on err.code
without string-matching the message. Thrown only for FATAL_CODES conditions.
The message is value-free: it names the structural fault (a resource path, a missing field,
the role of a configured column) and never echoes an input value, so it is safe to log, and
safe in an err.stack that reaches an error reporter. The rule the strings are built by is in
this module's docblock above.
Example
import { loadConceptMap, TerminologyError, FATAL_CODES } from "@cosyte/terminology";
try {
loadConceptMap({ resourceType: "Patient" });
} catch (err) {
(err as TerminologyError).code === FATAL_CODES.TERM_CONCEPTMAP_MALFORMED; // => true
}
Extends
Error
Constructors
Constructor
new TerminologyError(
code,message):TerminologyError
Parameters
code
The stable FatalCode describing the fault.
message
string
A value-free structural description (path + fault; never an input value).
Every piece of it must be engine-owned: a literal, a frozen-table entry, or a locus this
package built. This string reaches err.stack, so interpolating a caller-supplied or
document-derived value into it is how a diagnostic becomes a leak.
Returns
Overrides
Error.constructor
Properties
code
readonlycode:FatalCode
The stable fatal code. Branch on this, not on message.
Interfaces
AnnotationNode
A component that carries only an annotation (e.g. {cells}), dimensionless and inert.
Properties
kind
readonlykind:"annotation"
ApproximateMatchOptions
Options for approximateMatch.
Properties
limit?
readonlyoptionallimit?:number
Maximum number of candidates to return, best-first. Default 20.
minScore?
readonlyoptionalminScore?:number
Minimum similarity (0–1) for a candidate to be returned. Default 0.34.
BillableFlag
The billable-flag descriptor for a FixedWidthFieldMap.
Properties
at
readonlyat:number
The 0-based char index of the flag.
billableValue
readonlybillableValue:string
The character value that means "billable/valid leaf" (ICD-10-CM: "1"; "0" is a header).
CodeableConcept
A concept described by one or more Codings plus optional free text: FHIR R4
CodeableConcept. Included so the value layer is complete for downstream consumers even though
../conceptmap/translate.translate operates on a single Coding.
Example
import { codeableConcept } from "@cosyte/terminology";
const cc = codeableConcept({
coding: [{ system: "http://loinc.org", code: "2160-0" }],
text: "Serum creatinine",
});
cc.coding[0].code; // => "2160-0"
Properties
coding
readonlycoding: readonlyCoding[]
The codings for this concept, in order of preference. Frozen and never empty-by-fabrication.
text?
readonlyoptionaltext?:string
Plain-text representation of the concept, when supplied.
CodeSystem
A loaded, immutable code-system release: the queryable model loadCodeSystem produces and lookup / validateCode run over. Concepts are keyed by code for O(1) identity, and every concept is frozen.
Properties
concepts
readonlyconcepts:ReadonlyMap<string,Concept>
The concepts, keyed by code. A read-only view, not a Map you were handed: reads and
iteration behave as a Map's do, adding / deleting / clearing is refused however it is
attempted, and every value is frozen.
A view is not a Map instance: instanceof Map is false and this model cannot be
structuredCloned or posted to a worker; copy out what you need (new Map(…)).
count
readonlycount:number
The number of loaded concepts.
name?
readonlyoptionalname?:string
A short human-readable name, when supplied.
url?
readonlyoptionalurl?:string
The code system's canonical URI, when supplied by the source.
version?
readonlyoptionalversion?:string
The release version, when supplied: mappings and displays are release-scoped.
warnings
readonlywarnings: readonlyLoadWarning[]
The skipped-row warnings surfaced during load, in line order. Frozen; may be empty.
Coding
A single coded value: a code drawn from a code system, optionally versioned and displayed.
Models FHIR R4 Coding. system is the code system's canonical URI (e.g.
http://loinc.org), not a mnemonic or OID: use ../systems/resolve.resolveSystem to
canonicalize before constructing one. system is optional because a raw wire code sometimes
arrives without one; the engine surfaces that rather than inventing a system.
Example
import { coding } from "@cosyte/terminology";
const c = coding({ system: "http://loinc.org", code: "2160-0", display: "Creatinine" });
c.code; // => "2160-0"
Properties
code
readonlycode:string
The symbol in the code system's syntax. Required: a coding without a code is meaningless.
display?
readonlyoptionaldisplay?:string
The human-readable label. Carried verbatim from the source; never fabricated by the engine.
system?
readonlyoptionalsystem?:string
The code system's canonical URI (e.g. http://snomed.info/sct). Optional when unknown.
version?
readonlyoptionalversion?:string
The code system version this code is drawn from, when known (mappings are release-scoped).
ComplexMap
A loaded, immutable SNOMED→ICD-10-CM complex map. Entries are keyed by source concept id; within a source they are ordered by (group, priority). Applied only SNOMED→ICD-10-CM; never inverted.
entries is a read-only view, not a Map you were handed, and each source's rule list
is frozen: nothing that holds a loaded map can delete a source concept's rules, or add one your
refset never carried, and have applyComplexMap resolve from it.
A view is not a Map instance: instanceof Map is false and this model cannot be
structuredCloned or posted to a worker; copy out what you need (new Map(…)).
Properties
count
readonlycount:number
The number of loaded rows.
entries
readonlyentries:ReadonlyMap<string, readonlyComplexMapEntry[]>
Rows keyed by SNOMED source concept id, each ordered by (group, priority). Frozen.
version?
readonlyoptionalversion?:string
The map version/release, when supplied: mappings are release-scoped.
warnings
readonlywarnings: readonlyComplexMapLoadWarning[]
The skipped-row warnings surfaced during load, in line order. Frozen; may be empty.
ComplexMapContextRequired
A group whose winning path is a context-dependent IFA rule (or 447639009/447640006
category) for which the caller supplied no matching context. The engine surfaces the rules +
advice and refuses to pick a branch: the never-fabricate rule for runtime context.
Properties
code
readonlycode:"TERM_CROSSWALK_CONTEXT_REQUIRED"
The stable diagnostic code.
group
readonlygroup:number
The 1-based map group.
outcome
readonlyoutcome:"context-required"
Discriminant.
rules
readonlyrules: readonlyComplexMapEntry[]
The unresolved candidate rules in this group (priority order), each with its target + advice.
ComplexMapEntry
One row of the SNOMED CT → ICD-10-CM complex/extended map refset: the caller-supplied, SNOMED-licensed content the resolver runs over (no SNOMED CT refset is bundled). The field names paraphrase the SNOMED RF2 extended-map refset columns.
Properties
advice
readonlyadvice:string
The map advice, verbatim (pipe-delimited in the source): steward instructions to a human
(CONSIDER LATERALITY, EPISODE OF CARE INFORMATION NEEDED, THIS IS A MANIFESTATION CODE…).
Carried through untouched: advice flags must never be swallowed.
category?
readonlyoptionalcategory?:string
The steward map category id (a MAP_CATEGORIES value, e.g. 447638001), when supplied.
correlation?
readonlyoptionalcorrelation?:string
The map correlation id (SNOMED map-correlation concept), when supplied. Carried verbatim.
group
readonlygroup:number
The map group (1-based). Distinct groups on one source are an AND: the source needs a target from each group (e.g. a manifestation code plus an etiology code). Every group resolves independently.
priority
readonlypriority:number
The map priority within a group (1-based). Rules are evaluated in ascending priority; the first whose rule matches the caller's context wins that group (an if-then-else chain).
rule
readonlyrule:string
The map rule, verbatim: "TRUE" / "OTHERWISE TRUE" (unconditional fall-through), or an
IFA predicate (e.g. an age-band or gender test) evaluated against caller-supplied context.
source
readonlysource:string
The SNOMED CT source concept id (referencedComponentId), verbatim.
target?
readonlyoptionaltarget?:string
The ICD-10-CM map target code, verbatim: absent for a No-Map / empty-target row.
ComplexMapGroupNoMap
A group the steward marked No-Map (447638001 "cannot be classified", or an empty target): a
typed, surfaced outcome, never a fabricated target.
Properties
advice
readonlyadvice:string
The advice on the No-Map row, verbatim.
category?
readonlyoptionalcategory?:string
The steward map category, when supplied (447638001, or absent for an empty-target row).
code
readonlycode:"TERM_CROSSWALK_NO_MAP"
The stable diagnostic code.
group
readonlygroup:number
The 1-based map group.
outcome
readonlyoutcome:"no-map"
Discriminant.
ComplexMapGroupResolved
A group that resolved to a concrete ICD-10-CM target via its winning rule.
Properties
advice
readonlyadvice:string
The winning rule's advice, verbatim.
category?
readonlyoptionalcategory?:string
The steward map category, when supplied (e.g. 447637006).
group
readonlygroup:number
The 1-based map group.
outcome
readonlyoutcome:"resolved"
Discriminant.
rule
readonlyrule:string
The winning rule text, verbatim ("TRUE", an IFA predicate, …).
target
readonlytarget:Coding
The resolved ICD-10-CM target coding (drawn verbatim from the map).
ComplexMapLoadWarning
A surfaced, non-fatal complex-map load warning: a malformed refset row that was skipped.
Properties
code
readonlycode:"TERM_COMPLEX_MAP_MALFORMED_ROW"
The stable diagnostic code for a skipped complex-map row.
detail
readonlydetail:string
A value-free description of the structural fault.
line
readonlyline:number
The 1-based source line the fault was found on.
ComplexMapMatched
A successful complex-map application: one resolution per map group, in group order.
Properties
groups
readonlygroups: readonlyComplexMapGroupResult[]
One resolution per map group, ordered by group. A source needing N codes has N groups. Frozen.
mapped
readonlymapped:true
Discriminant: the source concept is present in the map.
source
readonlysource:string
The SNOMED source concept id, echoed.
Concept
One loaded, immutable concept: the subset of a CodeSystem.concept the operations need.
Properties
code
readonlycode:string
The code, exactly as it appears in the release.
definition?
readonlyoptionaldefinition?:string
The formal definition, when the release supplied one.
display?
readonlyoptionaldisplay?:string
The preferred display, carried verbatim. Absent when the release supplied none (never invented).
properties
readonlyproperties: readonlyProperty[]
Additional properties, in load order. Frozen; may be empty, never fabricated.
status?
readonlyoptionalstatus?:ConceptStatus
The concept's status flags, when the release carried status information.
ConceptMap
A loaded, immutable ConceptMap: the subset of the FHIR R4 ConceptMap resource the
$translate engine needs. Produced by loadConceptMap; every field frozen.
Properties
group
readonlygroup: readonlyConceptMapGroup[]
The translation groups.
sourceScope?
readonlyoptionalsourceScope?:string
The map's sourceUri/sourceCanonical scope, when declared.
targetScope?
readonlyoptionaltargetScope?:string
The map's targetUri/targetCanonical scope, when declared.
url?
readonlyoptionalurl?:string
The resource's canonical url, when declared.
version?
readonlyoptionalversion?:string
The resource's business version, when declared.
ConceptMapElement
One group.element: a source concept and its candidate targets (FHIR R4).
Properties
code?
readonlyoptionalcode?:string
The source code.
display?
readonlyoptionaldisplay?:string
The source display.
target
readonlytarget: readonlyConceptMapTarget[]
The candidate targets.
ConceptMapGroup
One group: a source-system/target-system pair with its element mappings (FHIR R4).
Properties
element
readonlyelement: readonlyConceptMapElement[]
The element mappings.
source?
readonlyoptionalsource?:string
The group's source code system (canonical URI), when declared.
sourceVersion?
readonlyoptionalsourceVersion?:string
The group's source system version, when declared.
target?
readonlyoptionaltarget?:string
The group's target code system (canonical URI), when declared.
targetVersion?
readonlyoptionaltargetVersion?:string
The group's target system version, when declared.
unmapped?
readonlyoptionalunmapped?:ConceptMapUnmapped
The group.unmapped fallback directive, when declared.
ConceptMapTarget
One group.element.target: a candidate target for a source concept (FHIR R4).
Properties
code?
readonlyoptionalcode?:string
The target code (absent for a pure unmatched assertion).
comment?
readonlyoptionalcomment?:string
Author's comment (e.g. steward map advice), carried verbatim.
display?
readonlyoptionaldisplay?:string
The target display, carried verbatim when present.
equivalence
readonlyequivalence:R4Equivalence
The verbatim R4 equivalence token.
ConceptMapUnmapped
A single group.unmapped directive from a loaded ConceptMap group (FHIR R4).
Properties
code?
readonlyoptionalcode?:string
For fixed, the fixed target code.
display?
readonlyoptionaldisplay?:string
For fixed, the fixed target display.
mode
readonlymode:UnmappedMode
The fallback mode.
url?
readonlyoptionalurl?:string
For other-map, the canonical URL of the map to consult.
ConceptRef
One explicit ValueSet.compose.include.concept: an enumerated code (extensional).
Properties
code
readonlycode:string
The code, drawn verbatim from the value set.
display?
readonlyoptionaldisplay?:string
The display, when the value set supplied one (carried verbatim, never fabricated).
ConceptSetComponent
One ValueSet.compose.include / .exclude component: a ConceptSet. Selects codes by an explicit
concept list, by filters over a system, by referencing other value sets (valueSet), or a
combination (the combination is an intersection, per FHIR).
Properties
concept?
readonlyoptionalconcept?: readonlyConceptRef[]
An explicit, enumerated code list (extensional). Mutually exclusive with filter in FHIR.
filter?
readonlyoptionalfilter?: readonlyConceptSetFilter[]
Intensional filters over system. Each code must satisfy all filters.
system?
readonlyoptionalsystem?:string
The code system these codes are drawn from (canonical URI), when the component names one.
valueSet?
readonlyoptionalvalueSet?: readonlystring[]
Canonical URLs of other value sets; a code must be a member of every one (intersection).
version?
readonlyoptionalversion?:string
The code system version to pin the selection to, when declared.
ConceptSetFilter
One ValueSet.compose.include.filter: a property op value predicate over a code system.
Properties
op
readonlyop:FilterOperator
The filter operator.
property
readonlyproperty:string
The concept property the predicate is on (e.g. "concept" for the code hierarchy, or a code).
value
readonlyvalue:string
The comparison value (for in/not-in, a comma-separated list; for is-a, an anchor code).
ConceptStatus
The status flags a $lookup/$validate-code carries on a concept: the safety surface that stops
a non-current or non-billable code from being presented as clean. Present only when
the loaded release supplied status information; the engine never fabricates a status.
Properties
active
readonlyactive:boolean
Convenience: activity === "active". A caller can gate on this without a switch.
activity
readonlyactivity:ConceptActivity
The normalized ConceptActivity.
billable?
readonlyoptionalbillable?:boolean
For classification systems (ICD-10-CM): is this a billable/valid leaf? A header is false.
code?
readonlyoptionalcode?:DiagnosticCode
A stable DiagnosticCode naming the concern, when the concept is not clean-active.
raw?
readonlyoptionalraw?:string
The steward's raw status token, carried verbatim (e.g. "DEPRECATED", "O", "0").
CrosswalkNoMap
A No-Map outcome: the source is present in the map but the steward declares it has no valid target ("cannot be classified with available data"). A first-class typed result, never a fabricated target. Distinct from CrosswalkUnmapped (source absent entirely).
Properties
code
readonlycode:"TERM_CROSSWALK_NO_MAP"
The stable diagnostic code.
entries
readonlyentries: readonlyGemEntry[]
The steward flags/advice that declared the No-Map, carried verbatim.
mapped
readonlymapped:false
Discriminant: the source did not map.
noMap
readonlynoMap:true
Sub-discriminant: this is an authored No-Map, not a plain absence.
source
readonlysource:string
The source code, echoed.
CrosswalkUnmapped
An unmapped outcome: the source code is not present in the map at all (distinct from an authored No-Map). Surfaced as a typed result, never a guessed target and never a silent success.
Properties
code
readonlycode:"TERM_CROSSWALK_UNMAPPED"
The stable diagnostic code.
mapped
readonlymapped:false
Discriminant: the source did not map.
noMap
readonlynoMap:false
Sub-discriminant: a plain absence, not an authored No-Map.
source
readonlysource:string
The source code, echoed.
CsvColumnMap
The column mapping for a CsvSource (header names, matched against the header row).
Properties
code
readonlycode:string
The header name of the code column (e.g. LOINC LOINC_NUM).
display
readonlydisplay:string
The header name of the display column (e.g. LOINC LONG_COMMON_NAME).
properties?
readonlyoptionalproperties?: readonlystring[]
Header names to surface as properties.
status?
readonlyoptionalstatus?:string
The header name of a status column (e.g. LOINC STATUS), when present.
CsvSource
An RFC-4180 CSV source (quoted fields, embedded commas/quotes/newlines): e.g. LOINC's
Loinc.csv. The one release format that needs real quote handling; hand-rolled, zero-dep. BYO.
Properties
columns
readonlycolumns:CsvColumnMap
Which header-named columns hold the code/display/status/properties.
content
readonlycontent:string
The raw CSV file content.
format
readonlyformat:"csv"
Discriminant.
name?
readonlyoptionalname?:string
A human-readable name.
statusMap?
readonlyoptionalstatusMap?:StatusMapper
Override the default status interpretation of the status column's raw token.
url?
readonlyoptionalurl?:string
The code system's canonical URI.
version?
readonlyoptionalversion?:string
The release version.
ExpandResult
The result of expand: the flattened membership plus an honest completeness signal.
complete is false whenever any part could not be fully computed (a missing code system, an
unresolved referenced value set, an unimplemented filter op, or a truncated pre-computed
expansion). A false here is the never-fabricate contract in action: the contains set is a
lower bound, so it must never be read as exhaustive membership.
Properties
complete
readonlycomplete:boolean
Whether the expansion is exhaustive. When false, contains is a lower bound, not the whole set.
contains
readonlycontains: readonlyCoding[]
The expanded, de-duplicated members, in first-seen order (frozen; every member frozen).
diagnostics
readonlydiagnostics: readonlyExpansionDiagnostic[]
The surfaced concerns, in encounter order (frozen; may be empty).
total?
readonlyoptionaltotal?:number
The server-reported total, when the expansion came from a pre-computed snapshot.
ExpansionContains
One ValueSet.expansion.contains entry from a pre-computed expansion.
Properties
code
readonlycode:string
The code. Required: a contains entry without a code is a malformed expansion.
display?
readonlyoptionaldisplay?:string
The display, carried verbatim when present.
system?
readonlyoptionalsystem?:string
The code system URI, when the entry names one.
version?
readonlyoptionalversion?:string
The code system version, when the entry pins one.
ExpansionContext
The data an expand/validateCodeInValueSet call draws on: the loaded
CodeSystem releases (for intensional filter/system includes) and any referenced
ValueSets (for compose.include.valueSet), each keyed by its canonical URL.
The engine makes no network call and holds no bundled code-system release: everything intensional resolves through this map, and a system or value set the caller did not supply becomes a typed DiagnosticCode.TERM_VALUESET_CANNOT_EXPAND, never a fabricated member.
Properties
codeSystems?
readonlyoptionalcodeSystems?:ReadonlyMap<string,CodeSystem>
Loaded code-system releases, keyed by canonical URI (e.g. "http://loinc.org").
valueSets?
readonlyoptionalvalueSets?:ReadonlyMap<string,ValueSet>
Referenced value sets, keyed by canonical URL, for compose.include.valueSet.
ExpansionDiagnostic
A surfaced expansion concern: a part that could not be expanded, or a truncated snapshot.
Properties
code
readonlycode:DiagnosticCode
The stable code (TERM_VALUESET_CANNOT_EXPAND / TERM_VALUESET_EXPANSION_TRUNCATED).
detail
readonlydetail:string
A value-free structural description of the concern (never echoes a patient value).
path?
readonlyoptionalpath?:string
A value-free structural locus into the caller's own resource: "expansion", or a
compose-relative index path such as "compose.include[2]" or
"compose.include[0].valueSet[1]". A diagnostic raised while expanding a referenced value set
is prefixed with the reference that reached it ("compose.include[0].valueSet[1]/compose.include[3]").
Built entirely from integers and the engine's own field names, so nothing the caller or their
resource supplied can reach it, at any length. It replaces the URI this field used to carry:
a canonical URI is unbounded consumer-supplied text on a diagnostic surface, and an index path
is strictly more precise anyway (two includes may name the same system).
FactorNode
A numeric factor component (a bare integer, e.g. the 4 in 4.[pi]).
Properties
kind
readonlykind:"factor"
value
readonlyvalue:number
The integer value.
FhirCodeSystemSource
A FHIR R4 CodeSystem JSON source (native, consumer-supplied model). The consumer supplies the
untrusted resource; nested concept hierarchies are flattened, and the standard inactive /
deprecated concept properties are read into ConceptStatus.
Properties
format
readonlyformat:"fhir"
Discriminant.
resource
readonlyresource:unknown
The untrusted FHIR CodeSystem resource (typically JSON.parse output, hence unknown).
FieldSlice
A half-open [start, end) slice of a fixed-width line (0-based char indices; end optional).
Properties
end?
readonlyoptionalend?:number
The 0-based end char index (exclusive). Omit to slice to end of line.
start
readonlystart:number
The 0-based start char index (inclusive).
FilterMatch
The outcome of evaluating a single filter against a single concept.
Properties
matched
readonlymatched:boolean
Whether the concept satisfies the filter (meaningful only when supported).
supported
readonlysupported:boolean
Whether the engine implements this filter operator; false ⇒ the caller must surface it.
FixedWidthFieldMap
The field mapping for a FixedWidthSource (0-based char slices).
Properties
billable?
readonlyoptionalbillable?:BillableFlag
The billable/header flag (ICD-10-CM position-15), when the format has one.
code
readonlycode:FieldSlice
The slice holding the concept code.
display
readonlydisplay:FieldSlice
The slice holding the display string.
properties?
readonlyoptionalproperties?: readonlyFixedWidthPropertyField[]
Extra slices to surface as properties.
status?
readonlyoptionalstatus?:FieldSlice
A slice holding a status token, when the format has one (alternative to billable).
FixedWidthPropertyField
One extra fixed-width field to capture as a Property.
Properties
name
readonlyname:string
The property code to emit.
slice
readonlyslice:FieldSlice
The field slice.
FixedWidthSource
A fixed-width source (slice by column): e.g. the ICD-10-CM order file. Fully parameterized: the consumer supplies the field slices (see ICD10CM_ORDER_FILE_FIELDS for the documented ICD-10-CM preset, which they confirm against their release's README, since the byte offsets are not confirmed against an authoritative machine-readable source). BYO.
Properties
content
readonlycontent:string
The raw fixed-width file content.
fields
readonlyfields:FixedWidthFieldMap
Which char slices hold the code/display/billable/status/properties.
format
readonlyformat:"fixed-width"
Discriminant.
name?
readonlyoptionalname?:string
A human-readable name.
statusMap?
readonlyoptionalstatusMap?:StatusMapper
Override the default status interpretation of the status slice's raw token.
url?
readonlyoptionalurl?:string
The code system's canonical URI.
version?
readonlyoptionalversion?:string
The release version.
GemChoiceList
One choice list within a combination scenario: pick one of its targets to build a cluster.
Properties
choiceList
readonlychoiceList:number
The choice-list number (GemFlags.choiceList).
targets
readonlytargets: readonlystring[]
The candidate target codes for this choice list, in file order. Frozen; never empty.
GemEntry
One loaded GEM entry: a source code, its (optional) target, and the decoded GemFlags. A No-Map entry (GemFlags.noMap) carries no target: the source has no equivalent, and the engine never invents one.
Properties
flags
readonlyflags:GemFlags
The decoded steward flags.
source
readonlysource:string
The source code (in the map's source classification), verbatim.
target?
readonlyoptionaltarget?:string
The target code (in the map's target classification), verbatim: absent for a No-Map entry.
GemFlags
The decoded 5-position flag field of a GEM entry (CMS Dx GEM User's Guide). Each digit is a steward signal a caller must not ignore; the verbatim field rides through as raw.
Positions (left to right): approximate | no-map | combination | scenario | choice-list.
Properties
approximate
readonlyapproximate:boolean
Position 1: approximate flag. true when the mapping is approximate (the common case: the
source and target are not identical in meaning); false when the entry is an exact identity. A
GEM entry is a reference mapping either way: never an assertion of clinical equivalence.
choiceList
readonlychoiceList:number
Position 5: choice-list number (0 for a non-combination entry). Within a scenario, a valid
cluster is built by taking one target from each distinct choice list.
combination
readonlycombination:boolean
Position 3: combination flag. true when the source requires a combination of target
codes to be fully represented; the entry is one candidate within a scenario/choice-list cluster
(see scenario / choiceList), never a standalone 1:1 target.
noMap
readonlynoMap:boolean
Position 2: no-map flag. true when the source code has no valid target in the other
classification (the target field is the NoDx/NoPCS sentinel). A first-class typed outcome:
surfaced as a CrosswalkNoMap, never a fabricated target.
raw
readonlyraw:string
The verbatim 5-character flag field, carried through untouched.
scenario
readonlyscenario:number
Position 4: scenario number (0 for a non-combination entry). Within a combination, all
entries sharing a scenario describe one valid way to represent the source; distinct scenarios
are alternative representations.
GemLoadWarning
A surfaced, non-fatal GEM load warning: a malformed line that was skipped, reported with its line number and a value-free structural reason. Liberal on load (the parsers' posture).
Properties
code
readonlycode:"TERM_GEM_MALFORMED_ROW"
The stable diagnostic code for a skipped GEM row.
detail
readonlydetail:string
A value-free description of the structural fault (never echoes a field value).
line
readonlyline:number
The 1-based source line the fault was found on.
GemMap
A loaded, immutable GEM map. Entries are keyed by source code (a source may have many entries, the maps are 1:many). Applied only in its direction; never inverted.
entries is a read-only view, not a Map you were handed, and each source's candidate
list is frozen: nothing that holds a loaded map can delete a source's mapping, or add a target the
steward's file never authored, and have applyGem answer from it.
A view is not a Map instance: instanceof Map is false and this model cannot be
structuredCloned or posted to a worker; copy out what you need (new Map(…)).
Properties
count
readonlycount:number
The number of loaded entries.
direction
readonlydirection:GemDirection
Which direction this file maps. Applied only this way.
entries
readonlyentries:ReadonlyMap<string, readonlyGemEntry[]>
Entries keyed by source code, each list in file order. Each list frozen.
version?
readonlyoptionalversion?:string
The GEM version/release (e.g. "2018"), when supplied: mappings are release-scoped.
warnings
readonlywarnings: readonlyGemLoadWarning[]
The skipped-row warnings surfaced during load, in line order. Frozen; may be empty.
GemMatched
A successful GEM application: one or more candidate targets for the source. The full candidate set is surfaced (never collapsed to one); when the source is a combination, combinations carries the scenario/choice-list structure needed to build valid clusters.
Properties
combinations?
readonlyoptionalcombinations?: readonlyGemScenario[]
For a combination source, the scenario→choice-list structure. Absent for a plain 1:many source.
direction
readonlydirection:GemDirection
The direction the map was applied in.
entries
readonlyentries: readonlyGemEntry[]
Every candidate entry for the source, in file order. Frozen; never empty here.
mapped
readonlymapped:true
Discriminant: the source mapped to at least one target.
source
readonlysource:string
The source code, echoed.
GemScenario
One combination scenario: a single valid way to represent the source as a combination of target codes. A valid cluster is one target taken from each of its choiceLists.
Properties
choiceLists
readonlychoiceLists: readonlyGemChoiceList[]
The choice lists composing this scenario, ordered by choice-list number. Frozen.
scenario
readonlyscenario:number
The scenario number (GemFlags.scenario).
GemSource
A raw GEM source file, plus the direction it maps and its release version. BYO: the caller supplies the public-domain CMS GEM file content.
Properties
content
readonlycontent:string
The raw GEM file content (whitespace-delimited: source target flags, one entry per line).
direction
readonlydirection:GemDirection
Which direction this file maps ("9-to-10" for …_I9gem.txt, "10-to-9" for …_I10gem.txt).
version?
readonlyoptionalversion?:string
The GEM release/version (e.g. "2018"), when known: mappings are release-scoped.
GroupNode
A parenthesised sub-term or an annotation-only component.
Properties
kind
readonlykind:"group"
term
readonlyterm:UnitNode
The parsed inner term.
LinearReduction
A unit reduced to base dimensions: a scalar factor times a map of dimension axis → exponent.
Dimension keys are the seven UCUM base symbols (m s g rad K C cd) plus arb:<code> axes for
arbitrary units. Two linear forms are the same unit iff equal dims and equal factor.
Properties
dims
readonlydims:Readonly<Record<string,number>>
Dimension axis → non-zero exponent (zero exponents omitted).
factor
readonlyfactor:number
The accumulated scalar factor in base units.
kind
readonlykind:"linear"
LoadWarning
A surfaced, non-fatal load warning: a malformed row that was skipped, reported with its line number and a value-free structural reason (never the row's content). Liberal on load.
Properties
code
readonlycode:DiagnosticCode
The stable diagnostic code (TERM_RRF_MALFORMED_ROW / _CSV_MALFORMED / _FIXED_WIDTH_MALFORMED).
detail
readonlydetail:string
A value-free description of the structural fault (never echoes a field value).
line
readonlyline:number
The 1-based source line the fault was found on (positional context; value-free).
LookupResult
A successful lookup: the concept's details plus its release provenance.
Properties
code
readonlycode:string
The code, echoed.
definition?
readonlyoptionaldefinition?:string
The formal definition, when present.
display?
readonlyoptionaldisplay?:string
The preferred display, when the release carried one (never fabricated).
found
readonlyfound:true
Discriminant: the code was found.
properties
readonlyproperties: readonlyProperty[]
The concept's properties, in load order (frozen, may be empty).
status?
readonlyoptionalstatus?:ConceptStatus
The concept's status flags, when present.
system?
readonlyoptionalsystem?:string
The code system's canonical URI, when known.
version?
readonlyoptionalversion?:string
The release version, when known.
LookupUnknown
A fail-safe unknown lookup: the never-fabricate outcome; no display is ever guessed.
Properties
code
readonlycode:"TERM_CODE_UNKNOWN"
The stable diagnostic code for an unknown code.
found
readonlyfound:false
Discriminant: the code was not found.
input
readonlyinput:string
The code that was looked up, echoed so the caller can surface it.
MapProvenance
Provenance of a translation, which map (and which group's systems) produced it.
Properties
conceptMapUrl?
readonlyoptionalconceptMapUrl?:string
The ConceptMap's canonical url, when declared.
conceptMapVersion?
readonlyoptionalconceptMapVersion?:string
The ConceptMap's business version, when declared (mappings are release-scoped).
sourceSystem?
readonlyoptionalsourceSystem?:string
The source code system for this translation. This is an echo of your query, not reference
data off the map: it is the system on the Coding you passed to translate, verbatim and
unbounded, whenever that coding carries one; the matched (or consulted) group's own source is
only the fallback for a coding that does not. Log it only if you would log the code you passed
in.
targetSystem?
readonlyoptionaltargetSystem?:string
The target code system of the group that matched, when known.
NdcResolution
A resolved NDC → RXCUI mapping (from an RXNSAT.RRF ATN=NDC attribute), carrying the
temporal NdcStatus and the as-of release it is valid for. NDC↔RXCUI is many:1 and
changes across releases, so a resolution is never timeless: the release rides
through on asOf.
Properties
asOf?
readonlyoptionalasOf?:string
The release version the mapping is valid as of, when the graph carries one.
ndc
readonlyndc:string
The 11-digit NDC (as supplied), echoed.
resolved
readonlyresolved:true
Discriminant: the NDC resolved to a concept in the loaded release.
rxcui
readonlyrxcui:string
The RXCUI the NDC attribute is attached to in the loaded release.
status
readonlystatus:NdcStatus
The temporal status of the NDC (NdcStatus).
NdcUnmapped
An NDC that could not be resolved to any RXCUI in the loaded release: a typed absence.
Properties
code
readonlycode:"TERM_RXNORM_NDC_UNMAPPED"
The stable diagnostic code.
ndc
readonlyndc:string
The NDC (as supplied), echoed.
resolved
readonlyresolved:false
Discriminant: the NDC is not present in the loaded release.
ParseFailure
A parse failure carrying a value-free structural reason.
Properties
ok
readonlyok:false
reason
readonlyreason:string
A structural description of the fault (never echoes an input value beyond the offending token shape).
PatientContext
The caller-supplied patient context an IFA rule is evaluated against. The resolver evaluates
only against what it is given: a rule needing context absent here surfaces as a
ComplexMapContextRequired, never a silently-picked branch.
Properties
ageYears?
readonlyoptionalageYears?:number
The patient's age in years, when known (for IFA … Age … bands).
gender?
readonlyoptionalgender?:"male"|"female"
The patient's administrative gender, when known (for gender IFA rules).
Property
One property value on a concept: models FHIR R4 $lookup property ("one or more properties
that contain additional information about the code, including status"). Carried verbatim from the
release; never fabricated.
Properties
code
readonlycode:string
Identifies the property (FHIR property.code), e.g. "shortDescription", "TTY", "parent".
description?
readonlyoptionaldescription?:string
Optional human-readable rendering of the value (FHIR property.description).
value
readonlyvalue:string|number|boolean
The property value (FHIR property.value[x]), reduced to the primitive kinds the readers emit.
RrfColumnMap
The column mapping for an RrfSource (0-based column indices into the pipe-split row).
Properties
code
readonlycode:number
The column holding the concept code (e.g. RxNorm RXCUI = 0, or CODE = 13).
display
readonlydisplay:number
The column holding the display string (e.g. STR = 14).
properties?
readonlyoptionalproperties?: readonlyRrfPropertyColumn[]
Extra columns to surface as properties.
status?
readonlyoptionalstatus?:number
The column holding a status/suppress token (e.g. SUPPRESS = 16), when present.
RrfPropertyColumn
One extra RRF column to capture as a Property.
Properties
column
readonlycolumn:number
The 0-based column index.
name
readonlyname:string
The property code to emit.
RrfSource
An RRF (Rich Release Format, pipe-delimited RxNorm/UMLS release) source. One parameterized
reader serves both: RxNorm RXNCONSO/RXNSAT and UMLS MRCONSO/MRSAT share the RRF shape
(pipe-delimited, one trailing pipe per line). BYO: the consumer supplies the file.
Properties
columns
readonlycolumns:RrfColumnMap
Which columns hold the code/display/status/properties.
content
readonlycontent:string
The raw RRF file content.
format
readonlyformat:"rrf"
Discriminant.
name?
readonlyoptionalname?:string
A human-readable name.
statusMap?
readonlyoptionalstatusMap?:StatusMapper
Override the default status interpretation of the status column's raw token.
url?
readonlyoptionalurl?:string
The code system's canonical URI, attached to the loaded release.
version?
readonlyoptionalversion?:string
The release version (RRF carries none inline, supply it so displays stay release-scoped).
RxNormApproximateMatch
One approximate-match candidate (the opt-in, never-default path). Every field is
marked so a caller can never mistake it for an exact identity: approximate is always true
and score is the labeled, derived similarity. The concept itself is drawn verbatim from the
loaded release.
Properties
approximate
readonlyapproximate:true
Always true: this is a similarity match, never an exact code resolution.
concept
readonlyconcept:RxNormConcept
The matched concept, verbatim from the loaded release.
score
readonlyscore:number
A derived, labeled similarity score in [0, 1] (token overlap). Never a clinical assertion.
RxNormConcept
One RxNorm concept (RXCUI) as loaded from RXNCONSO.RRF: its normalized name and term type.
Built from the concept's SAB=RXNORM atom (the normalized form); the verbatim RXCUI, TTY, and
STR (name) ride through untouched.
Properties
name
readonlyname:string
The concept's normalized name (RXNCONSO.STR), verbatim.
rxcui
readonlyrxcui:string
The RxNorm concept unique identifier (RXCUI), verbatim.
suppressed
readonlysuppressed:boolean
true when the source atom is suppressed (RXNCONSO.SUPPRESS ≠ N): surfaced, never hidden.
tty
readonlytty:TermType
The concept's term type (TermType), verbatim from the RXNCONSO.TTY of a defining
atom. Never a synonym-class TTY (PSN/SY/TMSY), which types a name rather than a concept.
RxNormEdge
One directed relationship edge, normalized from an RXNREL.RRF row under the documented direction
convention (see the module doc): the row (RXCUI1, …, RELA, RXCUI2, …) becomes
subject = RXCUI2, predicate = RELA, object = RXCUI1: read subject ⟶predicate⟶ object.
Properties
object
readonlyobject:string
The object RXCUI: RXCUI1 in the source row. The concept the relationship is to.
predicate
readonlypredicate:string
The relationship label (RXNREL.RELA, e.g. has_ingredient), verbatim.
subject
readonlysubject:string
The subject RXCUI: RXCUI2 in the source row. The concept the relationship is from.
RxNormGraph
A loaded, immutable RxNorm drug graph: concepts keyed by RXCUI, edges indexed by subject, and the
NDC→RXCUI attribute index. Applied only in the authored edge direction; never inverted.
Its three indexes are read-only views, not Maps you were handed: reads and iteration behave
as a Map's do, and adding / deleting / clearing is refused however it is attempted. What that
buys is the never-fabricate invariant surviving the handover: nothing that holds a loaded graph
can empty a medication's ingredient edges, or add an edge or concept the release never authored,
and leave conceptCount / edgeCount still reporting the loaded figures.
A view is not a Map instance: instanceof Map is false and this model cannot be
structuredCloned or posted to a worker; copy out what you need (new Map(…)).
Properties
conceptCount
readonlyconceptCount:number
The number of loaded concepts.
concepts
readonlyconcepts:ReadonlyMap<string,RxNormConcept>
Concepts keyed by RXCUI (first SAB=RXNORM atom per RXCUI wins). Each frozen.
edgeCount
readonlyedgeCount:number
The number of loaded edges.
edges
readonlyedges:ReadonlyMap<string, readonlyRxNormEdge[]>
Directed edges indexed by subject RXCUI, each list in file order. Each list frozen.
ndcs
readonlyndcs:ReadonlyMap<string, {rxcui:string;status:NdcStatus; }>
NDC → { rxcui, status } index from RXNSAT ATN=NDC attributes. Each frozen; may be empty.
version?
readonlyoptionalversion?:string
The release version (e.g. "RXNORM_2026AA"), when supplied: mappings are release-scoped.
warnings
readonlywarnings: readonlyRxNormLoadWarning[]
The skipped-row warnings surfaced during load, in file/line order. Frozen; may be empty.
RxNormGraphSource
A raw RxNorm RRF release, BYO. The caller supplies the public-domain Current Prescribable Content subset or the full (licensed) release; the engine bundles no RxNorm release.
Properties
conso
readonlyconso:string
The raw RXNCONSO.RRF content (pipe-delimited concept/atom names).
rel
readonlyrel:string
The raw RXNREL.RRF content (pipe-delimited relationships).
sat?
readonlyoptionalsat?:string
The raw RXNSAT.RRF content (pipe-delimited attributes): supply to resolve NDCs. Optional.
version?
readonlyoptionalversion?:string
The release version (e.g. "RXNORM_2026AA"), when known: mappings are release-scoped.
RxNormLoadWarning
A surfaced, non-fatal RxNorm load warning: an RXNCONSO / RXNREL / RXNSAT row (or, for
TERM_RXNORM_UNTYPED_CONCEPT, an RXCUI) that was skipped, reported with its line number and
a value-free structural reason (liberal on load). Never echoes a field value.
Properties
code
readonlycode:"TERM_RXNORM_MALFORMED_ROW"|"TERM_RXNORM_UNTYPED_CONCEPT"
The stable diagnostic code for the skip. TERM_RXNORM_MALFORMED_ROW is a structurally unusable
row; TERM_RXNORM_UNTYPED_CONCEPT is an RXCUI no defining atom could type. Both are in the
package-wide ../common/diagnostics.DIAGNOSTIC_CODES registry, which documents each.
detail
readonlydetail:string
A value-free description of the structural fault.
file
readonlyfile:"RXNCONSO"|"RXNREL"|"RXNSAT"
Which source file the fault was in.
line
readonlyline:number
The 1-based source line the fault was found on.
RxNormRelated
A successful graph-navigation result: the concept, the predicate followed, and the full set of
related concepts drawn verbatim from the loaded edges. targets may be empty: that is an
honest, data-grounded "the release has no such edge for this concept", never a fabricated relation.
Properties
found
readonlyfound:true
Discriminant: the source RXCUI is present in the graph.
predicates
readonlypredicates: readonlystring[]
The relationship predicate(s) that were followed.
rxcui
readonlyrxcui:string
The source RXCUI, echoed.
targets
readonlytargets: readonlyRxNormConcept[]
The related concepts, in edge order, each drawn verbatim from the loaded graph. May be empty.
RxNormUnknown
A typed unknown navigation result: the queried RXCUI is absent from the loaded graph. A
first-class outcome, never a fabricated concept or an empty success (the never-fabricate
invariant, applied to the drug graph). Distinct from a RxNormRelated with empty
targets, which means "present, but no such relationship".
Properties
code
readonlycode:"TERM_RXNORM_UNKNOWN_RXCUI"
The stable diagnostic code.
found
readonlyfound:false
Discriminant: the source RXCUI is not in the graph.
rxcui
readonlyrxcui:string
The queried RXCUI, echoed.
SimpleUnitNode
One parsed component of a unit term: a simple unit (prefix?+atom) with an optional exponent.
Properties
atom
readonlyatom:UcumAtom
The resolved atom.
exponent
readonlyexponent:number
The integer exponent (default 1). Negative for the denominator side.
kind
readonlykind:"simple"
prefix?
readonlyoptionalprefix?:UcumPrefix
The applied prefix, when present.
SpecialReduction
A non-linear (special) reduction: the expression involves a special unit (Cel, B, …) and
cannot be reduced to a scalar×dimension form. Carried by its normalized representation form;
two special reductions are the same unit iff their forms are identical (never equated with a
linear unit: the never-fabricate posture applied to units).
Properties
form
readonlyform:string
The normalized expression string (prefixes/atoms/exponents; annotations stripped).
kind
readonlykind:"special"
Subsumption
An immutable ancestor index over a CodeSystem's parent edges.
Methods
ancestorsOf()
ancestorsOf(
code):ReadonlySet<string>
All (transitive) ancestor codes of code, cycle-safe. Excludes code itself.
Parameters
code
string
Returns
ReadonlySet<string>
SystemIdentity
A resolved code-system identity: the canonical URI plus the alternate identifiers that name the same system.
Properties
mnemonics
readonlymnemonics: readonlystring[]
HL7 v2 Table 0396 mnemonic(s) and other accepted short aliases for this system.
name
readonlyname:string
A short human-readable name for diagnostics/logs (value-free, a system name, never a value).
oid?
readonlyoptionaloid?:string
The registered OID (bare, no urn:oid: prefix), when the system has one.
url
readonlyurl:string
The canonical URI: the single value the engine treats as the system's identity.
TranslateMatch
One target concept a translate call produced, with its relationship to the source and the verbatim R4 equivalence token. Never fabricated: every field is drawn from the loaded map.
Properties
comment?
readonlyoptionalcomment?:string
Author's free-text comment on this mapping, when present (carried verbatim, e.g. map advice).
equivalence
readonlyequivalence:R4Equivalence
The verbatim FHIR R4 equivalence token this match was declared with.
relationship
readonlyrelationship:Relationship
The normalized, version-neutral relationship (R5 vocabulary).
target
readonlytarget:Coding
The target Coding exactly as declared in the map (frozen).
TranslateMatched
A successful translation: one or more matches, never empty (an empty result is unmapped).
Properties
matches
readonlymatches: readonlyTranslateMatch[]
The target concepts, in declared order. Non-empty and frozen.
provenance
readonlyprovenance:MapProvenance
Where this translation came from.
unmapped
readonlyunmapped:false
Discriminant: the source mapped.
TranslateUnmapped
A fail-safe unmapped translation: the never-fabricate outcome. The source is surfaced as-is;
no target is ever guessed. Any group.unmapped fallback the author declared is reported via
UnmappedMode (and fixedTarget/otherMapUrl) for the caller to accept or reject: the
engine does not silently substitute it.
Properties
code
readonlycode:"TERM_TRANSLATE_UNMAPPED"
The stable diagnostic code for an unmapped translation.
fixedTarget?
readonlyoptionalfixedTarget?:Coding
For mode: "fixed", the author's fixed fallback coding: reported, not auto-applied.
mode
readonlymode:UnmappedMode
The map author's declared fallback mode (or none).
otherMapUrl?
readonlyoptionalotherMapUrl?:string
For mode: "other-map", the referenced map's URL: reported, not auto-followed.
provenance
readonlyprovenance:MapProvenance
Where the (failed) translation was attempted.
source
readonlysource:Coding
The original source Coding, surfaced untouched.
unmapped
readonlyunmapped:true
Discriminant: the source did not map.
UcumAtom
A UCUM unit atom, from the essence <base-unit> / <unit> table. An atom is a symbol like m,
L, [in_i], 10*, or Cel, before any prefix or exponent is applied.
Properties
arbitrary
readonlyarbitrary:boolean
An arbitrary unit (essence isArbitrary, e.g. [IU], [arb'U]): not commensurable with
any other unit. Modeled as its own dimension axis keyed by the atom code, so [IU]/[IU]
reduces to unity but [IU] is never equated with a mass or another arbitrary unit.
base
readonlybase:boolean
A base unit (one of the 7: m s g rad K C cd), its own dimension, factor 1.
code
readonlycode:string
The case-sensitive atom symbol (the essence Code, e.g. "m", "[iU]", "m[Hg]").
dim?
readonlyoptionaldim?:string
A base unit's dimension key (its own code), or undefined for derived atoms.
metric
readonlymetric:boolean
Whether a metric prefix may attach to this atom (essence isMetric). Only metric atoms prefix.
special
readonlyspecial:boolean
A special unit (essence isSpecial, e.g. Cel, B, [pH]): defined by a non-linear
function, so it has no linear factor/dimension and is never reduced to one. Compared only by
identity of its normalized representation (never claimed equal to a linear unit).
value?
readonlyoptionalvalue?:object
The linear definition: 1 <atom> = value × <unit> (essence <value value Unit>), for derived
atoms. undefined for base units (they define the dimensions) and for special units (non-linear).
factor
readonlyfactor:number
unit
readonlyunit:string
UcumEssence
The parsed UCUM essence table: the engine's in-memory unit model, built lazily and cached.
Properties
atomByCode
readonlyatomByCode:ReadonlyMap<string,UcumAtom>
Atom lookup by exact code.
atoms
readonlyatoms: readonlyUcumAtom[]
Atom symbols → atom, longest symbols first (for greedy longest-match).
prefixByCode
readonlyprefixByCode:ReadonlyMap<string,UcumPrefix>
Prefix lookup by exact code.
prefixes
readonlyprefixes: readonlyUcumPrefix[]
Prefix symbols → prefix, longest symbols first (for greedy matching).
UcumPrefix
A UCUM metric prefix (e.g. k = kilo, factor 1e3), from the essence <prefix> table.
Properties
code
readonlycode:string
The case-sensitive prefix symbol (e.g. "k", "da", "Ki").
factor
readonlyfactor:number
The multiplicative factor (e.g. 1000 for k, 1024 for Ki).
UnitNode
A parsed UCUM term: an ordered list of components, each combined into the product with the given
sign (+1 for . / the leading operand, -1 for the / denominator).
Properties
factors
readonlyfactors: readonlyobject[]
The components and their operator sign, in source order.
kind
readonlykind:"term"
UnknownSystem
The typed "not recognized" outcome from resolveSystem: surfaced, never a guess.
Properties
input
readonlyinput:string
The identifier as supplied, echoed back so the caller can surface/log it.
unknown
readonlyunknown:true
Discriminant: the identifier was not recognized.
ValidateCodeResult
The result of validateCode: models FHIR R4 $validate-code's result boolean. A found
concept is valid: true carrying its status (a deprecated or header code validates as present
but is flagged, never presented clean); an absent code is valid: false, never a guessed true.
Properties
code?
readonlyoptionalcode?:DiagnosticCode
For an invalid code, the stable diagnostic (TERM_CODE_UNKNOWN); absent when valid.
status?
readonlyoptionalstatus?:ConceptStatus
The concept's status flags, when the code was found and the release carried status.
valid
readonlyvalid:boolean
FHIR result: true if the code is a valid member of the code system.
ValueSet
A loaded, immutable ValueSet: the subset of the FHIR R4 ValueSet resource the binding layer
needs. Produced by loadValueSet; every field deep-frozen.
Properties
compose?
readonlyoptionalcompose?:ValueSetCompose
The intensional/extensional compose, when the resource defines membership by composition.
expansion?
readonlyoptionalexpansion?:ValueSetExpansion
A pre-computed expansion, when the resource carries a cached membership snapshot.
name?
readonlyoptionalname?:string
A short human-readable name, when declared.
url?
readonlyoptionalurl?:string
The resource's canonical url, when declared (the key referenced value sets resolve against).
version?
readonlyoptionalversion?:string
The resource's business version, when declared.
ValueSetCompose
A ValueSet.compose: the intensional/extensional definition of membership.
Properties
exclude
readonlyexclude: readonlyConceptSetComponent[]
The exclude components: codes removed from the include union.
include
readonlyinclude: readonlyConceptSetComponent[]
The include components (their union, minus every exclude, is the membership).
ValueSetExpansion
A pre-computed ValueSet.expansion: a cached membership snapshot, used as-is (extensional).
The engine never re-derives it; it only checks whether it is complete (a truncated
expansion must never read as full membership).
Properties
contains
readonlycontains: readonlyExpansionContains[]
The snapshot members, in expansion order (frozen).
total?
readonlyoptionaltotal?:number
The server-reported total membership, when present (FHIR expansion.total).
truncated
readonlytruncated:boolean
Derived at load: the expansion is incomplete. True when total exceeds contains.length, or
the http://hl7.org/fhir/StructureDefinition/valueset-toocostly extension flagged it too-costly
(the VSAC >1200-code truncation hazard). A truncated expansion never reads as complete membership.
ValueSetMemberDecided
A definitive membership answer: the code is (or is not) a member of the value set.
Properties
coding
readonlycoding:Coding
The coding that was tested, echoed.
result
readonlyresult:boolean
FHIR $validate-code result: true iff the code is a member of the value set.
undetermined
readonlyundetermined:false
Discriminant: membership was decided.
ValueSetMemberUndetermined
A fail-safe undetermined membership: the never-fabricate outcome for a value set that could
not be fully evaluated (a missing code system, a truncated expansion). The engine refuses to guess:
it returns neither true nor false, so a caller can never mistake "we could not check" for "not a
member" (a false "not a member" is a clinical error).
Properties
code
readonlycode:"TERM_VALUESET_CANNOT_EXPAND"
The stable diagnostic code (TERM_VALUESET_CANNOT_EXPAND).
coding
readonlycoding:Coding
The coding that was tested, echoed.
diagnostics
readonlydiagnostics: readonlyExpansionDiagnostic[]
The surfaced reasons the check could not be completed.
undetermined
readonlyundetermined:true
Discriminant: membership could not be decided.
Type Aliases
CodeSystemSource
CodeSystemSource =
RrfSource|CsvSource|FixedWidthSource|FhirCodeSystemSource
The discriminated union loadCodeSystem accepts.
ComplexMapApplyResult
ComplexMapApplyResult =
ComplexMapMatched|CrosswalkUnmapped
The result of ../crosswalk/complex-map.applyComplexMap: a per-group match, or a typed absence when the source concept is not in the map.
ComplexMapGroupResult
ComplexMapGroupResult =
ComplexMapGroupResolved|ComplexMapGroupNoMap|ComplexMapContextRequired
One map group's resolution: a discriminated outcome. A group resolves to a target, a No-Map, an ambiguity (candidates surfaced), or a context-required stall; it is never a silently-picked single target when the steward flagged otherwise.
ComplexMapInput
ComplexMapInput = {
format:"rows";rows: readonlyComplexMapEntry[];version?:string; } | {content:string;format:"rf2";version?:string; }
The discriminated input loadComplexMap accepts: already-structured refset rows, or a raw RF2 tab-delimited extended-map refset the caller exported from their SNOMED release.
ComponentNode
ComponentNode =
SimpleUnitNode|FactorNode|GroupNode|AnnotationNode
A component: a simple unit, a factor, a group, or an annotation, each optionally exponentiated.
ConceptActivity
ConceptActivity =
"active"|"deprecated"|"discouraged"|"trial"|"obsolete"|"suppressed"|"header"|"unknown"
A concept's normalized activity: whether it is a clean, current, usable code, or carries a
steward status that a caller must not ignore. active is the boolean convenience derived from it.
active: current and usable.deprecated: no longer current (LOINCDEPRECATED; a FHIRinactive/deprecatedconcept).discouraged/trial: LOINC lifecycle states (usable, but not settled).obsolete: withdrawn (RxNormSUPPRESS = O).suppressed: editor-suppressed (RxNorm/UMLSSUPPRESS = Y/E).header: a classification header, not a billable/valid leaf (ICD-10-CM flag0).unknown: a status token the mapper did not recognize; carried verbatim, never guessed clean.
DiagnosticCode
DiagnosticCode = typeof
DIAGNOSTIC_CODES[keyof typeofDIAGNOSTIC_CODES]
A value from DIAGNOSTIC_CODES: the type consumers narrow a diagnostic's code against.
FatalCode
FatalCode = typeof
FATAL_CODES[keyof typeofFATAL_CODES]
A value from FATAL_CODES: the type carried by a thrown TerminologyError.
FilterOperator
FilterOperator =
"="|"is-a"|"descendent-of"|"is-not-a"|"regex"|"in"|"not-in"|"generalizes"|"exists"
A FHIR R4 ValueSet.compose.include.filter operator: the subset the engine implements plus the
ones it explicitly does not. Grounded on the FHIR filter-operator code system
(https://hl7.org/fhir/R4/valueset-filter-operator.html).
Implemented: is-a / descendent-of / is-not-a (subsumption over the loaded release's
hierarchy), = / in / not-in / exists (property predicates). Not implemented (surfaced as
a typed DiagnosticCode.TERM_VALUESET_CANNOT_EXPAND, never silently mis-expanded): regex,
generalizes. Anything unrecognized is treated as not-implemented: never as "matches nothing".
GemApplyResult
GemApplyResult =
GemMatched|CrosswalkNoMap|CrosswalkUnmapped
The result of ../crosswalk/gems.applyGem: a match, an authored No-Map, or an absence.
GemDirection
GemDirection =
"9-to-10"|"10-to-9"
The direction of a loaded GEM file. CMS ships the forward (ICD-9→ICD-10, …_I9gem.txt) and
backward (ICD-10→ICD-9, …_I10gem.txt) maps as separate, non-inverse artifacts: a forward map
composed with a backward map is "not a mirror image". A GemMap therefore records
which direction it is and is only ever applied in that direction.
LookupOutcome
LookupOutcome =
LookupResult|LookupUnknown
The result of lookup: a found concept or a typed LookupUnknown.
MapCategoryId
MapCategoryId = typeof
MAP_CATEGORIES[keyof typeofMAP_CATEGORIES]
A value from MAP_CATEGORIES: the SNOMED map-category id carried on a resolution.
NdcResult
NdcResult =
NdcResolution|NdcUnmapped
The result of ../rxnorm/navigate.resolveNdc: a resolution or a typed absence.
NdcStatus
NdcStatus =
"active"|"obsolete"|"alien"|"unknown"
The temporal status of an NDC↔RXCUI mapping (RxNav getNDCStatus: ACTIVE / OBSOLETE / ALIEN
/ UNKNOWN). An NDC found in the loaded release's RXNSAT attributes is active as of that
release; obsolete / alien come from the RxNav NDC-history data (a differential / BYO source,
not the base RRF concept files) and are surfaced only when the caller supplies them: the engine
never fabricates a non-current status.
ParseResult
ParseResult = {
node:UnitNode;ok:true; } |ParseFailure
A successful parse (the AST) or a value-free failure reason.
R4Equivalence
R4Equivalence =
"relatedto"|"equivalent"|"equal"|"wider"|"subsumes"|"narrower"|"specializes"|"inexact"|"unmatched"|"disjoint"
The verbatim FHIR R4 ConceptMap.group.element.target.equivalence value, carried through
untouched so nothing the map author asserted is lost. (R4 enum:
relatedto | equivalent | equal | wider | subsumes | narrower | specializes | inexact | unmatched | disjoint.)
Reduction
Reduction =
LinearReduction|SpecialReduction
The reduced canonical form of a unit expression.
RelaName
A value from RELA: a drug-graph relationship name.
Relationship
Relationship =
"equivalent"|"source-is-narrower-than-target"|"source-is-broader-than-target"|"related-to"|"not-related-to"
The engine's normalized, version-neutral relationship between a source and a target concept:
the FHIR R5 vocabulary, which the R4 equivalence tokens fold into cleanly. Surfaced on every
match alongside the verbatim R4 token.
equivalent← R4equivalent/equalsource-is-narrower-than-target← R4wider/subsumes(the source is-a the target)source-is-broader-than-target← R4narrower/specializes(the target is-a the source)related-to← R4relatedto/inexactnot-related-to← R4disjoint/unmatched
ResolveSystemResult
ResolveSystemResult =
SystemIdentity|UnknownSystem
The result of resolveSystem: a resolved SystemIdentity or a typed unknown.
RxNormNavResult
RxNormNavResult =
RxNormRelated|RxNormUnknown
The result of a graph-navigation query: a match (possibly empty) or a typed unknown source.
StatusMapper
StatusMapper = (
raw) =>ConceptActivity
A mapper from a raw steward status token to a normalized ConceptActivity. Overridable.
Parameters
raw
string
Returns
TermType
TermType =
"IN"|"PIN"|"MIN"|"BN"|"SCDC"|"SBDC"|"SCDF"|"SBDF"|"SCDFP"|"SBDFP"|"SCD"|"SBD"|"SCDG"|"SBDG"|"SCDGP"|"GPCK"|"BPCK"|"DF"|"DFG"|"PSN"|"SY"|"TMSY"|"ET"
A RxNorm term type (TTY): the kind of drug concept an RXCUI names. These are the
RXNCONSO.RRF TTY values relevant to the drug graph, grounded on the NLM RxNorm Technical
Documentation (Appendix 5). Carried verbatim on a RxNormConcept; the engine classifies but
never re-labels a concept.
PSN / SY / TMSY are Appendix 5's synonym term types: each labels an alternate name on
some other concept rather than a concept of its own, so they are part of this vocabulary but can
never appear as a loaded RxNormConcept.tty. See
../rxnorm/tty.isSynonymTermType.
TranslateResult
TranslateResult =
TranslateMatched|TranslateUnmapped
The result of translate: a matched result or a typed TranslateUnmapped.
UcumValidation
UcumValidation = {
canonical:string;valid:true; } | {code:"TERM_UCUM_INVALID";reason:string;valid:false; }
The result of validateUcum: a valid unit with its canonical descriptor, or a typed invalid carrying the stable TERM_UCUM_INVALID diagnostic and a value-free reason.
Union Members
Type Literal
{ canonical: string; valid: true; }
canonical
readonlycanonical:string
A stable, normalized descriptor of the unit's canonical form: equal iff the units are the same (see ucumEqual). Note: this is a comparison/debug descriptor, not guaranteed to be a re-parseable UCUM expression (UCUM cannot express arbitrary numeric factors as literals).
valid
readonlyvalid:true
The expression is a well-formed UCUM unit over known atoms.
Type Literal
{ code: "TERM_UCUM_INVALID"; reason: string; valid: false; }
code
readonlycode:"TERM_UCUM_INVALID"
The stable diagnostic code: never a guessed "nearest" unit (the never-fabricate rule).
reason
readonlyreason:string
A value-free structural reason (a grammar fault or an unknown atom; never PHI).
valid
readonlyvalid:false
The expression is not a valid UCUM unit.
UnmappedMode
UnmappedMode =
"provided"|"fixed"|"other-map"|"none"
The FHIR R4 group.unmapped.mode an unmapped source fell through to: the map author's declared
fallback behavior. Surfaced (never silently acted on): the caller decides whether to trust a
fallback.
provided: echo the source code as the target (the map declares no real mapping).fixed: a single fixed fallback code the map declares for all unmapped sources.other-map: consult the referenced ConceptMap (which this engine does not auto-follow).none: nogroup.unmappeddirective applied (plain no-match, or an explicitunmatched).
ValueSetMembership
ValueSetMembership =
ValueSetMemberDecided|ValueSetMemberUndetermined
The result of validateCodeInValueSet: a decided membership or a typed undetermined.
Variables
COMPLEX_MAP_SOURCE_SYSTEM
constCOMPLEX_MAP_SOURCE_SYSTEM:"http://snomed.info/sct"=SNOMEDCT_SYSTEM
The SNOMED CT source-system URI a complex-map source concept is drawn from (re-exported for docs).
defaultStatusMapper
constdefaultStatusMapper:StatusMapper
The default raw-token → ConceptActivity mapping, case-insensitive.
Recognized (grounded in the format docs): ""/N/ACTIVE → active; DEPRECATED → deprecated;
DISCOURAGED; TRIAL; O/OBSOLETE → obsolete; Y/E/SUPPRESSED → suppressed. Anything else
→ unknown (surfaced with its raw token, never coerced to active).
Param
raw
The steward's raw status token.
Returns
The normalized activity.
Example
import { defaultStatusMapper } from "@cosyte/terminology";
defaultStatusMapper("DEPRECATED"); // => "deprecated"
defaultStatusMapper("N"); // => "active"
DIAGNOSTIC_CODES
constDIAGNOSTIC_CODES:object
Stable diagnostic codes: typed, surfaced, non-throwing outcomes.
These are not errors: they are first-class results a caller inspects (an unmapped translation,
an unrecognized code system). key === value so Object.values(...) yields the snapshot set.
Type Declaration
TERM_CODE_UNKNOWN
readonlyTERM_CODE_UNKNOWN:"TERM_CODE_UNKNOWN"="TERM_CODE_UNKNOWN"
A $lookup/$validate-code found no concept for the code in the loaded release. A first-class
typed outcome, never a guess: the engine returns unknown/valid: false, never a fabricated
display or a coerced valid: true (the never-fabricate invariant, applied to code identity).
TERM_COMPLEX_MAP_MALFORMED_ROW
readonlyTERM_COMPLEX_MAP_MALFORMED_ROW:"TERM_COMPLEX_MAP_MALFORMED_ROW"="TERM_COMPLEX_MAP_MALFORMED_ROW"
A SNOMED complex-map RF2 refset row was structurally unusable: missing its
referencedComponentId/mapGroup/mapPriority. Skipped and surfaced, never partial.
TERM_CONCEPT_DEPRECATED
readonlyTERM_CONCEPT_DEPRECATED:"TERM_CONCEPT_DEPRECATED"="TERM_CONCEPT_DEPRECATED"
A resolved concept is deprecated / no longer current (e.g. LOINC STATUS = DEPRECATED, or a
FHIR concept flagged inactive). Surfaced on the concept's status so a caller never presents a
non-current code as clean; the concept is still found (a lookup succeeds), it is just flagged.
TERM_CONCEPT_HEADER_NOT_BILLABLE
readonlyTERM_CONCEPT_HEADER_NOT_BILLABLE:"TERM_CONCEPT_HEADER_NOT_BILLABLE"="TERM_CONCEPT_HEADER_NOT_BILLABLE"
A resolved concept is a classification header, not a billable/valid leaf (e.g. an ICD-10-CM
order-file row with the position-15 flag 0). Surfaced on the concept's status: a header code is
found but is not valid for claim submission, and must never be presented as billable.
TERM_CROSSWALK_CONTEXT_REQUIRED
readonlyTERM_CROSSWALK_CONTEXT_REQUIRED:"TERM_CROSSWALK_CONTEXT_REQUIRED"="TERM_CROSSWALK_CONTEXT_REQUIRED"
A SNOMED→ICD-10-CM complex-map group's decision needs patient context (an IFA age band or
gender) the caller did not supply. The engine surfaces the candidate rules + advice and refuses
to pick a branch it lacks the data for: never a silently-chosen target.
TERM_CROSSWALK_NO_MAP
readonlyTERM_CROSSWALK_NO_MAP:"TERM_CROSSWALK_NO_MAP"="TERM_CROSSWALK_NO_MAP"
A crosswalk source code has an authored No-Map: the steward declares it has no valid target
in the other classification (a GEM NoDx/NoPCS sentinel, or a SNOMED complex-map 447638001
"cannot be classified" category). A first-class typed outcome, never an error and never a
guess (the never-fabricate invariant, applied to crosswalks). Distinct from
TERM_CROSSWALK_UNMAPPED: the source is in the map, and the map says "no target".
TERM_CROSSWALK_UNMAPPED
readonlyTERM_CROSSWALK_UNMAPPED:"TERM_CROSSWALK_UNMAPPED"="TERM_CROSSWALK_UNMAPPED"
A crosswalk source code is absent from the map entirely: not an authored No-Map, simply not present. Surfaced as a typed outcome (never a fabricated target, never a silent success), and kept distinct from TERM_CROSSWALK_NO_MAP so a caller can tell "the steward said no target" from "this code was not in the file".
TERM_CSV_MALFORMED
readonlyTERM_CSV_MALFORMED:"TERM_CSV_MALFORMED"="TERM_CSV_MALFORMED"
A CSV (RFC-4180, e.g. LOINC Loinc.csv) row was structurally unusable: too few fields to reach
a configured column. The row is skipped and surfaced as a load warning, never partial.
TERM_FHIR_CONCEPT_MALFORMED
readonlyTERM_FHIR_CONCEPT_MALFORMED:"TERM_FHIR_CONCEPT_MALFORMED"="TERM_FHIR_CONCEPT_MALFORMED"
A concept inside a FHIR CodeSystem resource was unusable: not an object, or missing its
required code. Skipped and surfaced (the whole resource still loads); line is 0 since a
JSON concept is not line-addressable.
TERM_FIXED_WIDTH_MALFORMED
readonlyTERM_FIXED_WIDTH_MALFORMED:"TERM_FIXED_WIDTH_MALFORMED"="TERM_FIXED_WIDTH_MALFORMED"
A fixed-width (e.g. ICD-10-CM order file) row was structurally unusable: too short to contain the configured code field, or a missing code. Skipped and surfaced, never partial.
TERM_GEM_MALFORMED_ROW
readonlyTERM_GEM_MALFORMED_ROW:"TERM_GEM_MALFORMED_ROW"="TERM_GEM_MALFORMED_ROW"
A GEM file line was structurally unusable: not three whitespace-delimited fields, or a flag field that is not a 5-digit code. The row is skipped and surfaced as a load warning (liberal on load), never kept as a partially-parsed entry.
TERM_RRF_MALFORMED_ROW
readonlyTERM_RRF_MALFORMED_ROW:"TERM_RRF_MALFORMED_ROW"="TERM_RRF_MALFORMED_ROW"
An RRF (pipe-delimited RxNorm/UMLS release) row was structurally unusable: too few columns to reach a configured field, or a missing code. The row is skipped and surfaced as a load warning (liberal on load), never kept as a partially-parsed concept.
TERM_RXNORM_MALFORMED_ROW
readonlyTERM_RXNORM_MALFORMED_ROW:"TERM_RXNORM_MALFORMED_ROW"="TERM_RXNORM_MALFORMED_ROW"
A RxNorm RRF row (RXNCONSO / RXNREL / RXNSAT) was structurally unusable: too few columns to
reach a required field, or a missing RXCUI/NDC value. The row is skipped and surfaced as a
load warning (liberal on load), never kept as a partial concept/edge. Rows that are simply not of
interest (a non-RXNORM atom, an atom-level relationship, a non-NDC attribute) are skipped
silently: they are expected, not faults.
TERM_RXNORM_NDC_UNMAPPED
readonlyTERM_RXNORM_NDC_UNMAPPED:"TERM_RXNORM_NDC_UNMAPPED"="TERM_RXNORM_NDC_UNMAPPED"
An NDC could not be resolved to any RXCUI in the loaded RxNorm release: a typed, surfaced
absence, never a guessed RXCUI. NDC↔RXCUI is many:1 and temporal, so a resolution
is always release-scoped; an NDC not present in the loaded release is this diagnostic.
TERM_RXNORM_UNKNOWN_RXCUI
readonlyTERM_RXNORM_UNKNOWN_RXCUI:"TERM_RXNORM_UNKNOWN_RXCUI"="TERM_RXNORM_UNKNOWN_RXCUI"
A RxNorm graph navigation was asked about an RXCUI absent from the loaded release: a
first-class typed outcome, never a fabricated concept and never an empty "success" (the
never-fabricate invariant, applied to the drug graph). Distinct from a present
concept that simply has no edge of the requested relationship (that is a found result with empty
targets).
TERM_RXNORM_UNTYPED_CONCEPT
readonlyTERM_RXNORM_UNTYPED_CONCEPT:"TERM_RXNORM_UNTYPED_CONCEPT"="TERM_RXNORM_UNTYPED_CONCEPT"
An RXCUI appeared in the release's SAB=RXNORM atoms but none of them could establish its
term type, so it is not in the graph. Either every atom carried a synonym-class TTY
(PSN/SY/TMSY, which Appendix 5 defines as a "synonym of another TTY" and which therefore
types a name rather than a concept) or every atom carried a TTY this engine does not model.
The concept is skipped rather than typed from a synonym atom: an absent concept is already a
first-class typed answer (TERM_RXNORM_UNKNOWN_RXCUI), while a concept whose term type reads
TMSY is a fabricated claim about what a drug is that a caller cannot detect.
TERM_SYSTEM_UNRECOGNIZED
readonlyTERM_SYSTEM_UNRECOGNIZED:"TERM_SYSTEM_UNRECOGNIZED"="TERM_SYSTEM_UNRECOGNIZED"
A code-system identifier (URI, OID, or mnemonic) was not recognized by the identity resolver.
Surfaced as a typed unknown, never coerced to a guessed canonical URI.
TERM_TRANSLATE_UNMAPPED
readonlyTERM_TRANSLATE_UNMAPPED:"TERM_TRANSLATE_UNMAPPED"="TERM_TRANSLATE_UNMAPPED"
A $translate found no target for the source code. A first-class outcome, never an error:
the source is surfaced as unmapped, never replaced with a guessed target (the never-fabricate
invariant).
TERM_UCUM_INVALID
readonlyTERM_UCUM_INVALID:"TERM_UCUM_INVALID"="TERM_UCUM_INVALID"
A UCUM unit expression is not valid: it does not parse against the UCUM grammar, or it
names an atom absent from the vendored UCUM table. A first-class typed outcome, never an
error and never a guess: validateUcum returns { valid: false, reason }, never a
coerced or "nearest" unit (the never-fabricate invariant, applied to units). The
reason is value-free (a grammar fault or an unknown-atom shape), never PHI.
TERM_VALUESET_CANNOT_EXPAND
readonlyTERM_VALUESET_CANNOT_EXPAND:"TERM_VALUESET_CANNOT_EXPAND"="TERM_VALUESET_CANNOT_EXPAND"
A ValueSet compose part could not be expanded: an intensional include/exclude whose
code system was not supplied, an unresolvable referenced value set, or a filter operator the
engine does not implement. Surfaced as a typed outcome that marks the expansion incomplete;
the engine never fabricates a member and never returns a silently-empty "no members"
answer for a part it could not compute (a false "not a member" is a clinical error).
TERM_VALUESET_EXPANSION_TRUNCATED
readonlyTERM_VALUESET_EXPANSION_TRUNCATED:"TERM_VALUESET_EXPANSION_TRUNCATED"="TERM_VALUESET_EXPANSION_TRUNCATED"
A pre-computed ValueSet.expansion is incomplete: its total exceeds the number of
contains entries, or it is flagged too-costly (the VSAC $expand >1200-code truncation
hazard). The engine never treats a truncated expansion as complete membership: a code
absent from a truncated expansion is undetermined, never a confident "not a member".
Example
import { DIAGNOSTIC_CODES } from "@cosyte/terminology";
DIAGNOSTIC_CODES.TERM_TRANSLATE_UNMAPPED; // => "TERM_TRANSLATE_UNMAPPED"
FATAL_CODES
constFATAL_CODES:object
Stable fatal codes: thrown (as a TerminologyError) when input cannot be loaded into
a usable model at all. Always thrown, never swallowed. key === value, part of the contract.
Type Declaration
TERM_CODESYSTEM_MALFORMED
readonlyTERM_CODESYSTEM_MALFORMED:"TERM_CODESYSTEM_MALFORMED"="TERM_CODESYSTEM_MALFORMED"
A CodeSystem source was structurally unusable: a FHIR resource with the wrong resourceType,
or a delimited source whose configured code/display column is absent from the header. Thrown
rather than silently loading an empty or mis-keyed release. (Malformed individual rows are
skipped-and-surfaced load warnings, not fatals: only an unusable source is fatal.)
TERM_CONCEPTMAP_MALFORMED
readonlyTERM_CONCEPTMAP_MALFORMED:"TERM_CONCEPTMAP_MALFORMED"="TERM_CONCEPTMAP_MALFORMED"
A ConceptMap resource was structurally unusable: wrong resourceType, or a group/element
missing a required field. Thrown rather than silently loading a partial, misleading map.
TERM_CROSSWALK_MALFORMED
readonlyTERM_CROSSWALK_MALFORMED:"TERM_CROSSWALK_MALFORMED"="TERM_CROSSWALK_MALFORMED"
A crosswalk map source was structurally unusable: e.g. a SNOMED complex-map RF2 refset with empty content or a header missing a required column. Thrown rather than silently loading an empty or mis-keyed map. (Malformed individual rows are skipped-and-surfaced warnings, not fatals.)
TERM_MAP_NOT_INVERTIBLE
readonlyTERM_MAP_NOT_INVERTIBLE:"TERM_MAP_NOT_INVERTIBLE"="TERM_MAP_NOT_INVERTIBLE"
An inversion of a directional crosswalk was requested: a forbidden operation. The GEMs and the SNOMED→ICD-10-CM map are authoritative in one direction only; a forward map is not the inverse of the backward map. Thrown by ../crosswalk/gems.invertGem so the never-invert refusal is a first-class, discoverable contract rather than a silent absence.
TERM_VALUESET_MALFORMED
readonlyTERM_VALUESET_MALFORMED:"TERM_VALUESET_MALFORMED"="TERM_VALUESET_MALFORMED"
A ValueSet resource was structurally unusable: wrong resourceType, or a compose/expansion
whose required shape (an include that is not an object, a contains entry missing its code)
is corrupt. Thrown rather than silently loading a partial value set that would bind some codes
and quietly drop others. (A filter operator the engine does not implement is not fatal; it
is the surfaced TERM_VALUESET_CANNOT_EXPAND diagnostic at expansion time.)
Example
import { FATAL_CODES } from "@cosyte/terminology";
FATAL_CODES.TERM_CONCEPTMAP_MALFORMED; // => "TERM_CONCEPTMAP_MALFORMED"
HL7_V2_OID_ROOT
constHL7_V2_OID_ROOT:"2.16.840.1.113883.12"="2.16.840.1.113883.12"
The OID root under which every HL7 v2 table code system is registered:
2.16.840.1.113883.12.[table]: grounded against the FHIR R4 terminology-systems registry.
The table number is appended with no leading zeros (e.g. table 0203 → …12.203).
HL7_V2_URL_PREFIX
constHL7_V2_URL_PREFIX:"http://terminology.hl7.org/CodeSystem/v2-"="http://terminology.hl7.org/CodeSystem/v2-"
The canonical URI prefix for HL7 v2 table code systems in HL7 Terminology (THO):
http://terminology.hl7.org/CodeSystem/v2-[XXXX], where [XXXX] is the zero-padded 4-digit
table id: grounded against the FHIR R4 terminology-systems registry.
ICD10CM_ORDER_FILE_FIELDS
constICD10CM_ORDER_FILE_FIELDS:FixedWidthFieldMap
The documented ICD-10-CM order file field layout (0-based char indices).
code: the ICD-10-CM code (no decimal point).billable, position-15 flag at index 14:"1"= billable/valid leaf,"0"= header.display: the long description (to end of line).- property
shortDescription: the 60-char short description.
Grounded on the CMS/CDC order-file layout; verify against your release's README before relying on the exact offsets, which are not confirmed against an authoritative machine-readable source. The reader takes the layout as a parameter precisely so this preset is a starting point, not a hardcoded assumption.
ICD10CM_SYSTEM
constICD10CM_SYSTEM:"http://hl7.org/fhir/sid/icd-10-cm"="http://hl7.org/fhir/sid/icd-10-cm"
The canonical code-system URI for ICD-10-CM: the target system of both crosswalks. A published identity fact (mirrors ../systems/registry.SYSTEM_IDENTITIES); attached to a resolved target ../common/coding.Coding so a translation is self-describing.
ICD9CM_SYSTEM
constICD9CM_SYSTEM:"http://hl7.org/fhir/sid/icd-9-cm"="http://hl7.org/fhir/sid/icd-9-cm"
The canonical code-system URI for ICD-9-CM (the legacy diagnosis classification the GEMs bridge to/from). A published identity fact; attached to a GEM target/source coding.
MAP_CATEGORIES
constMAP_CATEGORIES:object
The SNOMED CT complex-map map category concept ids: the mapCategoryId column of the
SNOMED→ICD-10-CM extended-map refset. These four SNOMED CT concepts (id and steward description)
are bundled in this package (SNOMED CT is copyright © International Health Terminology
Standards Development Organisation); carried through a resolution verbatim so a caller sees the
steward's own trust signal.
Type Declaration
AMBIGUOUS
readonlyAMBIGUOUS:"447640006"="447640006"
447640006: "Source concept is ambiguous" (surface candidates, never pick one).
CONTEXT_DEPENDENT
readonlyCONTEXT_DEPENDENT:"447639009"="447639009"
447639009: "Map of source concept is context dependent" (needs runtime patient context).
NO_MAP
readonlyNO_MAP:"447638001"="447638001"
447638001: "Map source concept cannot be classified with available data" (a No-Map).
PROPERLY_CLASSIFIED
readonlyPROPERLY_CLASSIFIED:"447637006"="447637006"
447637006: "Map source concept is properly classified" (a normal, usable target).
Example
import { MAP_CATEGORIES } from "@cosyte/terminology";
MAP_CATEGORIES.NO_MAP; // => "447638001"
NO_MAP_CATEGORIES
constNO_MAP_CATEGORIES:ReadonlySet<string>
The set of MAP_CATEGORIES ids the resolver treats as a No-Map (a typed, surfaced "cannot be classified", never a fabricated target).
RELA
constRELA:object
The drug-graph RELA relationship names, grounded on the NLM RxNorm Technical Documentation
(Appendix 1). Each is directional and read subject ⟶RELA⟶ object after normalization (see the
module doc). RxNorm ships both members of an inverse pair as separate rows, so the graph
traverses the authored predicate for the direction it wants: it never synthesizes an inverse.
Type Declaration
CONSISTS_OF
readonlyCONSISTS_OF:"consists_of"="consists_of"
consists_of: subject (an SCD/SBD) consists of object (its SCDC/SBDC component(s)).
CONSTITUTES
readonlyCONSTITUTES:"constitutes"="constitutes"
constitutes: subject (a component) constitutes object (the drug). Inverse of consists_of.
CONTAINED_IN
readonlyCONTAINED_IN:"contained_in"="contained_in"
contained_in: subject (a drug) is contained in object (a pack). Inverse of contains.
CONTAINS
readonlyCONTAINS:"contains"="contains"
contains: subject (a pack) contains object (a member drug).
DOSE_FORM_GROUP_OF
readonlyDOSE_FORM_GROUP_OF:"doseformgroup_of"="doseformgroup_of"
doseformgroup_of: inverse of has_doseformgroup.
DOSE_FORM_OF
readonlyDOSE_FORM_OF:"dose_form_of"="dose_form_of"
dose_form_of: subject (a DF) is the dose form of object (a drug).
HAS_DOSE_FORM
readonlyHAS_DOSE_FORM:"has_dose_form"="has_dose_form"
has_dose_form: subject (a drug) has dose form object (a DF).
HAS_DOSE_FORM_GROUP
readonlyHAS_DOSE_FORM_GROUP:"has_doseformgroup"="has_doseformgroup"
has_doseformgroup: subject has dose-form group object (a DFG).
HAS_INGREDIENT
readonlyHAS_INGREDIENT:"has_ingredient"="has_ingredient"
has_ingredient: subject has ingredient object. Authored from the clinical side
(SCDC/SCDF/SCDG) to an IN and from the branded side (SBD/SBDC/SBDF/SBDG) to a
BN; RxNorm authors no SCD ⟶ IN row.
HAS_PRECISE_INGREDIENT
readonlyHAS_PRECISE_INGREDIENT:"has_precise_ingredient"="has_precise_ingredient"
has_precise_ingredient: subject has precise ingredient object (a PIN).
HAS_QUANTIFIED_FORM
readonlyHAS_QUANTIFIED_FORM:"has_quantified_form"="has_quantified_form"
has_quantified_form: subject has quantified form object.
HAS_TRADENAME
readonlyHAS_TRADENAME:"has_tradename"="has_tradename"
has_tradename: subject (a generic concept) has tradename object (a branded concept).
INGREDIENT_OF
readonlyINGREDIENT_OF:"ingredient_of"="ingredient_of"
ingredient_of: subject is an ingredient of object. The authored inverse, so an IN reaches
clinical components and dose forms and a BN reaches branded concepts (the SBD included).
Neither reaches an SCD.
INVERSE_ISA
readonlyINVERSE_ISA:"inverse_isa"="inverse_isa"
inverse_isa: subject is a parent of object. Inverse of isa.
ISA
readonlyISA:"isa"="isa"
isa: subject is a object (hierarchical, e.g. SCD isa SCDG).
PRECISE_INGREDIENT_OF
readonlyPRECISE_INGREDIENT_OF:"precise_ingredient_of"="precise_ingredient_of"
precise_ingredient_of: inverse of has_precise_ingredient.
QUANTIFIED_FORM_OF
readonlyQUANTIFIED_FORM_OF:"quantified_form_of"="quantified_form_of"
quantified_form_of: inverse of has_quantified_form.
TRADENAME_OF
readonlyTRADENAME_OF:"tradename_of"="tradename_of"
tradename_of: subject (a branded concept) is a tradename of object (its generic).
Example
import { RELA } from "@cosyte/terminology";
RELA.HAS_INGREDIENT; // => "has_ingredient"
RELA_INVERSE
constRELA_INVERSE:Readonly<Record<string,string>>
The authored inverse pairs of the drug-graph RELAs: a published fact (RxNorm Appendix 1),
used only to document and validate that a caller is traversing a real relationship. The graph
never uses this to synthesize a missing edge: RxNorm ships both directions, so
../rxnorm/navigate follows whichever authored predicate points the way it wants to go.
Example
import { RELA_INVERSE, RELA } from "@cosyte/terminology";
RELA_INVERSE[RELA.HAS_INGREDIENT]; // => "ingredient_of"
RXNORM_SYSTEM
constRXNORM_SYSTEM:"http://www.nlm.nih.gov/research/umls/rxnorm"="http://www.nlm.nih.gov/research/umls/rxnorm"
The canonical code-system URI for RxNorm: a published identity fact, attached to graph codings.
SNOMEDCT_SYSTEM
constSNOMEDCT_SYSTEM:"http://snomed.info/sct"="http://snomed.info/sct"
The canonical code-system URI for SNOMED CT: the source system of the SNOMED→ICD-10-CM complex map. Recognised by URI only; no SNOMED CT refset or release is bundled.
SYSTEM_IDENTITIES
constSYSTEM_IDENTITIES: readonlySystemIdentity[]
The seed identity table. Order is irrelevant; lookup indexes are built from it in ../systems/resolve. Each entry is one firsthand-grounded system (see the module doc).
TERM_TYPES
constTERM_TYPES:Readonly<Record<TermType,string>>
The drug-graph term types (RXNCONSO.TTY), each mapped to its verbatim Appendix 5 name (ET
excepted: the appendix publishes no Name for it, so the UMLS expansion "Entry Term" is used).
Encoded as an identity fact; a concept's TTY is carried verbatim on its
../rxnorm/types.RxNormConcept, never re-labeled.
The keys are the full Appendix 5 vocabulary, defining and synonym alike. Only the defining ones can appear on a loaded concept (see isSynonymTermType).
Example
import { TERM_TYPES } from "@cosyte/terminology";
TERM_TYPES.SCD; // => "Semantic Clinical Drug"
TERM_TYPES.SCDF; // => "Semantic Clinical Drug Form"
VERSION
constVERSION:string="0.0.13"
Library version string, kept in lockstep with package.json#version.
Changesets owns the bump and rewrites package.json only, so the release version script runs
scripts/sync-version.mjs to rewrite this declaration in the same commit, and
test/sanity.test.ts compares the two so a skipped sync goes red instead of shipping a version
string that lies. That is not hypothetical: 0.0.1 went to the registry exporting "0.0.0".
Example
import { VERSION } from "@cosyte/terminology";
typeof VERSION; // => "string"
Functions
applyComplexMap()
applyComplexMap(
map,source,context?):ComplexMapApplyResult
Apply a loaded SNOMED→ICD-10-CM complex map to a source concept and patient context.
Resolves each map group independently (groups are an AND, a source needing multiple ICD-10-CM
codes has multiple groups) by running its rules in priority order against context. A group whose
decision needs IFA context the caller did not supply is a typed
ComplexMapContextRequired; a 447638001 row is a typed No-Map; every result carries the
steward's advice verbatim. Never fabricates a target, never inverts the map.
Parameters
map
A ComplexMap from loadComplexMap.
source
string
The SNOMED CT source concept id.
context?
PatientContext = {}
The caller-supplied PatientContext (age / gender). Optional; a missing
field that a rule needs yields a context-required group, never a guessed branch.
Returns
A ComplexMapApplyResult: per-group resolutions, or a typed absence.
Example
import { loadComplexMap, applyComplexMap } from "@cosyte/terminology";
const map = loadComplexMap({
format: "rows",
rows: [
{ source: "72098002", group: 1, priority: 1, rule: "IFA 248152002 | Female (finding) |", advice: "MAP IS CONTEXT DEPENDENT FOR GENDER", target: "O00.9", category: "447639009" },
{ source: "72098002", group: 1, priority: 2, rule: "OTHERWISE TRUE", advice: "CANNOT BE CLASSIFIED", category: "447638001" },
],
});
const r = applyComplexMap(map, "72098002", { gender: "female" });
r.mapped; // => true
applyGem()
applyGem(
map,source):GemApplyResult
Apply a loaded GEM map to a source code, in the map's authored direction only.
Returns the full candidate set (never collapsed to one), with each entry's steward flags; a
combination source additionally surfaces its scenario/choice-list structure. A source the steward
marked No-Map (NoDx sentinel) is a typed CrosswalkNoMap; a source absent from the map
is a typed CrosswalkUnmapped: the two are distinct, and neither is ever a fabricated code.
Parameters
map
source
string
The source code (in the map's source classification).
Returns
Example
import { loadGems, applyGem } from "@cosyte/terminology";
const gems = loadGems({ direction: "9-to-10", content: "V290 NoDx 11000\n" });
const r = applyGem(gems, "V290");
r.mapped; // => false
approximateMatch()
approximateMatch(
graph,query,options?): readonlyRxNormApproximateMatch[]
Opt-in, explicitly labeled approximate name matching: find loaded concepts whose
names are token-similar to query. This is never the default resolution path and its results
are never an exact code assertion: every candidate is marked approximate: true with a derived
RxNormApproximateMatch.score. A caller opts in by calling this function explicitly.
Coverage is not correctness: a "no match" is an empty array (typed, honest), distinct from a fabricated nearest guess. The engine never promotes an approximate hit to an exact one.
Parameters
graph
A loaded RxNormGraph.
query
string
A free-text drug name to match against loaded concept names.
options?
ApproximateMatchOptions (min score, limit).
Returns
readonly RxNormApproximateMatch[]
The labeled approximate candidates, best-first (possibly empty). Never an exact resolution.
Example
import { loadRxNormGraph, approximateMatch } from "@cosyte/terminology";
const g = loadRxNormGraph({
conso: "1|ENG||||||||||RXNORM|IN||lisinopril||N||",
rel: "",
});
approximateMatch(g, "lisinopril")[0]?.approximate; // => true
asTermType()
asTermType(
tty):TermType|undefined
Narrow a raw RXNCONSO.TTY string to a known TermType, or undefined when it is not a
drug-graph term type this engine models (the atom is then skipped at load, liberal-on-load, never
coerced to a wrong type).
Parameters
tty
string
The raw TTY value from an RXNCONSO row.
Returns
TermType | undefined
The narrowed TermType, or undefined when unrecognized.
Example
import { asTermType } from "@cosyte/terminology";
asTermType("SCD"); // => "SCD"
asTermType("ZZZ"); // => undefined
brandsFor()
brandsFor(
graph,rxcui):RxNormNavResult
The branded form(s) of a generic concept: an SCD/IN/GPCK that has_tradename a brand.
The authored forward edge; not a synthesized inverse of tradename_of.
Parameters
graph
A loaded RxNormGraph.
rxcui
string
The generic concept.
Returns
The branded concept(s) (possibly empty), or a typed unknown source.
Example
import { loadRxNormGraph, brandsFor } from "@cosyte/terminology";
const g = loadRxNormGraph({
conso: "1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\n2|ENG||||||||||RXNORM|SBD||lisinopril 10 MG Oral Tablet [Zestril]||N||",
rel: "2|||RN|1|||has_tradename|||RXNORM||||||",
});
brandsFor(g, "1").found; // => true
buildSubsumption()
buildSubsumption(
cs):Subsumption
Build a cycle-safe ancestor index from a loaded CodeSystem's parent concept-properties.
Parameters
cs
The loaded code system.
Returns
A Subsumption answering transitive-ancestor queries.
Example
import { loadCodeSystem, buildSubsumption } from "@cosyte/terminology";
const cs = loadCodeSystem({
format: "fhir",
resource: { resourceType: "CodeSystem", concept: [{ code: "p", concept: [{ code: "c" }] }] },
});
buildSubsumption(cs).ancestorsOf("c").has("p"); // => true
codeableConcept()
codeableConcept(
init):CodeableConcept
Construct a deep-frozen CodeableConcept (its coding array and every member frozen).
Parameters
init
The concept fields; coding is required (may be empty).
Returns
A frozen CodeableConcept.
Example
import { codeableConcept } from "@cosyte/terminology";
const cc = codeableConcept({ coding: [{ code: "2160-0" }] });
Object.isFrozen(cc.coding); // => true
coding()
coding(
init):Coding
Construct a deep-frozen Coding.
The returned object is Object.freezed so it cannot be mutated in place: parsed/translated
values are immutable by default. Optional fields are only present when supplied (no undefined
keys), so structural equality checks stay clean.
Parameters
init
The coding fields; code is required.
Returns
A frozen Coding.
Example
import { coding } from "@cosyte/terminology";
const frozen = coding({ system: "http://loinc.org", code: "2160-0" });
Object.isFrozen(frozen); // => true
consistsOf()
consistsOf(
graph,rxcui):RxNormNavResult
The components a drug consists_of: an SCD/SBD → its SCDC/SBDC dose-form components.
Parameters
graph
A loaded RxNormGraph.
rxcui
string
The drug concept.
Returns
The component concept(s) (possibly empty), or a typed unknown source.
Example
import { loadRxNormGraph, consistsOf } from "@cosyte/terminology";
const g = loadRxNormGraph({
conso: "2|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\n3|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||",
rel: "3|||RN|2|||consists_of|||RXNORM||||||",
});
consistsOf(g, "2").found; // => true
doseFormsOf()
doseFormsOf(
graph,rxcui):RxNormNavResult
The dose form(s) of a drug: the DF/DFG concepts it has_dose_form / has_doseformgroup.
Parameters
graph
A loaded RxNormGraph.
rxcui
string
The drug concept.
Returns
The dose-form concept(s) (possibly empty), or a typed unknown source.
Example
import { loadRxNormGraph, doseFormsOf } from "@cosyte/terminology";
const g = loadRxNormGraph({
conso: "1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\n9|ENG||||||||||RXNORM|DF||Oral Tablet||N||",
rel: "9|||RN|1|||has_dose_form|||RXNORM||||||",
});
doseFormsOf(g, "1").found; // => true
expand()
expand(
vs,ctx?):ExpandResult
$expand: compute the flattened membership of a ValueSet over the supplied code systems.
Parameters
vs
The loaded value set.
ctx?
ExpansionContext = {}
The loaded code systems / referenced value sets the intensional parts resolve against.
Returns
An ExpandResult: the contains members plus an honest complete flag. When
complete is false, contains is a lower bound (never treat it as exhaustive membership).
Example
import { loadValueSet, loadCodeSystem, expand } from "@cosyte/terminology";
const cs = loadCodeSystem({
format: "fhir",
resource: {
resourceType: "CodeSystem",
url: "http://example.org/cs",
concept: [{ code: "a" }, { code: "b" }, { code: "c" }],
},
});
const vs = loadValueSet({
resourceType: "ValueSet",
compose: { include: [{ system: "http://example.org/cs", concept: [{ code: "a" }, { code: "b" }] }] },
});
const result = expand(vs, { codeSystems: new Map([["http://example.org/cs", cs]]) });
result.complete; // => true
result.contains.length; // => 2
genericFor()
genericFor(
graph,rxcui):RxNormNavResult
The generic form(s) of a branded concept: an SBD/BN/BPCK tradename_of its generic. The
authored forward edge; the engine never inverts a has_tradename edge to synthesize this.
Parameters
graph
A loaded RxNormGraph.
rxcui
string
The branded concept.
Returns
The generic concept(s) (possibly empty), or a typed unknown source.
Example
import { loadRxNormGraph, genericFor } from "@cosyte/terminology";
// "SBD(2) tradename_of SCD(1)": subject=RXCUI2=2, object=RXCUI1=1.
const g = loadRxNormGraph({
conso: "1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\n2|ENG||||||||||RXNORM|SBD||lisinopril 10 MG Oral Tablet [Zestril]||N||",
rel: "1|||RN|2|||tradename_of|||RXNORM||||||",
});
genericFor(g, "2").found; // => true
getArray()
getArray(
obj,key): readonlyunknown[] |undefined
Read an array property from an untrusted object as a readonly unknown[], or undefined.
The elements are left as unknown: callers narrow each one. A non-array (including a missing
key) yields undefined, which callers treat as "no entries" rather than an error.
Parameters
obj
unknown
The source object (may be any unknown).
key
string
The property name to read.
Returns
readonly unknown[] | undefined
The array (elements untyped), or undefined when the key is missing or not an array.
Example
import { getArray } from "@cosyte/terminology";
getArray({ group: [{ source: "a" }] }, "group")?.length; // => 1
getBoolean()
getBoolean(
obj,key):boolean|undefined
Read a boolean property from an untrusted object, or undefined if absent/not a boolean.
A non-boolean (including a missing key, or the strings "true"/"false") yields undefined:
the accessor never coerces, so a caller can distinguish "explicitly false" from "absent".
Parameters
obj
unknown
The source object (may be any unknown).
key
string
The property name to read.
Returns
boolean | undefined
The boolean value, or undefined when the key is missing or not a boolean.
Example
import { getBoolean } from "@cosyte/terminology";
getBoolean({ inactive: true }, "inactive"); // => true
getConcept()
getConcept(
graph,rxcui):RxNormConcept|undefined
Look up a single concept by RXCUI.
Parameters
graph
A loaded RxNormGraph.
rxcui
string
The concept unique identifier.
Returns
RxNormConcept | undefined
The RxNormConcept, or undefined when the RXCUI is not in the release.
Example
import { loadRxNormGraph, getConcept } from "@cosyte/terminology";
const g = loadRxNormGraph({ conso: "1|ENG||||||||||RXNORM|IN||aspirin||N||", rel: "" });
getConcept(g, "1")?.tty; // => "IN"
getNumber()
getNumber(
obj,key):number|undefined
Read a number property from an untrusted object, or undefined if absent/not a finite number.
Parameters
obj
unknown
The source object (may be any unknown).
key
string
The property name to read.
Returns
number | undefined
The number value, or undefined when the key is missing or not a finite number.
Example
import { getNumber } from "@cosyte/terminology";
getNumber({ valueInteger: 3 }, "valueInteger"); // => 3
getString()
getString(
obj,key):string|undefined
Read a string property from an untrusted object, or undefined if absent/not a string.
Parameters
obj
unknown
The source object (may be any unknown).
key
string
The property name to read.
Returns
string | undefined
The string value, or undefined when the key is missing or not a string.
Example
import { getString } from "@cosyte/terminology";
getString({ url: "http://loinc.org" }, "url"); // => "http://loinc.org"
ingredientsOf()
ingredientsOf(
graph,rxcui):RxNormNavResult
The ingredients of a concept: the concepts it links to by a direct has_ingredient /
has_precise_ingredient edge in the loaded release.
This follows the authored, direct edge only (never-fabricate, never a synthesized path), and
RxNorm's ingredient topology is not the obvious one. Always read the TTY of what comes back:
- concepts on the clinical side (
SCDC,SCDF,SCDG) link to the ingredient itself, anIN; - concepts on the branded side (
SBD,SBDC,SBDF,SBDG) link to their brand name, aBN. That is what the release says and what is echoed back, term type included. It is not the active ingredient. (has_precise_ingredient, which this function also follows, likewise reaches aPIN.) - a clinical drug (
SCD) carries nohas_ingredientedge at all. RxNorm authors none, in any release, so this honestly returns found-with-empty-targets rather than walking a path on the caller's behalf. - the precise forms (
SCDFP,SBDFP,SCDGP) carry neither edge, so this returns found-with-empty-targets for them too. They do not behave like their non-precise siblings: anSCDFPreaches its basis-of-strength substance(s) byhas_boss, a one-to-many relation with a different meaning whose targets can be aPINor a plainIN, and which this function deliberately does not follow; anSBDFPand anSCDGPauthor no ingredient-bearing edge at all and are reached instead throughform_of/tradename_of/isa.
Those pairings are the ones RxNorm authors, not a closed set a caller may rely on: check the
returned TTY rather than assuming it from the one you queried.
To reach an active ingredient, walk to the CLINICAL component and take its edge. From an SCD
that is SCD ⟶consists_of⟶ SCDC ⟶has_ingredient⟶ IN, i.e. consistsOf then
ingredientsOf. From an SBD it needs one more decision, because consists_of returns both
its branded component (SBDC, whose own ingredient edge is the BN again) and the clinical
SCDC: it is the SCDC that leads to the IN. The engine never invents the transitive edge and
never picks that branch for you.
Parameters
graph
A loaded RxNormGraph.
rxcui
string
The concept (a drug or a clinical/branded component).
Returns
The directly-linked ingredient concepts (possibly empty), or a typed unknown source.
Example
import { loadRxNormGraph, ingredientsOf } from "@cosyte/terminology";
// The ingredient edge is authored on the COMPONENT, not on the clinical drug.
const g = loadRxNormGraph({
conso: "1|ENG||||||||||RXNORM|IN||lisinopril||N||\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||",
rel: "1|||RN|2|||has_ingredient|||RXNORM||||||",
});
ingredientsOf(g, "2").found; // => true
invertGem()
invertGem(
map):never
Refuse to invert a directional GEM map. Always throws FATAL_CODES.TERM_MAP_NOT_INVERTIBLE.
The never-invert invariant made explicit and discoverable: a forward GEM (9→10) is not the inverse of the backward GEM (10→9): CMS ships them as separate artifacts and "forward and backward mappings are not simply the reverse". To resolve the other direction, load the other file with loadGems; the engine never synthesizes an inverse.
Parameters
map
The map an inversion was (incorrectly) requested for.
Returns
never
Never: always throws.
Throws
TERM_MAP_NOT_INVERTIBLE, always.
Example
import { loadGems, invertGem } from "@cosyte/terminology";
const gems = loadGems({ direction: "9-to-10", content: "0010 A000 00000\n" });
invertGem(gems); // throws TERM_MAP_NOT_INVERTIBLE
isA()
isA(
sub,code,anchor):boolean
True when code is-a anchor: the same code, or a (transitive) descendant of it.
Parameters
sub
The subsumption index (from buildSubsumption).
code
string
The candidate code.
anchor
string
The ancestor code to test against.
Returns
boolean
Whether code is anchor or a descendant of it.
Example
import { loadCodeSystem, buildSubsumption, isA } from "@cosyte/terminology";
const cs = loadCodeSystem({
format: "fhir",
resource: { resourceType: "CodeSystem", concept: [{ code: "p", concept: [{ code: "c" }] }] },
});
isA(buildSubsumption(cs), "c", "p"); // => true
isJsonObject()
isJsonObject(
value):value is Record<string, unknown>
Narrow an unknown to a plain JSON object (a non-null, non-array object).
Parameters
value
unknown
The value to test.
Returns
value is Record<string, unknown>
true when value is a non-null, non-array object.
Example
import { isJsonObject } from "@cosyte/terminology";
isJsonObject({ resourceType: "ConceptMap" }); // => true
isSynonymTermType()
isSynonymTermType(
tty):boolean
Is this term type a synonym-class one (PSN / SY / TMSY)?
Appendix 5 defines each as a "synonym of another TTY": it labels an alternate name for a
concept, never the concept's own kind. So a synonym atom can never establish an RXCUI's term
type, and ../rxnorm/load.loadRxNormGraph will not let one: an RXCUI whose release
supplies only synonym atoms is skipped and surfaced, never typed "TMSY".
Parameters
tty
A TermType.
Returns
boolean
true for PSN / SY / TMSY; false for every defining term type.
Example
import { isSynonymTermType } from "@cosyte/terminology";
isSynonymTermType("TMSY"); // => true
isSynonymTermType("SCDF"); // => false
isUnknownSystem()
isUnknownSystem(
result):result is UnknownSystem
Type guard: did resolveSystem fail to recognize the identifier?
Parameters
result
A resolveSystem result.
Returns
result is UnknownSystem
true when the result is a typed UnknownSystem.
Example
import { resolveSystem, isUnknownSystem } from "@cosyte/terminology";
isUnknownSystem(resolveSystem("nope")); // => true
loadCodeSystem()
loadCodeSystem(
source):CodeSystem
Load a consumer-supplied code-system release into an immutable, queryable CodeSystem.
Dispatches on source.format:
"rrf": pipe-delimited RxNorm/UMLS release (one parameterized reader for both)."csv": RFC-4180 CSV (e.g. LOINCLoinc.csv), with real quote handling."fixed-width": slice-by-column order files (e.g. ICD-10-CM; seeICD10CM_ORDER_FILE_FIELDS)."fhir": a native FHIR R4CodeSystemJSON resource.
Liberal on load: a malformed row is skipped and surfaced in warnings (never a crash, never a
partial concept). Conservative on structure: an unusable source (wrong FHIR resourceType, or
a CSV whose configured columns are absent from the header) throws a typed TerminologyError
carrying TERM_CODESYSTEM_MALFORMED.
Parameters
source
The release descriptor (a discriminated CodeSystemSource).
Returns
The immutable, deep-frozen CodeSystem.
Throws
TERM_CODESYSTEM_MALFORMED when the source is structurally unusable.
Example
import { loadCodeSystem } from "@cosyte/terminology";
const cs = loadCodeSystem({
format: "fhir",
resource: {
resourceType: "CodeSystem",
url: "http://example.org/cs",
concept: [{ code: "A", display: "Alpha" }],
},
});
cs.count; // => 1
loadComplexMap()
loadComplexMap(
input):ComplexMap
Load a SNOMED→ICD-10-CM complex map from caller-supplied rows or a raw RF2 refset into an immutable ComplexMap, keyed by source concept and ordered by (group, priority).
Liberal on load: a structurally unusable RF2 row is skipped and surfaced as a warning; only an unusable source (empty content, header missing required columns) is a fatal FATAL_CODES.TERM_CROSSWALK_MALFORMED. Ships no SNOMED CT release or refset: the rows are the caller's, under their own licence.
Parameters
input
Structured rows, or a raw RF2 extended-map refset content.
Returns
The immutable ComplexMap.
Throws
TERM_CROSSWALK_MALFORMED when the source is structurally unusable.
Example
import { loadComplexMap } from "@cosyte/terminology";
const map = loadComplexMap({
format: "rows",
rows: [
{ source: "195967001", group: 1, priority: 1, rule: "TRUE", advice: "ALWAYS J45.909", target: "J45.909", category: "447637006" },
],
});
map.count; // => 1
loadConceptMap()
loadConceptMap(
json):ConceptMap
Load an untrusted FHIR R4 ConceptMap JSON value into an immutable ConceptMap.
Accepts the standard resource shape: a top-level object with resourceType: "ConceptMap" and an
optional group[]. source[x]/target[x] scopes are read from either the Uri or Canonical
variant. The result is deep-frozen. Anything structurally unusable throws a
TerminologyError carrying FATAL_CODES.TERM_CONCEPTMAP_MALFORMED.
Parameters
json
unknown
The untrusted resource (typically JSON.parse output, hence unknown).
Returns
The immutable, validated ConceptMap.
Throws
TERM_CONCEPTMAP_MALFORMED when the resource is not a usable ConceptMap.
Example
import { loadConceptMap } from "@cosyte/terminology";
const map = loadConceptMap({
resourceType: "ConceptMap",
url: "http://example.org/cm/gender",
group: [
{
source: "http://hl7.org/fhir/administrative-gender",
target: "http://terminology.hl7.org/CodeSystem/v2-0001",
element: [{ code: "male", target: [{ code: "M", equivalence: "equivalent" }] }],
},
],
});
map.group.length; // => 1
loadGems()
loadGems(
source):GemMap
Load a CMS GEM file into an immutable GemMap, keyed by source code.
Liberal on load: a structurally unusable line (not three whitespace-delimited fields, or a malformed 5-digit flag) is skipped and surfaced as a GemLoadWarning, never a partially-parsed entry. An unusable source is not possible here (an all-malformed file loads to an empty map with warnings): there is no fatal for GEM load. Ships no GEM content: the entries are the caller's public-domain file.
Parameters
source
The GemSource (raw content + direction + version).
Returns
The immutable GemMap.
Example
import { loadGems, applyGem } from "@cosyte/terminology";
// Synthetic rows in the CMS GEM format (source target flags): an exact map and a No-Map.
const gems = loadGems({
direction: "9-to-10",
version: "2018",
content: "0010 A000 00000\nV290 NoDx 11000\n",
});
applyGem(gems, "0010").mapped; // => true
loadRxNormGraph()
loadRxNormGraph(
source):RxNormGraph
Load a caller-supplied RxNorm RRF release into an immutable RxNormGraph.
Parses RXNCONSO (concepts), RXNREL (directed edges, normalized to the documented direction), and
(when supplied) RXNSAT (NDC attributes). Liberal on load: a structurally unusable row is a
skipped, surfaced RxNormLoadWarning, never partial. Ships no RxNorm release: the graph
is entirely the caller's release.
A concept is typed only by a defining atom, never by a synonym-class one and never by file
order; an RXCUI no defining atom could type is skipped and surfaced as
TERM_RXNORM_UNTYPED_CONCEPT. See the module documentation.
Parameters
source
The RxNormGraphSource (RRF file contents + optional version).
Returns
The immutable RxNormGraph.
Example
import { loadRxNormGraph } from "@cosyte/terminology";
// Synthetic rows in the RxNorm RRF wire format (no RxNorm release is bundled).
const graph = loadRxNormGraph({
conso: "1|ENG||||||||||RXNORM|IN||lisinopril||N||\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||",
// "SCDC(2) has_ingredient IN(1)": subject=RXCUI2=2, object=RXCUI1=1.
rel: "1|||RN|2|||has_ingredient|||RXNORM||||||",
});
graph.conceptCount; // => 2
loadUcumEssence()
loadUcumEssence():
UcumEssence
Load the UCUM essence table, parsing the embedded verbatim XML on first call and caching it.
One table is shared by every caller and by the engine itself, so it is handed out frozen: an
atom's definition cannot be rewritten in place, and neither can the atoms array the parser
scans. It used to be, and doing so before that atom's first reduction poisoned the
reduction memo for the life of the process: a fabricated unit equivalence that survived putting
the table back. A write is refused, which in strict mode means a TypeError.
Returns
The shared, frozen in-memory UcumEssence model.
Example
import { loadUcumEssence } from "@cosyte/terminology";
const essence = loadUcumEssence();
essence.atomByCode.has("m"); // => true
loadValueSet()
loadValueSet(
json):ValueSet
Load an untrusted FHIR R4 ValueSet JSON value into an immutable ValueSet.
Accepts the standard resource shape: resourceType: "ValueSet" with an optional intensional
compose (include/exclude of system/concept/filter/valueSet) and/or a pre-computed
expansion (contains, with total and the valueset-toocostly extension read into a derived
truncated flag). The result is deep-frozen. Anything structurally unusable throws a
TerminologyError carrying FATAL_CODES.TERM_VALUESET_MALFORMED.
Parameters
json
unknown
The untrusted resource (typically JSON.parse output, hence unknown).
Returns
The immutable, validated ValueSet.
Throws
TERM_VALUESET_MALFORMED when the resource is not a usable ValueSet.
Example
import { loadValueSet } from "@cosyte/terminology";
const vs = loadValueSet({
resourceType: "ValueSet",
url: "http://example.org/vs/colors",
compose: {
include: [{ system: "http://example.org/cs", concept: [{ code: "red" }, { code: "green" }] }],
},
});
vs.compose?.include.length; // => 1
lookup()
lookup(
cs,code):LookupOutcome
$lookup: resolve a code to its display, definition, status, and properties in a loaded release.
Parameters
cs
The loaded CodeSystem.
code
string
The code to look up.
Returns
A LookupResult when found, or a typed LookupUnknown: never a guess.
Example
import { loadCodeSystem, lookup } from "@cosyte/terminology";
const cs = loadCodeSystem({
format: "fhir",
resource: { resourceType: "CodeSystem", concept: [{ code: "A", display: "Alpha" }] },
});
const r = lookup(cs, "A");
r.found === true && r.display; // => "Alpha"
makeStatus()
makeStatus(
activity,raw?,billable?):ConceptStatus
Assemble a frozen ConceptStatus from a normalized activity, carrying the raw token and (for
classification systems) the billable flag, and attaching the stable diagnostic code for the two
concerns it distinguishes: TERM_CONCEPT_DEPRECATED and TERM_CONCEPT_HEADER_NOT_BILLABLE.
Parameters
activity
The normalized activity.
raw?
string
The verbatim steward token, if any (omitted from the result when empty).
billable?
boolean
The billable flag for a classification system, if applicable.
Returns
A frozen ConceptStatus.
Example
import { makeStatus } from "@cosyte/terminology";
makeStatus("deprecated", "DEPRECATED").code; // => "TERM_CONCEPT_DEPRECATED"
matchesFilter()
matchesFilter(
concept,filter,sub):FilterMatch
Evaluate one ConceptSetFilter against one Concept, using the release's hierarchy.
The concept filter property (and the hierarchy operators regardless of property) reads the code
itself / its subsumption; other properties read the concept's property values. An unimplemented
operator returns { supported: false }: never a coerced matched.
Parameters
concept
The concept under test.
filter
The filter predicate.
sub
The subsumption index for the concept's code system.
Returns
A FilterMatch.
Example
import { loadCodeSystem, buildSubsumption, matchesFilter } from "@cosyte/terminology";
const cs = loadCodeSystem({
format: "fhir",
resource: { resourceType: "CodeSystem", concept: [{ code: "p", concept: [{ code: "c" }] }] },
});
const dog = cs.concepts.get("c");
dog && matchesFilter(dog, { property: "concept", op: "is-a", value: "p" }, buildSubsumption(cs)).matched; // => true
parseCsv()
parseCsv(
content):string[][]
Parse RFC-4180 CSV content into rows of fields (the .rows of parseCsvRows). Lenient: a
stray mid-field quote is literal, so a malformed quote never silently swallows subsequent rows.
Parameters
content
string
The raw CSV text.
Returns
string[][]
The rows, each an array of field strings (untrimmed).
Example
import { parseCsv } from "@cosyte/terminology";
parseCsv('a,b\n"x,y","z""q"'); // => [["a", "b"], ["x,y", 'z"q']]
parseCsvSource()
parseCsvSource(
source):object
Parse a CsvSource into concepts and skipped-row warnings.
Parameters
source
The CSV source.
Returns
object
The parsed concepts (by code) and the load warnings.
concepts
concepts:
Map<string,Concept>
warnings
warnings:
LoadWarning[]
Throws
TERM_CODESYSTEM_MALFORMED when the file has no header row, or a
configured code/display/status/property column is absent from the header. The message
names the missing column's role, never the name you configured.
Example
import { parseCsvSource } from "@cosyte/terminology";
const { concepts } = parseCsvSource({
format: "csv",
content: "CODE,NAME\n2160-0,Creatinine",
columns: { code: "CODE", display: "NAME" },
});
concepts.get("2160-0")?.display; // => "Creatinine"
parseFhirCodeSystem()
parseFhirCodeSystem(
source):object
Parse a FhirCodeSystemSource into concepts, a resolved url/version/name, and warnings.
Parameters
source
The FHIR CodeSystem source.
Returns
object
The parsed concepts (by code), the load warnings, and the resource metadata.
concepts
concepts:
Map<string,Concept>
name?
optionalname?:string
url?
optionalurl?:string
version?
optionalversion?:string
warnings
warnings:
LoadWarning[]
Throws
TERM_CODESYSTEM_MALFORMED when the resource is not a FHIR CodeSystem.
Example
import { parseFhirCodeSystem } from "@cosyte/terminology";
const { concepts } = parseFhirCodeSystem({
resource: { resourceType: "CodeSystem", concept: [{ code: "A", display: "Alpha" }] },
format: "fhir",
});
concepts.get("A")?.display; // => "Alpha"
parseFixedWidth()
parseFixedWidth(
source):object
Parse a FixedWidthSource into concepts and skipped-row warnings.
Parameters
source
The fixed-width source.
Returns
object
The parsed concepts (by code) and the load warnings.
concepts
concepts:
Map<string,Concept>
warnings
warnings:
LoadWarning[]
Example
import { parseFixedWidth } from "@cosyte/terminology";
const { concepts } = parseFixedWidth({
format: "fixed-width",
content: "A00 1 Cholera",
fields: { code: { start: 0, end: 3 }, display: { start: 6 } },
});
concepts.get("A00")?.display; // => "Cholera"
parseRrf()
parseRrf(
source):object
Parse an RrfSource into concepts (first row per code wins) and skipped-row warnings.
A code that recurs across rows (RRF repeats a code once per atom/attribute) keeps its first
occurrence, a documented v1 limitation: preferred-atom selection (TS/STT/ISPREF) and
attribute merging are later work. The result is data only; loadCodeSystem freezes it.
Parameters
source
The RRF source.
Returns
object
The parsed concepts (by code) and the load warnings.
concepts
concepts:
Map<string,Concept>
warnings
warnings:
LoadWarning[]
Example
import { parseRrf } from "@cosyte/terminology";
const { concepts } = parseRrf({
format: "rrf",
content: "1|Aspirin|",
columns: { code: 0, display: 1 },
});
concepts.get("1")?.display; // => "Aspirin"
parseRrfLine()
parseRrfLine(
line): readonlystring[]
Split one RRF line into its fields, dropping the single reserved trailing pipe.
Parameters
line
string
One RRF line (no line terminator).
Returns
readonly string[]
The fields, in column order.
Example
import { parseRrfLine } from "@cosyte/terminology";
parseRrfLine("316151|ENG|lisinopril 10 MG|"); // => ["316151", "ENG", "lisinopril 10 MG"]
parseUcum()
parseUcum(
unit):ParseResult
Parse a UCUM unit expression into an AST.
Parameters
unit
string
The unit expression (e.g. "mmol/L", "kg.m/s2", "10*3/ul").
Returns
The parsed UnitNode, or a typed ParseFailure with a value-free reason.
Example
import { parseUcum } from "@cosyte/terminology";
parseUcum("mmol/L").ok; // => true
parseUcum("m/").ok; // => false
reduce()
reduce(
node):Reduction
Reduce a parsed UCUM unit to its canonical Reduction: a linear scalar×dimension form, or
an opaque special form for expressions involving a non-linear special unit.
The reduction of one atom is cached against that atom object, so a UnitNode you assembled
yourself is answered from its own atoms and cannot change how a unit off parseUcum reduces,
in this call or any later one.
Parameters
node
The AST from parseUcum.
Returns
The reduced form.
Throws
If reducing node reaches an atom with no linear definition, or one whose
definition does not parse. No expression parseUcum accepts reaches either; a node
you assemble yourself can, including by defining an atom in terms of a special unit such as
Cel, which lands on the table's own Cel. A third guard catches a definition that leads back
to itself. Naming a table atom does not reach it (a definition is resolved against the loaded
table, so your atom can name one but never be one), and neither does the table itself, which is
frozen; what reaches it is a value accessor that re-enters reduce for the same atom while
that atom is still being reduced. The message names the fault, never the atom.
Example
import { parseUcum, reduce } from "@cosyte/terminology";
const parsed = parseUcum("N");
if (parsed.ok) {
const r = reduce(parsed.node);
r.kind; // => "linear" (1000 × g·m·s⁻²)
}
relatedByRela()
relatedByRela(
graph,rxcui,predicate):RxNormNavResult
Follow one or more RELA predicates out of a concept (the generic navigation primitive). Direction
is the authored edge direction (subject ⟶predicate⟶ object); the engine never inverts.
Parameters
graph
A loaded RxNormGraph.
rxcui
string
The source concept.
predicate
string | readonly string[]
A RELA name, or an array of them (any-of).
Returns
A RxNormNavResult: the related concepts (possibly empty), or a typed unknown source.
Example
import { loadRxNormGraph, relatedByRela, RELA } from "@cosyte/terminology";
// "SCDC(2) has_ingredient IN(1)": subject=RXCUI2=2, object=RXCUI1=1.
const g = loadRxNormGraph({
conso: "1|ENG||||||||||RXNORM|IN||lisinopril||N||\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||",
rel: "1|||RN|2|||has_ingredient|||RXNORM||||||",
});
const r = relatedByRela(g, "2", RELA.HAS_INGREDIENT);
r.found && r.targets[0]?.name; // => "lisinopril"
resolveNdc()
resolveNdc(
graph,ndc):NdcResult
Resolve an NDC (National Drug Code) to its RXCUI in the loaded release, carrying the temporal
status and the as-of release. NDC↔RXCUI is many:1 and changes across releases, so an
NDC present in the release is active as of that release; an absent NDC is a typed
NdcUnmapped, never a guessed RXCUI.
Parameters
graph
A loaded RxNormGraph (load with sat supplied to populate NDC attributes).
ndc
string
The NDC (as it appears in the release, e.g. 11-digit).
Returns
An NdcResult: a resolution with status + asOf, or a typed absence.
Example
import { loadRxNormGraph, resolveNdc } from "@cosyte/terminology";
const g = loadRxNormGraph({
conso: "2|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||",
rel: "",
sat: "2||||||||NDC|RXNORM|00000000000|N||",
version: "RXNORM_2026AA",
});
const r = resolveNdc(g, "00000000000");
r.resolved && r.status; // => "active"
resolveSystem()
resolveSystem(
id):ResolveSystemResult
Resolve a code-system identifier to its canonical SystemIdentity.
Accepts, in order of attempt: a canonical URI (case-insensitive), a v2-XXXX mnemonic or a
v2 table URI/OID (resolved structurally), a bare or urn:oid:-prefixed OID, or an HL7 v2
Table 0396 mnemonic. Whitespace is trimmed. An empty or unrecognized identifier yields a typed
UnknownSystem: the resolver never invents a URI.
Parameters
id
string
The identifier (canonical URI, OID, urn:oid: OID, or mnemonic).
Returns
The resolved SystemIdentity, or { unknown: true, input }.
Example
import { resolveSystem } from "@cosyte/terminology";
resolveSystem("2.16.840.1.113883.6.1"); // => { url: "http://loinc.org", … }
resolveSystem("SCT"); // => { url: "http://snomed.info/sct", … }
resolveSystem("http://example.com/nope"); // => { unknown: true, input: "http://example.com/nope" }
sliceField()
sliceField(
line,slice):string
Extract and trim a FieldSlice from a line (end omitted slices to end of line).
Parameters
line
string
The source line.
slice
The half-open [start, end) slice.
Returns
string
The trimmed field text (empty when the slice is entirely past the line's end).
Example
import { sliceField } from "@cosyte/terminology";
sliceField("00001 A00 1 Cholera", { start: 6, end: 13 }); // => "A00"
translate()
translate(
sourceCoding,map):TranslateResult
Translate a source Coding through a loaded ConceptMap.
Matches the coding's code against each applicable group's element.code (the source side,
never targets, so the map is never inverted) and returns every declared target for it. A target
with an unmatched equivalence, or with no code, is treated as "no target" (the FHIR way of
asserting a non-mapping), and does not count as a match. When nothing matches, the map author's
group.unmapped directive (if any) is reported via the result's UnmappedMode but never
silently applied.
Parameters
sourceCoding
The source concept to translate.
map
A ConceptMap from loadConceptMap.
Returns
A TranslateResult: matched targets, or a typed unmapped outcome.
Example
import { loadConceptMap, translate } from "@cosyte/terminology";
const map = loadConceptMap({
resourceType: "ConceptMap",
group: [
{
source: "http://hl7.org/fhir/administrative-gender",
target: "http://terminology.hl7.org/CodeSystem/v2-0001",
element: [{ code: "male", target: [{ code: "M", equivalence: "equivalent" }] }],
},
],
});
const r = translate(
{ system: "http://hl7.org/fhir/administrative-gender", code: "male" },
map,
);
r.unmapped; // => false
ucumEqual()
ucumEqual(
a,b):boolean
Whether two UCUM expressions denote the same unit: i.e. they reduce to the same canonical
form (equal base dimensions and equal scale). This recognizes representational equivalences
(N ≡ kg.m/s2, mmol/L ≡ mmol.L-1, annotations inert) but is not magnitude conversion:
mg and g are different units and compare unequal.
A unit is never equal to an invalid expression, and a special (non-linear) unit (Cel, [pH]) is
equal only to a structurally identical special unit: never to a linear unit (the never-fabricate
posture: the engine will not assert an equivalence it cannot prove).
Parameters
a
string
The first UCUM unit expression.
b
string
The second UCUM unit expression.
Returns
boolean
true iff both are valid and denote the same unit.
Example
import { ucumEqual } from "@cosyte/terminology";
ucumEqual("N", "kg.m/s2"); // => true
ucumEqual("mmol/L", "mmol.L-1"); // => true
ucumEqual("mg", "g"); // => false
unsupportedOps()
unsupportedOps(
filters): readonlyConceptSetFilter[]
The filters whose operator the engine does not implement (regex / generalizes / unknown):
a non-empty result means the caller must surface a typed cannot-expand, never mis-expand.
Parameters
filters
readonly ConceptSetFilter[]
The component's filters.
Returns
readonly ConceptSetFilter[]
The subset with an unimplemented operator (empty when all are supported).
Example
import { unsupportedOps } from "@cosyte/terminology";
unsupportedOps([{ property: "concept", op: "is-a", value: "x" }]).length; // => 0
validateCode()
validateCode(
cs,code):ValidateCodeResult
$validate-code: is code a valid member of the loaded code system?
A found code is valid: true, carrying its status (a deprecated or header code is present but
flagged: never silently clean). An absent code is valid: false with TERM_CODE_UNKNOWN, never a
guessed true.
Parameters
cs
The loaded CodeSystem.
code
string
The code to validate.
Returns
Example
import { loadCodeSystem, validateCode } from "@cosyte/terminology";
const cs = loadCodeSystem({
format: "fhir",
resource: { resourceType: "CodeSystem", concept: [{ code: "A", display: "Alpha" }] },
});
validateCode(cs, "A").valid; // => true
validateCode(cs, "ZZZ").valid; // => false
validateCodeInValueSet()
validateCodeInValueSet(
coding,valueSet,ctx?):ValueSetMembership
$validate-code (ValueSet): is coding a member of valueSet?
Parameters
coding
The code to test (system + code).
valueSet
The loaded value set.
ctx?
ExpansionContext = {}
The loaded code systems / referenced value sets the intensional parts resolve against.
Returns
A decided ValueSetMembership (result: true/false), or a typed
ValueSetMemberUndetermined when membership could not be proven: never a fabricated false.
Example
import { loadValueSet, validateCodeInValueSet } from "@cosyte/terminology";
const vs = loadValueSet({
resourceType: "ValueSet",
compose: { include: [{ system: "http://example.org/cs", concept: [{ code: "a" }, { code: "b" }] }] },
});
const r = validateCodeInValueSet({ system: "http://example.org/cs", code: "a" }, vs);
r.undetermined === false && r.result; // => true
validateUcum()
validateUcum(
unit):UcumValidation
Validate a UCUM unit expression and, when valid, return its canonical descriptor.
Validation is parsing against the UCUM grammar over the known atom table: an expression is valid iff it parses completely. An invalid expression returns a typed TERM_UCUM_INVALID with a value-free reason: never a coerced or guessed unit.
Parameters
unit
string
The UCUM unit expression (e.g. "mmol/L", "kg.m/s2", "Cel").
Returns
{ valid: true, canonical } or { valid: false, code: "TERM_UCUM_INVALID", reason }.
Example
import { validateUcum } from "@cosyte/terminology";
validateUcum("mmol/L").valid; // => true
const bad = validateUcum("mg/dl/"); // trailing operator
bad.valid; // => false