@cosyte/ncpdp
Public entry point for the @cosyte/ncpdp package.
NCPDP is two structurally unrelated standards under one brand. They ship via
subpath exports: @cosyte/ncpdp/script (SCRIPT XML ePrescribing),
@cosyte/ncpdp/telecom (the Telecommunication claim standard), and
@cosyte/ncpdp/common (shared vocabulary).
This root re-exports the implemented SCRIPT and Telecom surfaces plus the shared common vocabulary for convenience; deep imports from the subpaths are equivalent and keep Telecom-only or SCRIPT-only consumers lean.
Classes
NcpdpProfileError
Thrown by defineProfile() and profile-validation code when a profile
definition is structurally invalid. Carries the offending profile name (when
known) so consumers can pinpoint which definition failed.
Example
import { defineProfile, NcpdpProfileError } from "@cosyte/ncpdp/profiles";
try {
defineProfile({ name: "" });
} catch (err) {
if (err instanceof NcpdpProfileError) {
console.error(err.message, err.profileName);
}
}
Extends
Error
Constructors
Constructor
new NcpdpProfileError(
message,profileName?):NcpdpProfileError
Internal
Construct a new NcpdpProfileError. profileName is optional so the name
validator can throw before a usable name is available.
Parameters
message
string
profileName?
string
Returns
Overrides
Error.constructor
Properties
profileName
readonlyprofileName:string|undefined
NcpdpScriptBuildError
Thrown when the SCRIPT builder is asked to construct an invalid-by-construction
message. Carries a stable ScriptBuildCode, and its message is that
code's SCRIPT_BUILD_MESSAGES entry: builder input is caller-supplied
and PHI-dense, so none of it is quoted back.
Example
try {
buildScriptResponse({ kind: "Status" });
} catch (err) {
if (err instanceof NcpdpScriptBuildError) {
err.code; // "NCPDP_SCRIPT_BUILD_MISSING_RESPONSE_CODE"
}
}
Extends
Error
Constructors
Constructor
new NcpdpScriptBuildError(
code):NcpdpScriptBuildError
Parameters
code
The stable build error code, which selects the message.
Returns
Overrides
Error.constructor
Properties
code
readonlycode:ScriptBuildCode
Stable, machine-readable build error code.
NcpdpScriptParseError
Thrown when NCPDP SCRIPT input is structurally unrecoverable.
Carries a stable ScriptFatalCode and optional positional context, and
nothing else. message is the SCRIPT_FATAL_MESSAGES entry for the
code, so the error, including its stack, is safe to log and safe to forward
to an error reporter.
It carries no snippet of the offending input. An earlier version did, capped
at 64 characters and documented as a redaction boundary; the cap bounded the
length and nothing about the content, and the paths that raised it are exactly
the paths where the input is too broken to say where in it those characters
came from. NcpdpScriptBuildError and both Telecom errors had already refused
a snippet for that reason. This one now agrees with them.
Example
try {
parseScript("not xml");
} catch (err) {
if (err instanceof NcpdpScriptParseError) {
err.code; // "NCPDP_SCRIPT_NOT_XML"
}
}
Extends
Error
Constructors
Constructor
new NcpdpScriptParseError(
code,opts?):NcpdpScriptParseError
Parameters
code
The stable fatal code, which selects the message.
opts?
Optional positional context.
position?
Returns
Overrides
Error.constructor
Properties
code
readonlycode:ScriptFatalCode
Stable, machine-readable fatal code.
position?
readonlyoptionalposition?:ScriptPosition
XPath-style location of the failure, when known.
NcpdpTelecomBuildError
Thrown when the Telecom builder is asked to construct an invalid-by-construction
transaction. Carries a stable TelecomBuildCode, and its message is
that code's TELECOM_BUILD_MESSAGES entry; like the parse error it never
quotes the offending value (Telecom data is PHI-dense).
Example
try {
buildTelecomRequest({ header: {}, segments: [] });
} catch (err) {
if (err instanceof NcpdpTelecomBuildError) {
err.code; // "NCPDP_TELECOM_BUILD_MISSING_TRANSACTION_CODE"
}
}
Extends
Error
Constructors
Constructor
new NcpdpTelecomBuildError(
code,headerField?):NcpdpTelecomBuildError
Parameters
code
The stable build error code, which selects the message.
headerField?
keyof TelecomHeader
The fixed-header slot at fault, when applicable.
Returns
Overrides
Error.constructor
Properties
code
readonlycode:TelecomBuildCode
Stable, machine-readable build error code.
headerField?
readonlyoptionalheaderField?: keyof TelecomHeader
Which fixed-header field the builder rejected, when the rejection was about
one. Typed as keyof TelecomHeader, so it can only ever be one of this
parser's own nine header field names: it names the slot, never anything
the caller supplied. Absent for rejections that are not header-field-scoped.
NcpdpTelecomParseError
Thrown when NCPDP Telecommunication-standard input is structurally unrecoverable.
Carries a stable TelecomFatalCode and optional positional context, and
nothing else. message is the TELECOM_FATAL_MESSAGES entry for the
code, and it intentionally carries no snippet of the offending bytes: a
Telecom message is PHI-dense, so the TelecomPosition (offset + field
id, never a value) is the only context.
Example
try {
parseTelecom("");
} catch (err) {
if (err instanceof NcpdpTelecomParseError) {
err.code; // "EMPTY_INPUT"
}
}
Extends
Error
Constructors
Constructor
new NcpdpTelecomParseError(
code,opts?):NcpdpTelecomParseError
Parameters
code
The stable fatal code, which selects the message.
opts?
Optional positional context.
position?
Returns
Overrides
Error.constructor
Properties
code
readonlycode:TelecomFatalCode
Stable, machine-readable fatal code.
position?
readonlyoptionalposition?:TelecomPosition
Byte-offset context of the failure, when known.
ScriptMessage
An immutable parsed SCRIPT message: routing header, the typed body, and any non-fatal warnings raised while parsing. Construct via "./parse".parseScript: instances are deeply frozen.
Example
const msg = parseScript(xml);
msg.header.messageId;
msg.asNewRx()?.medication?.description;
Constructors
Constructor
new ScriptMessage(
init):ScriptMessage
Parameters
init
Pre-extracted header, body, warnings, and optional profile.
body
header
profile?
warnings
readonly NcpdpScriptWarning[]
Returns
Properties
body
readonlybody:ScriptBody
The typed transaction body.
header
readonlyheader:ScriptHeader
Routing/correlation header fields.
profile?
readonlyoptionalprofile?:NcpdpProfile
The trading-partner profile in effect for this parse: either passed
explicitly via parseScript's options.profile or resolved from the
process-scoped default. Present only when a profile applied; attribution
only (v1 profiles never alter the parse).
warnings
readonlywarnings: readonlyNcpdpScriptWarning[]
Non-fatal warnings, in the order raised.
Accessors
correlatesTo
Get Signature
get correlatesTo():
string|undefined
The identifier of the message this one answers (<RelatesToMessageID>), or
undefined. The correlation key that ties a response back to its request.
Example
parseScript(responseXml).correlatesTo; // the request's MessageID
Returns
string | undefined
The correlated message id, or undefined.
disposition
Get Signature
get disposition():
ResponseDisposition|undefined
The disposition of this message when it is a response transaction
(<Status>/<Error>/<Verify>), else undefined. Derived only from the
body kind: an <Error> is always "error" and is never read as a
success.
Example
parseScript(xml).disposition; // "success" | "error" | "verify" | undefined
Returns
ResponseDisposition | undefined
The ResponseDisposition, or undefined for a request /
unsupported transaction.
Methods
asError()
asError():
ErrorBody|undefined
The ErrorBody when this message is an <Error> response, else
undefined.
Returns
ErrorBody | undefined
The Error body, or undefined.
Example
parseScript(xml).asError()?.code;
asLifecycleRequest()
asLifecycleRequest():
LifecycleRequest|undefined
The LifecycleRequest body when this message is a renewal/change/cancel
request (RxRenewalRequest/RxChangeRequest/CancelRx), else undefined.
Returns
LifecycleRequest | undefined
The lifecycle request body, or undefined.
Example
parseScript(xml).asLifecycleRequest()?.medicationPrescribed?.description;
asLifecycleResponse()
asLifecycleResponse():
LifecycleResponse|undefined
The LifecycleResponse body when this message is a renewal/change/cancel
response (RxRenewalResponse/RxChangeResponse/CancelRxResponse), else
undefined.
Returns
LifecycleResponse | undefined
The lifecycle response body, or undefined.
Example
parseScript(xml).asLifecycleResponse()?.outcome; // "approved" | "denied" | …
asNewRx()
asNewRx():
NewRx|undefined
The NewRx body when this message is a NewRx, else undefined.
Returns
NewRx | undefined
The NewRx body, or undefined.
Example
const rx = parseScript(xml).asNewRx();
rx?.medication?.description;
asStatus()
asStatus():
StatusBody|undefined
The StatusBody when this message is a <Status> response, else
undefined.
Returns
StatusBody | undefined
The Status body, or undefined.
Example
parseScript(xml).asStatus()?.code;
asVerify()
asVerify():
VerifyBody|undefined
The VerifyBody when this message is a <Verify> response, else
undefined.
Returns
VerifyBody | undefined
The Verify body, or undefined.
Example
parseScript(xml).asVerify()?.code;
toString()
toString():
string
Serialize this message back to canonical NCPDP SCRIPT XML. Equivalent to "./serialize".serializeScript; only the modeled fields are emitted, so the result is canonical (idempotent under re-parse) rather than byte-identical to any original input.
Returns
string
The canonical SCRIPT XML string.
Example
parseScript(raw).toString(); // canonical XML
Interfaces
CancelRx
A prescriber-initiated request to retract a prescription (<CancelRx>).
Extends
Properties
kind
readonlykind:"CancelRx"
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The prescription this request concerns (<MedicationPrescribed>).
Inherited from
LifecycleRequestFields.medicationPrescribed
patient?
readonlyoptionalpatient?:Patient
Inherited from
LifecycleRequestFields.patient
pharmacy?
readonlyoptionalpharmacy?:Pharmacy
Inherited from
LifecycleRequestFields.pharmacy
prescriber?
readonlyoptionalprescriber?:Prescriber
Inherited from
LifecycleRequestFields.prescriber
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number, verbatim (<RequestReferenceNumber>).
Inherited from
LifecycleRequestFields.requestReferenceNumber
CancelRxResponse
A pharmacy's confirmation/denial of a cancel request (<CancelRxResponse>).
Extends
Properties
kind
readonlykind:"CancelRxResponse"
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The medication carried with the response. For an approvedWithChanges
outcome this is the changed medication and is the field a consumer must
read to dispense correctly.
Inherited from
LifecycleResponseFields.medicationPrescribed
outcome
readonlyoutcome:ResponseOutcome
The prescriber's decision, detected fail-safe from the <Response> choice.
Inherited from
LifecycleResponseFields.outcome
reason?
readonlyoptionalreason?:ResponseReason
The reason carried with the outcome, when present.
Inherited from
LifecycleResponseFields.reason
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number echoing the request, verbatim (<RequestReferenceNumber>).
Inherited from
LifecycleResponseFields.requestReferenceNumber
CodedValue
A coded value: the raw code, its source qualifier, and the normalized system we recognized from that qualifier. The original qualifier is always preserved so a consumer can re-derive the mapping if our table lags the spec.
Properties
qualifier
readonlyqualifier:string
The source qualifier string that accompanied the code.
system
readonlysystem:CodeSystem
Normalized code system recognized from qualifier.
value
readonlyvalue:string
The code itself, verbatim.
DecimalValue
A decimal value preserved exactly as it appeared on the wire.
NCPDP quantities, strengths, and days-supply are decimal quantities where
binary floating point would silently corrupt the value (e.g. 0.1). We never
parse them into a JS number; we keep the original source string and a
validity flag, leaving any arithmetic to the consumer who can choose a
decimal-safe representation.
Properties
isValid
readonlyisValid:boolean
True when source matches a plain decimal numeric literal.
source
readonlysource:string
The original textual value, verbatim.
DrugCoded
A coded drug product (<DrugCoded>).
Properties
drugDbCode?
readonlyoptionaldrugDbCode?:CodedValue
<DrugDBCode> with its qualifier resolved to a code system.
productCode?
readonlyoptionalproductCode?:CodedValue
<ProductCode> with its qualifier resolved to a code system.
ErrorBody
A SCRIPT <Error>: a negative acknowledgment. Its ResponseFields.code
and description are surfaced verbatim and it always dispositions as
"error": it is never coerced to a success.
Extends
Properties
code?
readonlyoptionalcode?:string
Primary response code, verbatim (<Code>).
Inherited from
description?
readonlyoptionaldescription?:string
Free-text description, verbatim (<Description>).
Inherited from
descriptionCode?
readonlyoptionaldescriptionCode?:string
Secondary description code, verbatim (<DescriptionCode>).
Inherited from
ResponseFields.descriptionCode
kind
readonlykind:"Error"
LifecycleRequestFields
Fields shared by the lifecycle request transactions.
Extended by
Properties
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The prescription this request concerns (<MedicationPrescribed>).
patient?
readonlyoptionalpatient?:Patient
pharmacy?
readonlyoptionalpharmacy?:Pharmacy
prescriber?
readonlyoptionalprescriber?:Prescriber
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number, verbatim (<RequestReferenceNumber>).
LifecycleResponseFields
Fields shared by the lifecycle response transactions.
Extended by
Properties
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The medication carried with the response. For an approvedWithChanges
outcome this is the changed medication and is the field a consumer must
read to dispense correctly.
outcome
readonlyoutcome:ResponseOutcome
The prescriber's decision, detected fail-safe from the <Response> choice.
reason?
readonlyoptionalreason?:ResponseReason
The reason carried with the outcome, when present.
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number echoing the request, verbatim (<RequestReferenceNumber>).
MedicationPrescribed
The prescribed medication (<MedicationPrescribed>).
Properties
coded?
readonlyoptionalcoded?:DrugCoded
daysSupply?
readonlyoptionaldaysSupply?:DecimalValue
description?
readonlyoptionaldescription?:string
directions?
readonlyoptionaldirections?:string
Free-text directions (<Directions>), verbatim.
note?
readonlyoptionalnote?:string
numberOfRefills?
readonlyoptionalnumberOfRefills?:string
quantity?
readonlyoptionalquantity?:Quantity
sig?
readonlyoptionalsig?:StructuredSig
Best-effort, lossy decode of the structured <Sig>, present only when a
<Sig> element exists. The free-text sigText stays the source of
truth; this structured view is additive and per-field provenance-tagged.
sigText?
readonlyoptionalsigText?:string
Structured SIG free text (<Sig><SigText>), verbatim.
strength?
readonlyoptionalstrength?:Strength
substitutions?
readonlyoptionalsubstitutions?:string
writtenDate?
readonlyoptionalwrittenDate?:string
Written date, verbatim.
NcpdpProfile
A readonly, frozen profile produced by defineProfile(). Mirrors the locked
x12/hl7 shape (name / description / lineage) plus NCPDP's standard-tagged
quirks axis and a structured describe().
Example
import { parseTelecom } from "@cosyte/ncpdp/telecom";
import { profiles } from "@cosyte/ncpdp/profiles";
const tx = parseTelecom(raw, { profile: profiles.pbm });
tx.profile?.name; // "pbm"
tx.profile?.describe().requires.length;
Properties
describe
readonlydescribe: () =>NcpdpProfileDescription
Returns
description?
readonlyoptionaldescription?:string
lineage
readonlylineage: readonlystring[]
name
readonlyname:string
quirks
readonlyquirks: readonlyNcpdpProfileQuirk[]
NcpdpProfileDescription
Structured describe() output: the "what this profile relaxes / adds /
requires" record published with the package. Returned as DATA (not a
formatted string) so downstream tooling: docs generators, the pathways
engine: can consume it programmatically.
Example
import { profiles } from "@cosyte/ncpdp/profiles";
const d = profiles.pbm.describe();
d.requires.map((q) => q.id); // ["person-code-required"]
d.expectedWarnings; // readonly NcpdpWarningCode[]
Properties
adds
readonlyadds: readonlyNcpdpProfileQuirk[]
description?
readonlyoptionaldescription?:string
expectedWarnings
readonlyexpectedWarnings: readonlyNcpdpWarningCode[]
Sorted, de-duplicated union of every quirk's expectedWarnings.
lineage
readonlylineage: readonlystring[]
name
readonlyname:string
relaxes
readonlyrelaxes: readonlyNcpdpProfileQuirk[]
requires
readonlyrequires: readonlyNcpdpProfileQuirk[]
standards
readonlystandards: readonlyNcpdpStandard[]
Standards this profile's quirks touch (sorted, de-duplicated).
NcpdpProfileQuirk
A single trading-partner convention captured by a profile. Every quirk is
fixture-grounded: fixture points at a real Tier-2 corpus file that
demonstrates the convention, and sourceCategory records where it is
documented. This is the locked hard rule: a quirk without a demonstrating
fixture is forbidden, enforced both by this required field and by the
accuracy test.
Example
import type { NcpdpProfileQuirk } from "@cosyte/ncpdp/profiles";
const quirk: NcpdpProfileQuirk = {
id: "person-code-required",
standard: "telecom",
effect: "requires",
summary: "Insurance segment carries a Person Code (303-C3) cardholder/dependent value.",
fixture: "telecom/pbm-person-code.ncpdp",
sourceCategory: "NCPDP Telecommunication vD.0: Person Code (303-C3); PBM payer sheets",
};
Properties
effect
readonlyeffect:NcpdpProfileEffect
Which describe() bucket this quirk renders into.
expectedWarnings?
readonlyoptionalexpectedWarnings?: readonlyNcpdpWarningCode[]
Warning codes this quirk leads a consumer to EXPECT when the convention is
present. Drives partitionWarnings. Often empty: the lenient parser
absorbs most conventions with zero warnings, and that "lossless, no warning"
outcome is itself the documented behavior.
fixture
readonlyfixture:string
Path to the Tier-2 fixture demonstrating the convention, relative to
test/fixtures/ (e.g. "telecom/pbm-person-code.ncpdp"). REQUIRED: the
locked hard rule. The accuracy test parses this file and asserts the
claimed convention is present.
id
readonlyid:string
Stable, kebab-case identifier: unique within a profile's quirk set.
sourceCategory
readonlysourceCategory:string
Where the convention is documented (standard clause / companion guide).
standard
readonlystandard:NcpdpStandard
Which NCPDP standard the quirk (and its cited fixture) belongs to.
summary
readonlysummary:string
One-line human summary. NEVER contains PHI: describes structure only.
NcpdpProfileSpec
Input accepted by defineProfile(). Every field except name is optional;
extends composes parent profiles (lineage + quirks merge) the same way the
x12/hl7 extends does.
Example
import { defineProfile, profiles, type NcpdpProfileSpec } from "@cosyte/ncpdp/profiles";
const spec: NcpdpProfileSpec = {
name: "my-regional-pbm",
extends: profiles.pbm,
quirks: [
{
id: "reject-code-depth",
standard: "telecom",
effect: "adds",
summary: "Returns reject codes beyond the modeled core set.",
fixture: "telecom/pbm-reject-unknown.ncpdp",
sourceCategory: "regional PBM payer sheet: reject-code taxonomy",
},
],
};
const profile = defineProfile(spec);
Properties
description?
readonlyoptionaldescription?:string
extends?
readonlyoptionalextends?:NcpdpProfile| readonlyNcpdpProfile[]
name
readonlyname:string
quirks?
readonlyoptionalquirks?: readonlyNcpdpProfileQuirk[]
NcpdpScriptWarning
A non-fatal SCRIPT parse warning: a stable code, its registry message, and the XPath-style location where it was raised.
What is and is not guaranteed. message is always the
SCRIPT_WARNING_MESSAGES entry for code, byte for byte, so no part of
a parsed document can appear in it. position.path is assembled only from
element names this parser recognizes, so a sender-chosen name never reaches it
either. A warning is therefore safe to log whole. That is a property of the
construction, not a promise about the document.
Properties
code
readonlycode:ScriptWarningCode
Stable, machine-readable warning code.
message
readonlymessage:string
The SCRIPT_WARNING_MESSAGES entry for code, verbatim.
position
readonlyposition:ScriptPosition
XPath-style location where the condition was detected.
NcpdpTelecomWarning
A non-fatal Telecom parse warning: a stable code, its registry message, and the byte-offset location where it was raised.
What is and is not guaranteed. message is always the
TELECOM_WARNING_MESSAGES entry for code, byte for byte, so no part
of a transmission can appear in it. position carries a byte offset and, when
known, a field identifier this parser named itself. A warning is therefore
safe to log whole. That is a property of the construction, not a promise about
the transmission: the segment and field values on the model are wire data
and are exactly as sensitive as the claim they came from.
Properties
code
readonlycode:TelecomWarningCode
Stable, machine-readable warning code.
message
readonlymessage:string
The TELECOM_WARNING_MESSAGES entry for code, verbatim.
position
readonlyposition:TelecomPosition
Byte-offset location where the condition was detected.
NcpdpWarningPartition
The result of partitionWarnings: warnings split into those a profile leads you to EXPECT and those it does not. Preserves the input warning type.
Example
import type { NcpdpWarningPartition } from "@cosyte/ncpdp/profiles";
import type { NcpdpTelecomWarning } from "@cosyte/ncpdp/telecom";
declare const p: NcpdpWarningPartition<NcpdpTelecomWarning>;
p.unexpected.length; // alert only on these
Type Parameters
W
W extends object
Properties
expected
readonlyexpected: readonlyW[]
unexpected
readonlyunexpected: readonlyW[]
NdcValue
A National Drug Code preserved verbatim, with a best-effort segmentation hint. We do not rewrite or zero-pad the value: the original is authoritative.
Properties
segmentation
readonlysegmentation:NdcSegmentation
Best-effort segmentation classification of value.
value
readonlyvalue:string
The NDC exactly as it appeared, including any hyphens.
NewRx
A parsed SCRIPT NewRx transaction body.
Properties
kind
readonlykind:"NewRx"
medication?
readonlyoptionalmedication?:MedicationPrescribed
patient?
readonlyoptionalpatient?:Patient
pharmacy?
readonlyoptionalpharmacy?:Pharmacy
prescriber?
readonlyoptionalprescriber?:Prescriber
NewRxInput
Input to buildNewRx: routing header, optional parties, and the medication.
Properties
header?
readonlyoptionalheader?:ScriptHeaderInput
medication
readonlymedication:MedicationPrescribed
The prescribed medication; a description is required.
patient?
readonlyoptionalpatient?:Patient
pharmacy?
readonlyoptionalpharmacy?:Pharmacy
prescriber?
readonlyoptionalprescriber?:Prescriber
ParseScriptOptions
Options for parseScript.
Properties
profile?
readonlyoptionalprofile?:NcpdpProfile|null
Trading-partner profile to attach to the result for attribution (and
partitionWarnings). An explicit profile ALWAYS wins over any
process-scoped default; pass null to opt out of the default for this one
call; omit (or undefined) to consult getDefaultProfile(). v1 profiles
are DESCRIPTIVE: the profile is surfaced as msg.profile but does NOT
alter the lenient parse.
PartyIdentification
A pharmacy or prescriber identification (<Identification>).
Properties
deaNumber?
readonlyoptionaldeaNumber?:string
ncpdpId?
readonlyoptionalncpdpId?:string
npi?
readonlyoptionalnpi?:string
Patient
The patient on a NewRx (<Patient>).
Properties
dateOfBirth?
readonlyoptionaldateOfBirth?:string
Date of birth, verbatim: no reformatting.
gender?
readonlyoptionalgender?:string
name?
readonlyoptionalname?:ScriptName
Pharmacy
The dispensing pharmacy on a NewRx (<Pharmacy>).
Properties
businessName?
readonlyoptionalbusinessName?:string
identification?
readonlyoptionalidentification?:PartyIdentification
Prescriber
The prescriber on a NewRx (<Prescriber>).
Properties
identification?
readonlyoptionalidentification?:PartyIdentification
name?
readonlyoptionalname?:ScriptName
Quantity
A dispense quantity (<Quantity>).
Properties
codeListQualifier?
readonlyoptionalcodeListQualifier?:string
unitOfMeasure?
readonlyoptionalunitOfMeasure?:string
value?
readonlyoptionalvalue?:DecimalValue
ResponseFields
Fields shared by the SCRIPT response transactions. All are optional because a real-world sender may omit them; every value is surfaced verbatim: codes and descriptions are never reformatted, looked up, or translated.
Extended by
Properties
code?
readonlyoptionalcode?:string
Primary response code, verbatim (<Code>).
description?
readonlyoptionaldescription?:string
Free-text description, verbatim (<Description>).
descriptionCode?
readonlyoptionaldescriptionCode?:string
Secondary description code, verbatim (<DescriptionCode>).
ResponseReason
The reason carried alongside a lifecycle response outcome. All fields are surfaced verbatim: codes and free text are never reformatted, looked up, or translated.
Properties
code?
readonlyoptionalcode?:string
Coded reason, verbatim (<ReasonCode>).
denialReason?
readonlyoptionaldenialReason?:string
Free-text denial reason, verbatim (<DenialReason>).
note?
readonlyoptionalnote?:string
Free-text note, verbatim (<Note>).
referenceNumber?
readonlyoptionalreferenceNumber?:string
Reference number tying the reason to a request item, verbatim (<ReferenceNumber>).
RxChangeRequest
A pharmacy-initiated request to change a prescription (<RxChangeRequest>).
Extends
Properties
kind
readonlykind:"RxChangeRequest"
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The prescription this request concerns (<MedicationPrescribed>).
Inherited from
LifecycleRequestFields.medicationPrescribed
patient?
readonlyoptionalpatient?:Patient
Inherited from
LifecycleRequestFields.patient
pharmacy?
readonlyoptionalpharmacy?:Pharmacy
Inherited from
LifecycleRequestFields.pharmacy
prescriber?
readonlyoptionalprescriber?:Prescriber
Inherited from
LifecycleRequestFields.prescriber
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number, verbatim (<RequestReferenceNumber>).
Inherited from
LifecycleRequestFields.requestReferenceNumber
RxChangeResponse
A prescriber's answer to a change request (<RxChangeResponse>).
Extends
Properties
kind
readonlykind:"RxChangeResponse"
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The medication carried with the response. For an approvedWithChanges
outcome this is the changed medication and is the field a consumer must
read to dispense correctly.
Inherited from
LifecycleResponseFields.medicationPrescribed
outcome
readonlyoutcome:ResponseOutcome
The prescriber's decision, detected fail-safe from the <Response> choice.
Inherited from
LifecycleResponseFields.outcome
reason?
readonlyoptionalreason?:ResponseReason
The reason carried with the outcome, when present.
Inherited from
LifecycleResponseFields.reason
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number echoing the request, verbatim (<RequestReferenceNumber>).
Inherited from
LifecycleResponseFields.requestReferenceNumber
RxRenewalRequest
A pharmacy-initiated request to renew a prescription (<RxRenewalRequest>).
Extends
Properties
kind
readonlykind:"RxRenewalRequest"
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The prescription this request concerns (<MedicationPrescribed>).
Inherited from
LifecycleRequestFields.medicationPrescribed
patient?
readonlyoptionalpatient?:Patient
Inherited from
LifecycleRequestFields.patient
pharmacy?
readonlyoptionalpharmacy?:Pharmacy
Inherited from
LifecycleRequestFields.pharmacy
prescriber?
readonlyoptionalprescriber?:Prescriber
Inherited from
LifecycleRequestFields.prescriber
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number, verbatim (<RequestReferenceNumber>).
Inherited from
LifecycleRequestFields.requestReferenceNumber
RxRenewalResponse
A prescriber's answer to a renewal request (<RxRenewalResponse>).
Extends
Properties
kind
readonlykind:"RxRenewalResponse"
medicationPrescribed?
readonlyoptionalmedicationPrescribed?:MedicationPrescribed
The medication carried with the response. For an approvedWithChanges
outcome this is the changed medication and is the field a consumer must
read to dispense correctly.
Inherited from
LifecycleResponseFields.medicationPrescribed
outcome
readonlyoutcome:ResponseOutcome
The prescriber's decision, detected fail-safe from the <Response> choice.
Inherited from
LifecycleResponseFields.outcome
reason?
readonlyoptionalreason?:ResponseReason
The reason carried with the outcome, when present.
Inherited from
LifecycleResponseFields.reason
requestReferenceNumber?
readonlyoptionalrequestReferenceNumber?:string
Request reference number echoing the request, verbatim (<RequestReferenceNumber>).
Inherited from
LifecycleResponseFields.requestReferenceNumber
ScriptHeader
The SCRIPT <Header> fields useful for routing and correlation. Every field
is optional because real-world senders omit some; absence is undefined, not
an error (Postel's Law).
Properties
from?
readonlyoptionalfrom?:string
Source identifier (<From>).
messageId?
readonlyoptionalmessageId?:string
Unique message identifier (<MessageID>).
prescriberOrderNumber?
readonlyoptionalprescriberOrderNumber?:string
Prescriber order number (<PrescriberOrderNumber>), when present.
relatesToMessageId?
readonlyoptionalrelatesToMessageId?:string
Correlated prior message identifier (<RelatesToMessageID>).
sentTime?
readonlyoptionalsentTime?:string
Sender timestamp, verbatim (<SentTime>).
to?
readonlyoptionalto?:string
Destination identifier (<To>).
version?
readonlyoptionalversion?:string
Declared SCRIPT version (root version/Version, or <Header><Version>).
ScriptHeaderInput
The SCRIPT <Header> fields a builder accepts; all optional.
Properties
from?
readonlyoptionalfrom?:string
messageId?
readonlyoptionalmessageId?:string
prescriberOrderNumber?
readonlyoptionalprescriberOrderNumber?:string
relatesToMessageId?
readonlyoptionalrelatesToMessageId?:string
sentTime?
readonlyoptionalsentTime?:string
to?
readonlyoptionalto?:string
version?
readonlyoptionalversion?:string
Declared SCRIPT version, emitted as the root version attribute.
ScriptName
A person's name as carried in SCRIPT (<Name>).
Properties
firstName?
readonlyoptionalfirstName?:string
lastName?
readonlyoptionallastName?:string
middleName?
readonlyoptionalmiddleName?:string
ScriptPosition
Positional context attached to NCPDP SCRIPT warnings and fatal errors.
SCRIPT is XML, so position is an XPath-style location string (e.g.
/Message/Body/NewRx/MedicationPrescribed): never a field value. This keeps
diagnostics PHI-safe: a consumer learns where a problem is without the
library echoing patient data.
Properties
path
readonlypath:string
XPath-style location of the element, e.g. /Message/Body/NewRx.
ScriptResponseInput
Input to buildScriptResponse: the response kind, its code, and optional detail.
Properties
code
readonlycode:string
The primary response <Code>; required (a response must carry one).
description?
readonlyoptionaldescription?:string
descriptionCode?
readonlyoptionaldescriptionCode?:string
header?
readonlyoptionalheader?:ScriptHeaderInput
kind
readonlykind:ResponseKind
Which response transaction to build.
SigField
One decoded component of a structured SIG, always carrying its
SigFieldProvenance so a consumer can tell, per field, whether the value
was coded, derived from uncoded structure, or absent. A "coded" field's code
keeps its source qualifier verbatim (SNOMED CT / NCI Thesaurus / etc.) so the
provenance is auditable even when our qualifier table lags the spec.
Properties
code?
readonlyoptionalcode?:CodedValue
The code + recognized system, when the structure carried a coded value.
provenance
readonlyprovenance:SigFieldProvenance
Whether this field was coded, derived from uncoded structure, or absent.
text?
readonlyoptionaltext?:string
Verbatim human-readable text, when the structure carried any.
StatusBody
A SCRIPT <Status>: a positive acknowledgment of a prior transaction.
Extends
Properties
code?
readonlyoptionalcode?:string
Primary response code, verbatim (<Code>).
Inherited from
description?
readonlyoptionaldescription?:string
Free-text description, verbatim (<Description>).
Inherited from
descriptionCode?
readonlyoptionaldescriptionCode?:string
Secondary description code, verbatim (<DescriptionCode>).
Inherited from
ResponseFields.descriptionCode
kind
readonlykind:"Status"
Strength
Explicit <Strength>. Surfaced independently of any strength implied by a
coded product: the two are never reconciled (see
"../common/warnings".SCRIPT_WARNING_CODES.STRENGTH_CODED_AND_EXPLICIT).
Properties
form?
readonlyoptionalform?:string
unitOfMeasure?
readonlyoptionalunitOfMeasure?:string
value?
readonlyoptionalvalue?:string
StructuredSig
A best-effort, lossy decode of a SCRIPT structured <Sig> into typed
dosing components. Every component slot is always present and tagged
SigFieldProvenance, so the surface is uniform and a consumer can see
which fields are coded, derived, or absent.
Safety contract. The free-text sigText is the source of truth and is preserved verbatim; the structured view is additive and clearly flagged lossy (see "../common/warnings".SCRIPT_WARNING_CODES.SIG_STRUCTURED_LOSSY). The two are never reconciled: when structured dosing and the free text disagree, both are surfaced as-is. An ambiguous structured dose is never collapsed into a confident value (see "../common/warnings".SCRIPT_WARNING_CODES.SIG_AMBIGUOUS_DOSE).
Properties
administrationTiming
readonlyadministrationTiming:SigField
Administration timing / frequency.
dose
readonlydose:SigField
Dose amount (the numeric quantity), string-preserved; never a confident guess.
doseDeliveryMethod
readonlydoseDeliveryMethod:SigField
Method of dose delivery (e.g. "take", "apply").
doseUnitOfMeasure
readonlydoseUnitOfMeasure:SigField
Unit of measure for the dose (e.g. tablet, mL).
duration
readonlyduration:SigField
Duration of therapy.
hasStructuredData
readonlyhasStructuredData:boolean
True when at least one component decoded to a non-"absent" value.
indication
readonlyindication:SigField
Clinical indication ("as needed for ...") .
maximumDoseRestriction
readonlymaximumDoseRestriction:SigField
Maximum-dose restriction.
route
readonlyroute:SigField
Route of administration (SNOMED/NCI when coded).
sigText?
readonlyoptionalsigText?:string
The free-text SIG (<SigText>), verbatim: always the source of truth.
siteOfAdministration
readonlysiteOfAdministration:SigField
Site of administration (SNOMED/NCI when coded).
vehicle
readonlyvehicle:SigField
Vehicle / diluent the dose is taken with.
TelecomClaim
A B1/B2/B3 request view over a decoded Telecom transaction: the safety-relevant
fields a biller needs, lifted from their field-id-keyed segments and preserved
verbatim. Every field is optional: a missing segment or field yields
undefined rather than a throw, in keeping with the lenient parse contract.
Properties
cardholderId?
readonlyoptionalcardholderId?:string
Cardholder ID (302-C2) from the Insurance segment. PHI.
dateOfBirth?
readonlyoptionaldateOfBirth?:string
Date of Birth (304-C4) from the Patient segment, verbatim (CCYYMMDD). PHI.
daysSupply?
readonlyoptionaldaysSupply?:DecimalValue
Days Supply (405-D5), preserved as a decimal-safe value.
dispenseAsWritten?
readonlyoptionaldispenseAsWritten?:string
Dispense As Written / Product Selection Code (408-D8), verbatim.
fillNumber?
readonlyoptionalfillNumber?:string
Fill Number (403-D3) from the Claim segment.
genderCode?
readonlyoptionalgenderCode?:string
Patient Gender Code (305-C5) from the Patient segment.
groupId?
readonlyoptionalgroupId?:string
Group ID (301-C1) from the Insurance segment.
personCode?
readonlyoptionalpersonCode?:string
Person Code (303-C3) from the Insurance segment.
prescriberId?
readonlyoptionalprescriberId?:string
Prescriber ID (411-DB) from the Prescriber segment.
prescriberIdQualifier?
readonlyoptionalprescriberIdQualifier?:string
Prescriber ID Qualifier (466-EZ) from the Prescriber segment.
prescriptionReferenceNumber?
readonlyoptionalprescriptionReferenceNumber?:string
Prescription/Service Reference Number (402-D2) from the Claim segment.
prescriptionReferenceQualifier?
readonlyoptionalprescriptionReferenceQualifier?:string
Prescription/Service Reference Number Qualifier (455-EM).
product?
readonlyoptionalproduct?:TelecomProductCode
Product/Service ID + qualifier (407-D7 / 436-E1), when present.
quantityDispensed?
readonlyoptionalquantityDispensed?:TelecomQuantity
Quantity Dispensed (442-E7) with its implied 3-place decimal.
transactionCode
readonlytransactionCode:string
Transaction Code (103-A3) from the header, e.g. "B1".
TelecomField
A single decoded field: its 2-character id, verbatim value, and paraphrased name.
Properties
byteOffset
readonlybyteOffset:number
Byte offset of this field token in the raw message.
id
readonlyid:string
The 2-character field identifier, verbatim (empty for a malformed token).
name?
readonlyoptionalname?:string
Paraphrased field name when id is recognized.
value
readonlyvalue:string
The field value exactly as it appeared on the wire.
TelecomFieldInput
A single field to build: its 2-character id and verbatim value.
Properties
id
readonlyid:string
The 2-character field identifier, e.g. "D7".
value
readonlyvalue:string
The field value, emitted verbatim.
TelecomHeader
The fixed-length Transaction Header that opens every NCPDP Telecommunication request. It carries no field separators: each field is positional. Field numbers/designators are from the NCPDP Telecommunication standard vD.0; the names here are our own paraphrases (we do not redistribute NCPDP prose).
Values are trimmed of pad whitespace; numeric leading zeros are preserved (a BIN or PCN is an identifier, not an arithmetic quantity).
Properties
binNumber
readonlybinNumber:string
101-A1: the routing Bank Identification Number (6 chars on the wire).
dateOfService
readonlydateOfService:string
401-D1: Date of Service, verbatim (CCYYMMDD on the wire).
processorControlNumber
readonlyprocessorControlNumber:string
104-A4: Processor Control Number.
serviceProviderId
readonlyserviceProviderId:string
201-B1: Service Provider ID (e.g. the pharmacy NPI).
serviceProviderIdQualifier
readonlyserviceProviderIdQualifier:string
202-B2: Service Provider ID Qualifier.
softwareCertificationId
readonlysoftwareCertificationId:string
110-AK: Software Vendor / Certification ID.
transactionCode
readonlytransactionCode:string
103-A3: Transaction Code, e.g. "B1" (billing), "B2", "B3", "E1".
transactionCount
readonlytransactionCount:string
109-A9: declared number of transactions in the transmission (1 char).
versionRelease
readonlyversionRelease:string
102-A2: Version/Release, "D0" for the standard this reader decodes.
TelecomHeaderInput
The fixed Transaction Header fields to build. Only transactionCode is required.
Properties
binNumber?
readonlyoptionalbinNumber?:string
101-A1: routing BIN.
dateOfService?
readonlyoptionaldateOfService?:string
401-D1: Date of Service (CCYYMMDD).
processorControlNumber?
readonlyoptionalprocessorControlNumber?:string
104-A4: Processor Control Number.
serviceProviderId?
readonlyoptionalserviceProviderId?:string
201-B1: Service Provider ID.
serviceProviderIdQualifier?
readonlyoptionalserviceProviderIdQualifier?:string
202-B2: Service Provider ID Qualifier.
softwareCertificationId?
readonlyoptionalsoftwareCertificationId?:string
110-AK: Software Vendor / Certification ID.
transactionCode
readonlytransactionCode:string
103-A3: Transaction Code; required (a request cannot route without one).
transactionCount?
readonlyoptionaltransactionCount?:string
109-A9: transaction count; defaults to "1".
versionRelease?
readonlyoptionalversionRelease?:string
102-A2: Version/Release; defaults to "D0".
TelecomParseOptions
Options controlling parseTelecom.
Properties
encoding?
readonlyoptionalencoding?:BufferEncoding
When the input is a Buffer, the encoding used to decode it to text.
The Telecommunication standard is single-byte ASCII; defaults to "latin1"
so every byte maps to a code point without loss.
profile?
readonlyoptionalprofile?:NcpdpProfile|null
Trading-partner profile to attach to the result for attribution (and
partitionWarnings). An explicit profile ALWAYS wins over any
process-scoped default; pass null to opt out of the default for this one
call; omit (or undefined) to consult getDefaultProfile(). v1 profiles
are DESCRIPTIVE: the profile is surfaced as tx.profile but does NOT alter
the lenient parse.
TelecomPosition
Positional context attached to NCPDP Telecommunication-standard warnings and fatal errors.
The Telecommunication standard is a byte-oriented, control-character-framed format, so position is a byte offset into the raw message: optionally narrowed to the 2-character field identifier where the condition was detected. It never carries a field value: a consumer learns where a problem is without the library echoing cardholder, patient, or drug data, keeping diagnostics PHI-safe.
Properties
byteOffset
readonlybyteOffset:number
Zero-based byte offset into the raw message.
fieldId?
readonlyoptionalfieldId?:string
The 2-character field identifier in scope, when known. Never a value.
TelecomProductCode
A drug identifier from the Claim segment: the Product/Service ID (407-D7) and its qualifier (436-E1), each preserved verbatim. The qualifier names the code system (e.g. NDC); we surface a paraphrased meaning when we recognize it but never reinterpret the id itself.
Properties
id
readonlyid:string
Product/Service ID (407-D7), verbatim: e.g. an 11-digit NDC.
qualifier
readonlyqualifier:string
Product/Service ID Qualifier (436-E1), verbatim.
qualifierMeaning?
readonlyoptionalqualifierMeaning?:string
Paraphrased qualifier meaning when the qualifier is recognized (e.g. "NDC").
TelecomQuantity
Quantity Dispensed (442-E7). On the wire this is an unsigned integer string
with an implied 3-place decimal (NCPDP format 9(7)v999): "30000" means
30.000. We never parse it into a float: binary floating point would corrupt
the value, so we keep the verbatim source and, when it is all digits, surface
the implied decimal applied string-wise.
Properties
impliedDecimal?
readonlyoptionalimpliedDecimal?:string
source with the implied 3-place decimal inserted, when valid.
isValid
readonlyisValid:boolean
True when source is a non-empty run of digits.
source
readonlysource:string
The quantity exactly as it appeared on the wire.
TelecomRequestInput
The whole request to build: the fixed header and the variable segments.
Properties
header
readonlyheader:TelecomHeaderInput
The fixed Transaction Header fields.
segments
readonlysegments: readonlyTelecomSegmentInput[]
The request segments, in wire order.
TelecomSegment
A decoded segment: its identification code, name, and ordered fields.
Properties
byteOffset
readonlybyteOffset:number
Byte offset of the segment in the raw message.
fields
readonlyfields: readonlyTelecomField[]
The segment's data fields, in wire order. The AM field is not repeated
here once it has been read into segmentId; when it could not be
(MALFORMED_SEGMENT_ID), it stays in this list instead of being dropped.
name?
readonlyoptionalname?:string
Paraphrased segment name when segmentId is recognized.
segmentId
readonlysegmentId:string
The Segment Identification (111-AM) code, e.g. "07".
Always either exactly two characters or empty. It is empty when the segment
did not begin with an AM field (MISSING_SEGMENT_ID) and when it did
but that field's value was not two characters (MALFORMED_SEGMENT_ID); in
the second case the AM field itself is kept in fields, verbatim, so
no byte is lost. The bound is what makes this field safe for a consumer to
interpolate into its own diagnostics: fields[].value is not.
TelecomSegmentInput
A segment to build: its Segment Identification code and ordered fields.
Properties
fields
readonlyfields: readonlyTelecomFieldInput[]
The segment's data fields, in wire order.
segmentId
readonlysegmentId:string
The Segment Identification (111-AM) code, e.g. "07".
TelecomTransaction
A decoded Telecom transmission: the fixed header, the variable segments of the first transaction (field-id-keyed, in wire order), the header's declared transaction count, and any non-fatal warnings. Everything is frozen.
Properties
header
readonlyheader:TelecomHeader
The decoded fixed Transaction Header. For a response, the overlapping fields (version, transaction code, count, service provider) are lifted from the response header; request-only fields (BIN, PCN, …) are empty.
kind
readonlykind:"request"|"response"
Whether this is a request transmission (decoded against the 56-byte request header) or a response transmission (decoded against the response header).
profile?
readonlyoptionalprofile?:NcpdpProfile
The trading-partner profile in effect for this parse: either passed
explicitly via options.profile or resolved from the process-scoped
default. Present only when a profile applied; attribution only (v1 profiles
never alter the parse).
responseHeader?
readonlyoptionalresponseHeader?:TelecomResponseHeader
The decoded Response Transaction Header: present only when kind is "response".
segments
readonlysegments: readonlyTelecomSegment[]
The first transaction's segments, in wire order.
transactionCount
readonlytransactionCount:string
Declared number of transactions (109-A9), verbatim from the header.
warnings
readonlywarnings: readonlyNcpdpTelecomWarning[]
Non-fatal parse warnings: stable code + byte offset + field id, never PHI.
UnsupportedBody
A SCRIPT transaction body this parser recognizes but does not model. The raw transaction name is surfaced so a consumer can branch, without the parser pretending to understand it.
Properties
kind
readonlykind:"unsupported"
transaction?
readonlyoptionaltransaction?:string
The SCRIPT transaction element name (e.g. RxRenewalRequest), present only
when the element the sender used is one of
"./versions".SCRIPT_TRANSACTION_NAMES.
It is absent for any other element name, and that is deliberate rather
than a gap. A <Body> child name is chosen by the sender, so echoing it
onto the model would hand every downstream package an unbounded, wire-derived
string to build its own diagnostics out of. When it is absent, the warning's
position and the document itself are how you find the element.
VerifyBody
A SCRIPT <Verify>: a prescriber's verification acknowledgment.
Extends
Properties
code?
readonlyoptionalcode?:string
Primary response code, verbatim (<Code>).
Inherited from
description?
readonlyoptionaldescription?:string
Free-text description, verbatim (<Description>).
Inherited from
descriptionCode?
readonlyoptionaldescriptionCode?:string
Secondary description code, verbatim (<DescriptionCode>).
Inherited from
ResponseFields.descriptionCode
kind
readonlykind:"Verify"
XmlElement
A namespace-stripped, immutable view of an XML element. This is the only XML
shape the rest of the SCRIPT parser sees: the fast-xml-parser output is
transformed into this tree at load time so downstream code never depends on
the parser's representation.
Properties
attrs
readonlyattrs:Readonly<Record<string,string>>
Attributes, prefix-stripped, in document order.
children
readonlychildren: readonlyXmlElement[]
Child elements, in document order.
name
readonlyname:string
Local element name, namespace prefix stripped (e.g. Message).
text
readonlytext:string
Concatenated direct text content, verbatim (not trimmed).
Type Aliases
CodeSystem
CodeSystem =
"NDC"|"RXNORM"|"SNOMED"|"NCI"|"ICD10"|"UNKNOWN"
Drug/clinical code systems recognized in NCPDP SCRIPT product codes. SCRIPT
carries a qualifier alongside each coded value; we map common qualifiers to a
normalized system and fall back to "UNKNOWN" rather than guessing.
KnownScriptVersion
KnownScriptVersion = typeof
KNOWN_SCRIPT_VERSIONS[number]
Union of the explicitly-supported SCRIPT version literals.
LifecycleRequest
LifecycleRequest =
RxRenewalRequest|RxChangeRequest|CancelRx
A parsed SCRIPT prescription-lifecycle request body.
LifecycleRequestKind
LifecycleRequestKind =
"RxRenewalRequest"|"RxChangeRequest"|"CancelRx"
The SCRIPT prescription-lifecycle request transactions this parser models.
LifecycleResponse
LifecycleResponse =
RxRenewalResponse|RxChangeResponse|CancelRxResponse
A parsed SCRIPT prescription-lifecycle response body.
LifecycleResponseKind
LifecycleResponseKind =
"RxRenewalResponse"|"RxChangeResponse"|"CancelRxResponse"
The SCRIPT prescription-lifecycle response transactions this parser models.
NcpdpProfileEffect
NcpdpProfileEffect =
"relaxes"|"adds"|"requires"
The bucket a quirk falls into when rendered by NcpdpProfile.describe. Mirrors the roadmap's "what this profile relaxes / adds / requires" framing.
relaxes: the partner tolerates / emits a structural variation a strict baseline read would flag (e.g. a SCRIPT version stamp outside the explicitly supported set).adds: the partner emits extra spec-optional content (e.g. an additional Telecom response segment, a deeper reject-code taxonomy) a generic consumer might not expect.requires: the partner mandates a normally-situational element be present (e.g. a PBM that requires Person Code in the Insurance segment).
Example
import type { NcpdpProfileEffect } from "@cosyte/ncpdp/profiles";
const effect: NcpdpProfileEffect = "adds";
NcpdpStandard
NcpdpStandard =
"script"|"telecom"
Which NCPDP standard a quirk applies to. SCRIPT and Telecom are unrelated formats with disjoint warning registries; a quirk is grounded in exactly one.
Example
import type { NcpdpStandard } from "@cosyte/ncpdp/profiles";
const std: NcpdpStandard = "telecom";
NcpdpWarningCode
NcpdpWarningCode =
ScriptWarningCode|TelecomWarningCode
The union of every public warning code across both standards. A quirk's
expectedWarnings is drawn from this set and validated against it.
Example
import type { NcpdpWarningCode } from "@cosyte/ncpdp/profiles";
const code: NcpdpWarningCode = "NCPDP_TELECOM_UNKNOWN_REJECT_CODE";
NdcSegmentation
NdcSegmentation =
"5-4-2"|"5-4-1"|"5-3-2"|"4-4-2"|"11-digit"|"10-digit"|"unknown"
The labeler/product/package segmentation hint for an NDC. Real-world NDCs arrive in several digit groupings; we surface the detected shape rather than forcing a normalization the consumer may not want.
ResponseApproval
ResponseApproval =
"affirmative"|"negative"|"indeterminate"
A coarse, fail-safe classification of a ResponseOutcome for
consumers that only need "did the prescriber say yes?". A denial is never
"affirmative", and anything that is not a clean yes/no (including unknown)
is "indeterminate" so it is never mistaken for a grant.
ResponseBody
ResponseBody =
StatusBody|ErrorBody|VerifyBody
A parsed SCRIPT response transaction body.
ResponseDisposition
ResponseDisposition =
"success"|"error"|"verify"
How a SCRIPT response transaction dispositions the message it answers:
success (a <Status>), error (an <Error>), or verify (a <Verify>).
Derived purely from the response body kind so that an Error can never be
read as a success.
ResponseKind
ResponseKind =
"Status"|"Error"|"Verify"
The three SCRIPT response-transaction element names this parser models.
ResponseOutcome
ResponseOutcome =
"approved"|"approvedWithChanges"|"denied"|"deniedNewToFollow"|"replace"|"validated"|"unknown"
The prescriber's decision on a lifecycle request, detected purely from the
<Response> choice element. The mapping is one-directional and fail-safe: a
<Denied> is always "denied" and is never read as an approval, and a
response with no recognized choice is "unknown": never assumed approved.
approved:<Approved>: the request is granted as written.approvedWithChanges:<ApprovedWithChanges>: granted, but the prescriber altered the medication; the changed medication is carried in LifecycleResponseFields.medicationPrescribed.denied:<Denied>: the request is refused.deniedNewToFollow:<DenyNewToFollow>(renewal): denied, a new prescription will follow separately.replace:<Replace>: the prescriber is replacing the prescription.validated:<Validated>(change): the prescriber validated the request without approving or denying it.unknown: no recognized outcome choice was present.
ScriptBody
ScriptBody =
NewRx|ResponseBody|LifecycleRequest|LifecycleResponse|UnsupportedBody
The parsed body of a SCRIPT message.
ScriptBuildCode
ScriptBuildCode = typeof
SCRIPT_BUILD_CODES[keyof typeofSCRIPT_BUILD_CODES]
Union of the SCRIPT builder error code string literals.
ScriptFatalCode
ScriptFatalCode = typeof
SCRIPT_FATAL_CODES[keyof typeofSCRIPT_FATAL_CODES]
Union of the SCRIPT fatal error code string literals.
ScriptTransactionName
ScriptTransactionName = typeof
SCRIPT_TRANSACTION_NAMES[number]
Union of the SCRIPT transaction element names this parser will name.
ScriptWarningCode
ScriptWarningCode = typeof
SCRIPT_WARNING_CODES[keyof typeofSCRIPT_WARNING_CODES]
Union of the SCRIPT warning code string literals.
SigFieldProvenance
SigFieldProvenance =
"coded"|"derived"|"absent"
Where a decoded structured-SIG field's value came from.
"coded": the structured element carried a code (with an optional system qualifier); a SigField.code is present."derived": a value was read from the structured element but it was not coded; only SigField.text is present."absent": the structured element was missing or empty; neither a code nor text could be read. The field is not inferred from the free text.
TelecomBuildCode
TelecomBuildCode = typeof
TELECOM_BUILD_CODES[keyof typeofTELECOM_BUILD_CODES]
Union of the Telecom builder error code string literals.
TelecomFatalCode
TelecomFatalCode = typeof
TELECOM_FATAL_CODES[keyof typeofTELECOM_FATAL_CODES]
Union of the Telecom fatal error code string literals.
TelecomVersion
TelecomVersion = {
kind:"d0"; } | {kind:"f6";stamp:string; } | {kind:"unsupported";stamp:string; }
Classification of the version stamp peeked from a raw Telecom message.
"d0": the supported D.0 standard; decode the fixed header at D.0 offsets."f6": the emerging F6 stamp; recognized but not decoded (different layout)."unsupported": no recognizable version stamp; the byte layout is untrustworthy.
TelecomWarningCode
TelecomWarningCode = typeof
TELECOM_WARNING_CODES[keyof typeofTELECOM_WARNING_CODES]
Union of the Telecom warning code string literals.
VersionClassification
VersionClassification = {
kind:"known";version:KnownScriptVersion; } | {kind:"tolerated";version:string; } | {kind:"absent"; } | {kind:"unsupported";version:string; }
Outcome of classifying a declared SCRIPT version string.
Variables
D0_HEADER_LENGTH
constD0_HEADER_LENGTH:56=56
Byte length of the fixed vD.0 request Transaction Header.
Example
import { D0_HEADER_LENGTH } from "@cosyte/ncpdp/telecom";
D0_HEADER_LENGTH; // 56: the fixed-width vD.0 request header
FIELD_NAMES
constFIELD_NAMES:ReadonlyMap<string,string>
Paraphrased names for the safety-relevant B1 field identifiers this parser surfaces, keyed by their 2-character field id. A field whose id is absent here is still preserved verbatim: absence of a name means only that the parser has not labeled it, never that the field is invalid or droppable.
Example
import { FIELD_NAMES } from "@cosyte/ncpdp/telecom";
FIELD_NAMES.get("D7"); // "Product / Service ID"
FIELD_NAMES.get("ZZ"); // undefined: unlabeled, still preserved verbatim
FIELD_SEPARATOR
constFIELD_SEPARATOR: "\u001c" = "\x1c"
Field Separator (NCPDP "FS", ASCII 0x1C): separates fields within a segment.
Example
import { FIELD_SEPARATOR } from "@cosyte/ncpdp/telecom";
FIELD_SEPARATOR.charCodeAt(0); // 28 (0x1C)
GROUP_SEPARATOR
constGROUP_SEPARATOR: "\u001d" = "\x1d"
Group Separator (NCPDP "GS", ASCII 0x1D): separates transactions in a transmission.
Example
import { GROUP_SEPARATOR } from "@cosyte/ncpdp/telecom";
GROUP_SEPARATOR.charCodeAt(0); // 29 (0x1D)
KNOWN_SCRIPT_VERSIONS
constKNOWN_SCRIPT_VERSIONS: readonly ["2017071","2023011"]
SCRIPT versions this parser explicitly supports. Both are XML-era releases routed through Surescripts.
The pair is grounded in US federal regulation, which is public law and therefore the license-clean source for a version identifier (the standard itself is paywalled). Two sections carry it:
- 45 CFR 170.205(b) adopts exactly these two SCRIPT Implementation Guide
versions for electronic prescribing, at (b)(1) and (b)(2). It also states
that the Secretary's adoption of
2017071expires on January 1, 2028, after which2023011is the only SCRIPT version that paragraph adopts. - 42 CFR 423.160 (Medicare Part D electronic prescribing) requires at (b)(1) that a prescription or prescription-related information comply with a standard in 45 CFR 170.205(b), and incorporates both guides by reference at (c)(2) and (c)(3).
Scope, because the list is narrower than it looks. This is the set those
two sections adopt, not the set of SCRIPT versions NCPDP has ever published.
A version outside it may well be real; nothing public that this package can
cite would establish that, so it is not written down here. Narrowing the list
never refuses a message: a present-but-unrecognized stamp is still parsed
best-effort and reported as tolerated, per classifyVersion.
Example
import { KNOWN_SCRIPT_VERSIONS } from "@cosyte/ncpdp/script";
KNOWN_SCRIPT_VERSIONS.includes("2023011"); // true
PRODUCT_QUALIFIER_MEANINGS
constPRODUCT_QUALIFIER_MEANINGS:ReadonlyMap<string,string>
Paraphrased meanings for the Product/Service ID Qualifier (436-E1) values this parser recognizes. The codes are factual identifiers from the NCPDP Telecommunication standard; the meanings are our own short labels (no redistributed NCPDP prose). A qualifier outside this set is preserved verbatim with an undefined meaning: absence of a label never means the value is invalid.
Example
import { PRODUCT_QUALIFIER_MEANINGS } from "@cosyte/ncpdp/telecom";
PRODUCT_QUALIFIER_MEANINGS.get("03"); // "NDC" (National Drug Code)
profiles
constprofiles:object
Namespace object exposing the shipped built-in profiles, one per NCPDP
standard. Each is authored via the public defineProfile() API and grounded
in a real Tier-2 fixture.
Type Declaration
pbm
readonlypbm:NcpdpProfile
surescripts
readonlysurescripts:NcpdpProfile
Example
import { parseTelecom } from "@cosyte/ncpdp/telecom";
import { profiles } from "@cosyte/ncpdp/profiles";
const tx = parseTelecom(raw, { profile: profiles.pbm });
tx.profile?.name; // "pbm"
SCRIPT_BUILD_CODES
constSCRIPT_BUILD_CODES:object
Stable error codes for the SCRIPT builder. The builder is the conservative (emit) half of Postel's Law: it refuses to construct a message that is invalid by construction (with one of these codes) rather than emitting XML a downstream system would reject. Distinct from the parser's SCRIPT_FATAL_CODES.
Type Declaration
INVALID_CHARACTER
readonlyINVALID_CHARACTER:"NCPDP_SCRIPT_BUILD_INVALID_CHARACTER"="NCPDP_SCRIPT_BUILD_INVALID_CHARACTER"
A supplied value carries a character that is illegal in XML 1.0 text.
MISSING_MEDICATION
readonlyMISSING_MEDICATION:"NCPDP_SCRIPT_BUILD_MISSING_MEDICATION"="NCPDP_SCRIPT_BUILD_MISSING_MEDICATION"
A NewRx was built with no prescribed medication (a drug description is required).
MISSING_RESPONSE_CODE
readonlyMISSING_RESPONSE_CODE:"NCPDP_SCRIPT_BUILD_MISSING_RESPONSE_CODE"="NCPDP_SCRIPT_BUILD_MISSING_RESPONSE_CODE"
A <Status>/<Error>/<Verify> response was built without a <Code>.
Example
import { SCRIPT_BUILD_CODES } from "@cosyte/ncpdp/common";
SCRIPT_BUILD_CODES.MISSING_RESPONSE_CODE; // "NCPDP_SCRIPT_BUILD_MISSING_RESPONSE_CODE"
SCRIPT_BUILD_MESSAGES
constSCRIPT_BUILD_MESSAGES:Readonly<Record<ScriptBuildCode,string>>
The frozen message registry for SCRIPT builder errors: one fixed sentence per
code, and the only source an NcpdpScriptBuildError's message can come
from.
Example
import { SCRIPT_BUILD_CODES, SCRIPT_BUILD_MESSAGES } from "@cosyte/ncpdp/common";
SCRIPT_BUILD_MESSAGES[SCRIPT_BUILD_CODES.MISSING_MEDICATION];
SCRIPT_FATAL_CODES
constSCRIPT_FATAL_CODES:object
Fatal error codes for NCPDP SCRIPT parsing. A fatal is reserved for unrecoverable structural corruption: input that cannot be treated as a SCRIPT message at all. Everything recoverable is a warning instead (see "./warnings".SCRIPT_WARNING_CODES).
Type Declaration
EMPTY_INPUT
readonlyEMPTY_INPUT:"EMPTY_INPUT"="EMPTY_INPUT"
Input is empty or whitespace-only.
NO_MESSAGE_ROOT
readonlyNO_MESSAGE_ROOT:"NCPDP_SCRIPT_NO_MESSAGE_ROOT"="NCPDP_SCRIPT_NO_MESSAGE_ROOT"
Well-formed XML, but the root element is not a SCRIPT <Message>.
NOT_XML
readonlyNOT_XML:"NCPDP_SCRIPT_NOT_XML"="NCPDP_SCRIPT_NOT_XML"
Input is not well-formed XML, or carries a forbidden DOCTYPE/ENTITY.
UNSUPPORTED_VERSION
readonlyUNSUPPORTED_VERSION:"NCPDP_SCRIPT_UNSUPPORTED_VERSION"="NCPDP_SCRIPT_UNSUPPORTED_VERSION"
The declared SCRIPT version predates the XML SCRIPT era and is unsupported.
Example
import { SCRIPT_FATAL_CODES } from "@cosyte/ncpdp/common";
SCRIPT_FATAL_CODES.NOT_XML; // "NCPDP_SCRIPT_NOT_XML"
SCRIPT_FATAL_MESSAGES
constSCRIPT_FATAL_MESSAGES:Readonly<Record<ScriptFatalCode,string>>
The frozen message registry for SCRIPT fatals: one fixed sentence per code,
and the only source an NcpdpScriptParseError's message can come from.
Example
import { SCRIPT_FATAL_CODES, SCRIPT_FATAL_MESSAGES } from "@cosyte/ncpdp/common";
SCRIPT_FATAL_MESSAGES[SCRIPT_FATAL_CODES.EMPTY_INPUT]; // "SCRIPT input is empty."
SCRIPT_TRANSACTION_NAMES
constSCRIPT_TRANSACTION_NAMES: readonly ["GetMessage","Status","Error","RxChangeRequest","RxChangeResponse","RxRenewalRequest","RxRenewalResponse","Resupply","Verify","CancelRx","CancelRxResponse","RxFill","DrugAdministration","NewRxRequest","NewRx","NewRxResponseDenied","RxTransferInitiationRequest","RxTransfer","RxTransferConfirm","RxFillIndicatorChange","Recertification","REMSInitiationRequest","REMSInitiationResponse","REMSRequest","REMSResponse","RxHistoryRequest","RxHistoryResponse","PAInitiationRequest","PAInitiationResponse","PARequest","PAResponse","PAAppealRequest","PAAppealResponse","PACancelRequest","PACancelResponse","PANotification"]
SCRIPT transaction element names this parser will name, as opposed to model. It is a closed vocabulary the library owns, not something read out of a document, and it exists so that an unmodeled transaction can still be identified without copying a sender-chosen element name onto the model or into a diagnostic.
The list is the transaction vocabulary published in 42 CFR 423.160, the federal e-prescribing standards rule, verbatim and in its order. That source is public law, not the paywalled standard, which is why the names can be written down here at all. Being grounded rather than invented matters: an earlier draft of this list was written from memory and got three transfer names and the recertification names wrong while omitting the whole prior-authorization and REMS families, which would have silently stripped the identity off every ePA message this library saw.
One assumption is worth stating: the regulation lists transaction names in prose, and this list is matched against XML element local names. Those are the same artifact only insofar as the regulation transcribed the standard's element names, which the shape of the names strongly suggests but which cannot be confirmed against a public source, since the schemas are paywalled. If one of them turns out not to be the element name, that transaction is surfaced unnamed, which is the same fail-safe path a vendor extension takes.
A transaction the standard defines but that regulation does not name is surfaced as unmodeled and unnamed; so is a vendor extension. That is the intended default, because the alternative (repeat whatever the element was called) is what put document-derived bytes on a diagnostic surface. A consumer that needs the element name reads the document it already holds.
Note that the PHI gate cannot check this list: a closed set passes it by construction. What keeps it safe is that it stays closed and stays sourced, which is a property of review, not of a test.
Example
import { SCRIPT_TRANSACTION_NAMES } from "@cosyte/ncpdp/script";
SCRIPT_TRANSACTION_NAMES.includes("RxHistoryRequest"); // true
SCRIPT_WARNING_CODES
constSCRIPT_WARNING_CODES:object
Stable warning codes for NCPDP SCRIPT parsing. Per Postel's Law, the parser is lenient: anything recoverable yields a warning with one of these codes rather than throwing. Codes are part of the public contract: renaming one is a breaking change.
Type Declaration
LIFECYCLE_AMBIGUOUS_OUTCOME
readonlyLIFECYCLE_AMBIGUOUS_OUTCOME:"NCPDP_SCRIPT_LIFECYCLE_AMBIGUOUS_OUTCOME"="NCPDP_SCRIPT_LIFECYCLE_AMBIGUOUS_OUTCOME"
A lifecycle response (RxRenewalResponse/RxChangeResponse/CancelRxResponse)
carried more than one outcome choice (e.g. both <Approved> and <Denied>);
the most conservative outcome (a denial before an approval) is reported so an
approval can never mask a denial.
LIFECYCLE_OUTCOME_UNRECOGNIZED
readonlyLIFECYCLE_OUTCOME_UNRECOGNIZED:"NCPDP_SCRIPT_LIFECYCLE_OUTCOME_UNRECOGNIZED"="NCPDP_SCRIPT_LIFECYCLE_OUTCOME_UNRECOGNIZED"
A lifecycle response carried no recognized outcome choice; the outcome is
surfaced as "unknown" rather than being assumed to be an approval.
MISSING_REQUIRED_ELEMENT
readonlyMISSING_REQUIRED_ELEMENT:"NCPDP_SCRIPT_MISSING_REQUIRED_ELEMENT"="NCPDP_SCRIPT_MISSING_REQUIRED_ELEMENT"
A required element for the detected transaction was missing; left undefined.
RESPONSE_AMBIGUOUS_DISPOSITION
readonlyRESPONSE_AMBIGUOUS_DISPOSITION:"NCPDP_SCRIPT_RESPONSE_AMBIGUOUS_DISPOSITION"="NCPDP_SCRIPT_RESPONSE_AMBIGUOUS_DISPOSITION"
More than one response transaction (<Status>/<Error>/<Verify>) was
present in one body; the most conservative disposition (error first) is
reported so a failure is never masked by a co-present success.
SIG_AMBIGUOUS_DOSE
readonlySIG_AMBIGUOUS_DOSE:"NCPDP_SCRIPT_SIG_AMBIGUOUS_DOSE"="NCPDP_SCRIPT_SIG_AMBIGUOUS_DOSE"
A structured dose element was present but no unambiguous dose quantity could
be derived from it. The dose is surfaced as absent (provenance
"absent") rather than a guessed value, so an ambiguous SIG never yields a
confident dose.
SIG_STRUCTURED_LOSSY
readonlySIG_STRUCTURED_LOSSY:"NCPDP_SCRIPT_SIG_STRUCTURED_LOSSY"="NCPDP_SCRIPT_SIG_STRUCTURED_LOSSY"
A structured <Sig> was decoded into typed dosing components. The decode is
best-effort and lossy; the free-text SigText remains the source of
truth and is preserved verbatim. Raised once per medication carrying any
structured component so a consumer never mistakes the additive structured
view for an authoritative one.
STRENGTH_CODED_AND_EXPLICIT
readonlySTRENGTH_CODED_AND_EXPLICIT:"NCPDP_SCRIPT_STRENGTH_CODED_AND_EXPLICIT"="NCPDP_SCRIPT_STRENGTH_CODED_AND_EXPLICIT"
A coded drug and an explicit Strength were both present; both surfaced, never reconciled.
UNSUPPORTED_TRANSACTION
readonlyUNSUPPORTED_TRANSACTION:"NCPDP_SCRIPT_UNSUPPORTED_TRANSACTION"="NCPDP_SCRIPT_UNSUPPORTED_TRANSACTION"
The transaction body is a SCRIPT type this parser does not model; surfaced as unsupported.
UNSUPPORTED_VERSION_TOLERATED
readonlyUNSUPPORTED_VERSION_TOLERATED:"NCPDP_SCRIPT_UNSUPPORTED_VERSION_TOLERATED"="NCPDP_SCRIPT_UNSUPPORTED_VERSION_TOLERATED"
Version is a plausible SCRIPT release we don't explicitly support; tolerated.
VERSION_ABSENT
readonlyVERSION_ABSENT:"NCPDP_SCRIPT_VERSION_ABSENT"="NCPDP_SCRIPT_VERSION_ABSENT"
No version could be determined from the message; parsed best-effort.
Example
import { SCRIPT_WARNING_CODES } from "@cosyte/ncpdp/common";
SCRIPT_WARNING_CODES.VERSION_ABSENT; // "NCPDP_SCRIPT_VERSION_ABSENT"
SCRIPT_WARNING_MESSAGES
constSCRIPT_WARNING_MESSAGES:Readonly<Record<ScriptWarningCode,string>>
The frozen message registry: one fixed sentence per SCRIPT warning code, and
the only source a warning's message can come from.
This is the mechanism, not a convention. scriptWarning takes no value
parameter at all, so there is no interpolation site for a document-derived
string to reach: a message is a table lookup or it does not exist. Everything
a consumer needs to locate the problem travels in the code and the
ScriptPosition, whose path is built from element names this parser
recognizes rather than from names a sender chose.
Example
import { SCRIPT_WARNING_CODES, SCRIPT_WARNING_MESSAGES } from "@cosyte/ncpdp/common";
SCRIPT_WARNING_MESSAGES[SCRIPT_WARNING_CODES.VERSION_ABSENT];
// "No SCRIPT version declared; parsed best-effort."
SEGMENT_ID_LENGTH
constSEGMENT_ID_LENGTH:2=2
Wire width of the Segment Identification (111-AM) code: two characters in the Telecommunication standard, which both halves of this library treat as a structural shape rather than a hint. The parser will not promote an AM value of any other length to TelecomSegment.segmentId, and the builder refuses to construct one, so the bound holds however a transaction was made.
Example
import { SEGMENT_ID_LENGTH } from "@cosyte/ncpdp/telecom";
SEGMENT_ID_LENGTH; // 2
SEGMENT_NAMES
constSEGMENT_NAMES:ReadonlyMap<string,string>
Segment Identification (111-AM) codes modeled by this parser, mapped to our own paraphrased names. Codes are factual identifiers from the NCPDP Telecommunication standard; the names are ours (no redistributed NCPDP prose). A code outside this set is preserved verbatim with an undefined name.
Example
import { SEGMENT_NAMES } from "@cosyte/ncpdp/telecom";
SEGMENT_NAMES.get("07"); // "Claim"
SEGMENT_NAMES.get("99"); // undefined: preserved verbatim, just not labeled
SEGMENT_SEPARATOR
constSEGMENT_SEPARATOR: "\u001e" = "\x1e"
Segment Separator (NCPDP "RS", ASCII 0x1E): separates segments within a transaction.
Example
import { SEGMENT_SEPARATOR } from "@cosyte/ncpdp/telecom";
SEGMENT_SEPARATOR.charCodeAt(0); // 30 (0x1E)
TELECOM_BUILD_CODES
constTELECOM_BUILD_CODES:object
Stable error codes for the Telecom builder. The builder is the conservative (emit) half of Postel's Law: it refuses to construct a message that is invalid by construction, with one of these codes, rather than producing malformed wire output that a downstream system would have to reject. These are distinct from the parser's TELECOM_FATAL_CODES.
Type Declaration
EMBEDDED_CONTROL_CHARACTER
readonlyEMBEDDED_CONTROL_CHARACTER:"NCPDP_TELECOM_BUILD_EMBEDDED_CONTROL_CHARACTER"="NCPDP_TELECOM_BUILD_EMBEDDED_CONTROL_CHARACTER"
A field separator / group separator / segment separator appeared inside supplied data.
FIELD_TOO_LONG
readonlyFIELD_TOO_LONG:"NCPDP_TELECOM_BUILD_FIELD_TOO_LONG"="NCPDP_TELECOM_BUILD_FIELD_TOO_LONG"
A fixed-width header field was supplied with a value longer than its wire width.
INVALID_FIELD_ID
readonlyINVALID_FIELD_ID:"NCPDP_TELECOM_BUILD_INVALID_FIELD_ID"="NCPDP_TELECOM_BUILD_INVALID_FIELD_ID"
A data field was supplied without a 2-character field identifier.
INVALID_SEGMENT_ID
readonlyINVALID_SEGMENT_ID:"NCPDP_TELECOM_BUILD_INVALID_SEGMENT_ID"="NCPDP_TELECOM_BUILD_INVALID_SEGMENT_ID"
A segment was supplied with a Segment Identification (111-AM) code that is
not exactly 2 characters. The builder refuses it for the same reason the
parser refuses to promote one: 111-AM is 2 characters on the wire, and a
longer value would put unbounded caller data on segment.segmentId, which
the model documents as bounded and safe for a consumer to interpolate.
MISSING_SEGMENT_ID
readonlyMISSING_SEGMENT_ID:"NCPDP_TELECOM_BUILD_MISSING_SEGMENT_ID"="NCPDP_TELECOM_BUILD_MISSING_SEGMENT_ID"
A segment was supplied with no Segment Identification code.
MISSING_TRANSACTION_CODE
readonlyMISSING_TRANSACTION_CODE:"NCPDP_TELECOM_BUILD_MISSING_TRANSACTION_CODE"="NCPDP_TELECOM_BUILD_MISSING_TRANSACTION_CODE"
No Transaction Code (103-A3) was supplied; a request cannot be routed without one.
Example
import { TELECOM_BUILD_CODES } from "@cosyte/ncpdp/telecom";
TELECOM_BUILD_CODES.MISSING_TRANSACTION_CODE; // "NCPDP_TELECOM_BUILD_MISSING_TRANSACTION_CODE"
TELECOM_BUILD_MESSAGES
constTELECOM_BUILD_MESSAGES:Readonly<Record<TelecomBuildCode,string>>
The frozen message registry for Telecom builder errors.
Every entry names the rule that was broken, never the offending value. A caller who supplied the value knows what it was; the library quoting it back is how a cardholder id ends up in a log line. Where the rejection is about one fixed-header slot, the slot travels as NcpdpTelecomBuildError.headerField, which is typed closed.
Example
import { TELECOM_BUILD_CODES, TELECOM_BUILD_MESSAGES } from "@cosyte/ncpdp/telecom";
TELECOM_BUILD_MESSAGES[TELECOM_BUILD_CODES.INVALID_FIELD_ID];
TELECOM_FATAL_CODES
constTELECOM_FATAL_CODES:object
Fatal error codes for NCPDP Telecommunication-standard parsing. A fatal is reserved for structure that cannot be treated as a Telecom transmission at all: input too short to hold the fixed Transaction Header, an unframeable body, or a version whose byte layout this reader cannot trust. Everything recoverable is a warning instead (see "./warnings".TELECOM_WARNING_CODES).
Type Declaration
EMPTY_INPUT
readonlyEMPTY_INPUT:"EMPTY_INPUT"="EMPTY_INPUT"
Input is empty or whitespace-only.
INVALID_FRAMING
readonlyINVALID_FRAMING:"NCPDP_TELECOM_INVALID_FRAMING"="NCPDP_TELECOM_INVALID_FRAMING"
The message body carries content but none of the framing control characters needed to tokenize it into segments and fields; a separator is never guessed.
NO_HEADER
readonlyNO_HEADER:"NCPDP_TELECOM_NO_HEADER"="NCPDP_TELECOM_NO_HEADER"
Input is too short to contain the fixed Transaction Header.
UNSUPPORTED_VERSION
readonlyUNSUPPORTED_VERSION:"NCPDP_TELECOM_UNSUPPORTED_VERSION"="NCPDP_TELECOM_UNSUPPORTED_VERSION"
A version stamp is present but is neither the supported D.0 nor a recognized future stamp (e.g. F6); the fixed-header byte layout cannot be trusted, so the message is refused rather than decoded against the wrong offsets.
Example
import { TELECOM_FATAL_CODES } from "@cosyte/ncpdp/telecom";
TELECOM_FATAL_CODES.NO_HEADER; // "NCPDP_TELECOM_NO_HEADER"
TELECOM_FATAL_MESSAGES
constTELECOM_FATAL_MESSAGES:Readonly<Record<TelecomFatalCode,string>>
The frozen message registry for Telecom fatals: one fixed sentence per code,
and the only source an NcpdpTelecomParseError's message can come from.
The two length-related entries name the parser's own fixed header widths rather than the input's length. A byte count is a number and could not carry a value on its own, but it is also nothing a caller cannot measure from the input it just passed in, and dropping it is what lets a test assert that a message equals its registry entry exactly.
Example
import { TELECOM_FATAL_CODES, TELECOM_FATAL_MESSAGES } from "@cosyte/ncpdp/telecom";
TELECOM_FATAL_MESSAGES[TELECOM_FATAL_CODES.EMPTY_INPUT]; // "Input is empty."
TELECOM_WARNING_CODES
constTELECOM_WARNING_CODES:object
Stable warning codes for NCPDP Telecommunication-standard parsing. Per Postel's Law, the parser is lenient: anything recoverable yields a warning with one of these codes rather than throwing, and the underlying bytes are always preserved verbatim so nothing is silently dropped. Codes are part of the public contract. Renaming one is a breaking change.
Type Declaration
COB_COUNT_MISMATCH
readonlyCOB_COUNT_MISMATCH:"NCPDP_TELECOM_COB_COUNT_MISMATCH"="NCPDP_TELECOM_COB_COUNT_MISMATCH"
A Coordination-of-Benefits segment declared an other-payer/other-payment count (337-4C request, 355-NT response) that disagrees with the number of other-payer blocks decoded. Every block is still surfaced; this flags a possible mis-read COB chain so secondary-payer money is never silently dropped or duplicated.
COMPOUND_COUNT_MISMATCH
readonlyCOMPOUND_COUNT_MISMATCH:"NCPDP_TELECOM_COMPOUND_COUNT_MISMATCH"="NCPDP_TELECOM_COMPOUND_COUNT_MISMATCH"
A Compound segment declared an ingredient count (447-EC) that disagrees with the number of ingredient occurrences actually decoded. Every ingredient is still surfaced verbatim; this flags a possible truncated/over-stuffed compound so a missing or extra ingredient is never silent (a compound with a missing ingredient is, clinically, a different medication).
MALFORMED_FIELD
readonlyMALFORMED_FIELD:"NCPDP_TELECOM_MALFORMED_FIELD"="NCPDP_TELECOM_MALFORMED_FIELD"
A field token was too short to carry a 2-character field identifier. It is preserved verbatim (with an empty id) rather than dropped.
MALFORMED_SEGMENT_ID
readonlyMALFORMED_SEGMENT_ID:"NCPDP_TELECOM_MALFORMED_SEGMENT_ID"="NCPDP_TELECOM_MALFORMED_SEGMENT_ID"
A segment led with an AM field whose value is not a 2-character Segment
Identification code. Off-shape bytes there are almost always a framing
failure (a dropped field separator runs the rest of the segment into the
code), so the value is not promoted to segment.segmentId: it stays in
the segment's fields as the AM field, verbatim and nothing dropped, and
the segment id reads empty. Keeping it out of the id also keeps unbounded
wire bytes off a structural identifier a downstream package would build a
diagnostic from.
MISSING_SEGMENT_ID
readonlyMISSING_SEGMENT_ID:"NCPDP_TELECOM_MISSING_SEGMENT_ID"="NCPDP_TELECOM_MISSING_SEGMENT_ID"
A segment's first field was not the Segment Identification (AM). The
segment is still surfaced with its fields preserved, but its segment id is
left empty since it could not be read from the expected position.
MULTI_TRANSACTION_TRUNCATED
readonlyMULTI_TRANSACTION_TRUNCATED:"NCPDP_TELECOM_MULTI_TRANSACTION_TRUNCATED"="NCPDP_TELECOM_MULTI_TRANSACTION_TRUNCATED"
The transmission carried more than one group-separator-delimited transaction. The parser decodes the first transaction's segments only and surfaces this warning so additional transactions are never silently ignored.
STATUS_CONFLICT
readonlySTATUS_CONFLICT:"NCPDP_TELECOM_STATUS_CONFLICT"="NCPDP_TELECOM_STATUS_CONFLICT"
A response declared a paid/captured/approved Transaction Response Status (112-AN) while also carrying one or more reject codes. The two disagree; the library resolves the disposition to rejected (a reject always wins: a consumer must never be told a rejected claim was paid) and raises this so the conflict is visible, never silent.
UNKNOWN_DUR_REASON
readonlyUNKNOWN_DUR_REASON:"NCPDP_TELECOM_UNKNOWN_DUR_REASON"="NCPDP_TELECOM_UNKNOWN_DUR_REASON"
A request DUR/PPS Reason For Service code (439-E4) is not one this parser recognizes. The code is preserved verbatim and surfaced; only the human-readable description is absent. The interaction is never dropped.
UNKNOWN_REJECT_CODE
readonlyUNKNOWN_REJECT_CODE:"NCPDP_TELECOM_UNKNOWN_REJECT_CODE"="NCPDP_TELECOM_UNKNOWN_REJECT_CODE"
A Reject Code (511-FB) value is not one this parser recognizes. The code is
preserved verbatim and surfaced with known: false; only the human-readable
description is absent. The reject is never dropped or reinterpreted.
UNKNOWN_RESPONSE_STATUS
readonlyUNKNOWN_RESPONSE_STATUS:"NCPDP_TELECOM_UNKNOWN_RESPONSE_STATUS"="NCPDP_TELECOM_UNKNOWN_RESPONSE_STATUS"
A Transaction Response Status (112-AN) value is not one this parser models.
The status is preserved verbatim and the disposition reads "unknown":
never assumed paid, so an unrecognized status can never imply payment.
UNKNOWN_SEGMENT
readonlyUNKNOWN_SEGMENT:"NCPDP_TELECOM_UNKNOWN_SEGMENT"="NCPDP_TELECOM_UNKNOWN_SEGMENT"
A segment's identification code is not one this parser models. The segment and its fields are preserved verbatim (keyed by their field ids) and surfaced; only the human-readable segment name is left undefined.
VF6_NOT_DECODED
readonlyVF6_NOT_DECODED:"NCPDP_TELECOM_VF6_NOT_DECODED"="NCPDP_TELECOM_VF6_NOT_DECODED"
The message declares the emerging F6 version stamp. F6 changes the fixed header layout (an 8-byte IIN replaces the 6-byte BIN, among other changes), so this D.0 reader recognizes but does not decode it: the version is surfaced and the body is left untokenized rather than read against the wrong offsets.
Example
import { TELECOM_WARNING_CODES } from "@cosyte/ncpdp/telecom";
TELECOM_WARNING_CODES.UNKNOWN_SEGMENT; // "NCPDP_TELECOM_UNKNOWN_SEGMENT"
TELECOM_WARNING_MESSAGES
constTELECOM_WARNING_MESSAGES:Readonly<Record<TelecomWarningCode,string>>
The frozen message registry: one fixed sentence per Telecom warning code, and
the only source a warning's message can come from.
This is the mechanism, not a convention. telecomWarning takes no value
parameter at all, so there is no interpolation site for wire bytes to reach.
A Telecom transmission is PHI-dense in almost every field, and a message that
quoted so much as a segment code could quote an NDC or a prescription number
instead the moment a field separator went missing. What a consumer needs to
locate the problem travels in the code and the TelecomPosition: a
byte offset and, when known, a 2-character field identifier.
Example
import { TELECOM_WARNING_CODES, TELECOM_WARNING_MESSAGES } from "@cosyte/ncpdp/telecom";
TELECOM_WARNING_MESSAGES[TELECOM_WARNING_CODES.UNKNOWN_SEGMENT];
// "The segment at this offset declares a code this parser does not model; preserved verbatim."
VERSION
constVERSION:string="0.0.7"
Library version string, synced with package.json#version by the build.
Example
import { VERSION } from "@cosyte/ncpdp";
console.log(VERSION);
Functions
approvalOf()
approvalOf(
outcome):ResponseApproval
Map a ResponseOutcome to its fail-safe ResponseApproval. Total
and one-directional: only an outright approval is "affirmative"; denials are
"negative"; everything else (replace/validated/unknown) is
"indeterminate".
Parameters
outcome
The detected response outcome.
Returns
The coarse approval classification.
Example
approvalOf("denied"); // "negative"
approvalOf("approvedWithChanges"); // "affirmative"
approvalOf("unknown"); // "indeterminate"
buildNewRx()
buildNewRx(
input):ScriptMessage
Build a spec-clean SCRIPT NewRx message. The conservative (emit) half of Postel's Law: it refuses to construct a NewRx with no prescribed-medication description (SCRIPT_BUILD_CODES.MISSING_MEDICATION) or carrying an XML-illegal control character (SCRIPT_BUILD_CODES.INVALID_CHARACTER), throwing NcpdpScriptBuildError rather than emitting an unusable message.
The returned ScriptMessage serializes (via
"./serialize".serializeScript / toString()) to XML that re-parses with
zero warnings.
Parameters
input
The header, parties, and medication to build.
Returns
A frozen ScriptMessage carrying a NewRx body.
Throws
NcpdpScriptBuildError when the input cannot form a spec-clean NewRx.
Example
import { buildNewRx } from "@cosyte/ncpdp/script";
const msg = buildNewRx({
header: { version: "2017071", messageId: "SYNTH-1" },
medication: { description: "Amoxicillin 500 MG Oral Capsule" },
});
msg.toString(); // canonical SCRIPT XML
buildScriptResponse()
buildScriptResponse(
input):ScriptMessage
Build a spec-clean SCRIPT response (<Status>/<Error>/<Verify>) message.
Refuses to construct a response with no <Code>
(SCRIPT_BUILD_CODES.MISSING_RESPONSE_CODE): the one field the parser
itself flags as required, or an XML-illegal control character
(SCRIPT_BUILD_CODES.INVALID_CHARACTER).
Parameters
input
The response kind, code, optional description, and header.
Returns
A frozen ScriptMessage carrying the response body.
Throws
NcpdpScriptBuildError when the input cannot form a spec-clean response.
Example
import { buildScriptResponse } from "@cosyte/ncpdp/script";
const ack = buildScriptResponse({
kind: "Status",
code: "010",
header: { relatesToMessageId: "SYNTH-1" },
});
ack.disposition; // "success"
buildTelecomRequest()
buildTelecomRequest(
input):TelecomTransaction
Build a spec-clean NCPDP Telecommunication vD.0 request transaction from a structured model. The conservative (emit) half of Postel's Law: it refuses to construct a message that is invalid by construction: a missing Transaction Code, a missing or non-2-character Segment Identification, a non-2-character field id, an embedded FS/GS/RS control character, or an over-long fixed-header field: throwing a typed NcpdpTelecomBuildError rather than producing malformed wire output a downstream processor would have to reject.
The returned transaction is frozen and ready for
"./serialize".serializeTelecom; the round trip
parseTelecom(serializeTelecom(buildTelecomRequest(input))) re-parses with zero
warnings.
Parameters
input
The header fields and segments to build.
Returns
A frozen, valid-by-construction TelecomTransaction.
Throws
NcpdpTelecomBuildError when the input cannot form a spec-clean message.
Example
import { buildTelecomRequest, serializeTelecom } from "@cosyte/ncpdp/telecom";
const t = buildTelecomRequest({
header: { transactionCode: "B1", binNumber: "999999" },
segments: [{ segmentId: "07", fields: [{ id: "D2", value: "RX0000001" }] }],
});
serializeTelecom(t); // canonical wire string
cancelRx()
cancelRx(
message):CancelRx|undefined
Convenience accessor: the CancelRx body, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
CancelRx | undefined
The cancel body, or undefined.
Example
cancelRx(parseScript(xml))?.medicationPrescribed?.description;
cancelRxResponse()
cancelRxResponse(
message):CancelRxResponse|undefined
Convenience accessor: the CancelRxResponse body, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
CancelRxResponse | undefined
The cancel-response body, or undefined.
Example
cancelRxResponse(parseScript(xml))?.outcome; // "approved" | "denied" | …
claim()
claim(
transaction):TelecomClaim|undefined
Build the B1/B2/B3 request view over a parsed Telecom transaction.
Parameters
transaction
A transaction from parseTelecom.
Returns
TelecomClaim | undefined
The TelecomClaim view, or undefined when no segments decoded.
Example
claim(parseTelecom(rawClaim))?.product?.id; // the dispensed NDC
claimView()
claimView(
transactionCode,segments):TelecomClaim|undefined
Build the B1/B2/B3 request view over a decoded Telecom transaction. Returns
undefined only when the transaction carries no segments at all; otherwise it
surfaces whatever safety-relevant fields are present, each optional.
Parameters
transactionCode
string
Transaction Code (103-A3) from the header.
segments
readonly TelecomSegment[]
The decoded segments in wire order.
Returns
TelecomClaim | undefined
The claim view, or undefined when there are no segments to read.
Example
const t = parseTelecom(raw);
claimView(t.header.transactionCode, t.segments)?.product?.id; // the NDC
classifyVersion()
classifyVersion(
raw):VersionClassification
Classify a declared SCRIPT version string.
- A known XML version →
known. - A legacy dotted major (pre-XML, e.g.
10.6) →unsupported(fatal). - Absent/blank →
absent(parse best-effort + warn). - Anything else present-but-unrecognized →
tolerated(parse best-effort + warn), since refusing an odd-but-present version string would violate Postel's Law for a message that is still XML.
Parameters
raw
string | undefined
The version attribute value, or undefined when absent.
Returns
Example
classifyVersion("2017071"); // { kind: "known", version: "2017071" }
classifyVersion("2099001"); // { kind: "tolerated", version: "2099001" }
classifyVersion("10.6"); // { kind: "unsupported", version: "10.6" }
classifyVersion(undefined); // { kind: "absent" }
codedValue()
codedValue(
value,qualifier):CodedValue
Build a frozen CodedValue from a raw code and qualifier, recognizing the code system in the process.
Parameters
value
string
The code, verbatim.
qualifier
string
The accompanying qualifier string.
Returns
A frozen CodedValue.
Example
codedValue("00002821501", "ND").system; // "NDC"
decimalValue()
decimalValue(
raw):DecimalValue
Wrap a raw textual value as a DecimalValue without converting to a
float. Invalid input is preserved as-is with isValid: false: lenient parse,
never a throw.
Parameters
raw
string
The textual value from the message (already trimmed by the caller).
Returns
A frozen DecimalValue.
Example
decimalValue("0.1").isValid; // true
decimalValue("1/2").isValid; // false (still preserved as source)
decodeD0Header()
decodeD0Header(
raw):TelecomHeader
Decode the fixed-length D.0 Transaction Header from the head of a raw message.
The caller guarantees raw.length >= D0_HEADER_LENGTH. Each positional
field is sliced and trimmed of pad whitespace.
Parameters
raw
string
The raw message text (length already validated by the caller).
Returns
A frozen TelecomHeader.
Example
const h = decodeD0Header("610279D0B1".padEnd(56, " "));
h.binNumber; // "610279"
h.transactionCode; // "B1"
deepFreeze()
deepFreeze<
T>(value):T
Recursively freeze an object graph so parsed models are immutable by default. Mutation, where allowed, happens only through explicit builder/setter methods that return new instances: never by reaching into a returned model.
Type Parameters
T
T
The value type.
Parameters
value
T
The value to deep-freeze in place.
Returns
T
The same reference, now deeply frozen.
Example
const m = deepFreeze({ a: { b: 1 } });
Object.isFrozen(m.a); // true
defineProfile()
defineProfile(
opts):NcpdpProfile
Build a readonly NcpdpProfile from a validated spec. Invalid input
throws "./errors.js".NcpdpProfileError with an actionable message:
missing/empty name, unknown option key (with a typo hint), or a quirk that
violates the locked hard rule (missing fixture, bad standard/effect,
unknown expectedWarnings code).
extends composes parent profiles: lineage flattens + dedupes, quirks merge
by id (child wins on collision, non-colliding parent quirks survive), and
description is last-wins.
Parameters
opts
Returns
Example
import { defineProfile } from "@cosyte/ncpdp/profiles";
const pbm = defineProfile({
name: "pbm",
description: "PBM / clearinghouse Telecom claim conventions",
quirks: [
{
id: "person-code-required",
standard: "telecom",
effect: "requires",
summary: "Insurance segment carries a Person Code (303-C3).",
fixture: "telecom/pbm-person-code.ncpdp",
sourceCategory: "NCPDP Telecommunication vD.0: Person Code (303-C3)",
},
],
});
pbm.name; // "pbm"
pbm.lineage; // ["pbm"]
pbm.describe().requires; // [{ id: "person-code-required", ... }]
detectVersion()
detectVersion(
raw):TelecomVersion
Peek the version stamp of a raw Telecom message without trusting the rest of the header layout.
D.0 carries "D0" in the Version/Release field at offset 6; F6 (which widens
the leading identification field) carries "F6" at offset 8. Both candidate
positions are checked. Anything else is "unsupported": the offsets cannot be
trusted, so the caller refuses rather than guesses.
Parameters
raw
string
The raw message text.
Returns
The TelecomVersion classification.
Example
detectVersion("123456D0B1…").kind; // "d0"
dispositionOf()
dispositionOf(
kind):ResponseDisposition
Map a response body kind to its disposition. The mapping is total and
one-directional: an ErrorBody is always "error".
Parameters
kind
The response body kind.
Returns
The disposition.
Example
dispositionOf("Error"); // "error"
error()
error(
message):ErrorBody|undefined
Convenience accessor: the <Error> (negative-acknowledgment) body of a
message, or undefined. An Error is never read as a success.
Parameters
message
A parsed ScriptMessage.
Returns
ErrorBody | undefined
The Error body, or undefined when the message is not an Error.
Example
error(parseScript(xml))?.code;
extractStructuredSig()
extractStructuredSig(
medEl,path,warnings):StructuredSig|undefined
Decode a structured SCRIPT <Sig> element into a StructuredSig, or
return undefined when no <Sig> is present under medEl.
Lenient and lossy by construction: every component is read independently and
tagged with its provenance; unrecoverable ambiguity downgrades a field to
"absent" and warns rather than guessing. The free-text <SigText> is always
preserved verbatim. Raises "../common/warnings".SCRIPT_WARNING_CODES.SIG_STRUCTURED_LOSSY
once when any structured component is decoded.
Parameters
medEl
The <MedicationPrescribed> (or equivalent) element.
path
string
XPath-style location of medEl (for warning context).
warnings
Sink that collects non-fatal warnings.
Returns
StructuredSig | undefined
A frozen StructuredSig, or undefined when no <Sig> exists.
Example
const warnings: NcpdpScriptWarning[] = [];
const sig = extractStructuredSig(medEl, "/Message/Body/NewRx/MedicationPrescribed", warnings);
sig?.sigText; // verbatim free text: the source of truth
sig?.route.code?.system; // "SNOMED" when the route was coded
fieldValue()
fieldValue(
segment,fieldId):string|undefined
Read the verbatim value of the first field with a given id within a segment.
Parameters
segment
TelecomSegment | undefined
The segment to read, or undefined.
fieldId
string
The 2-character field id, e.g. "D7".
Returns
string | undefined
The field value, or undefined when the segment or field is absent.
Example
fieldValue(findSegment(t.segments, "07"), "D7"); // the Product/Service ID
findSegment()
findSegment(
segments,code):TelecomSegment|undefined
Find the first segment with a given identification code.
Parameters
segments
readonly TelecomSegment[]
The decoded segments.
code
string
The 2-character Segment Identification code, e.g. "07".
Returns
TelecomSegment | undefined
The first matching segment, or undefined.
Example
findSegment(t.segments, "07")?.name; // "Claim"
getDefaultProfile()
getDefaultProfile():
NcpdpProfile|undefined
Return the current default profile, or undefined if none is registered.
Returns
NcpdpProfile | undefined
Example
import { getDefaultProfile } from "@cosyte/ncpdp/profiles";
const p = getDefaultProfile();
if (p !== undefined) console.log("default profile:", p.name);
impliedThreeDecimal()
impliedThreeDecimal(
digits):string|undefined
Apply the NCPDP implied 3-place decimal to an integer digit string, string-wise
(never via float). Returns undefined for non-digit input.
Parameters
digits
string
The verbatim integer string from the wire.
Returns
string | undefined
The value with a 3-place fraction, or undefined if not all digits.
Example
impliedThreeDecimal("30000"); // "30.000"
impliedThreeDecimal("5"); // "0.005"
joinPath()
joinPath(
parent,child):string
Append a child step to an XPath-style location string.
Parameters
parent
string
The parent path, e.g. /Message/Body.
child
string
The child element name, e.g. NewRx.
Returns
string
The joined path, e.g. /Message/Body/NewRx.
Example
joinPath("/Message/Body", "NewRx"); // "/Message/Body/NewRx"
ndcValue()
ndcValue(
raw):NdcValue
Classify an NDC string into a NdcSegmentation hint. Hyphenated forms
are matched by their digit groups; bare digit strings are classified by total
length. Anything else is "unknown".
Parameters
raw
string
The NDC value as it appeared on the wire.
Returns
A frozen NdcValue.
Example
ndcValue("0002-8215-01").segmentation; // "4-4-2"
ndcValue("00002821501").segmentation; // "11-digit"
newRx()
newRx(
message):NewRx|undefined
Convenience accessor: the NewRx body of a message, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
NewRx | undefined
The NewRx body, or undefined when the message is another transaction.
Example
const rx = newRx(parseScript(xml));
rx?.patient?.name?.lastName;
parseScript()
parseScript(
raw,options?):ScriptMessage
Parse a raw NCPDP SCRIPT XML string into an immutable ScriptMessage.
Liberal on input (Postel's Law): recoverable anomalies become warnings with
stable codes and XPath context. Fatal only for unrecoverable structure:
empty input, non-XML / entity-bearing input, a non-<Message> root, or a
pre-XML legacy SCRIPT version.
Parameters
raw
string
The raw SCRIPT XML.
options?
Optional ParseScriptOptions.
Returns
The parsed ScriptMessage.
Throws
On unrecoverable structural problems.
Example
const msg = parseScript("<Message version='2017071'>…</Message>");
msg.asNewRx()?.medication?.description;
parseTelecom()
parseTelecom(
raw,opts?):TelecomTransaction
Parse a raw NCPDP Telecommunication-standard transmission into a frozen TelecomTransaction. Lenient by contract: anything recoverable becomes a warning and the underlying bytes are preserved. Only structurally unrecoverable input throws NcpdpTelecomParseError with a Telecom fatal code.
Parameters
raw
string | Buffer<ArrayBufferLike>
The raw message as a string or Buffer.
opts?
Optional TelecomParseOptions.
Returns
The decoded transaction.
Throws
NcpdpTelecomParseError on empty input, a missing fixed header, unframeable body bytes, or an untrusted version layout.
Example
const t = parseTelecom(rawClaim);
t.header.transactionCode; // "B1"
t.segments.length; // number of decoded segments
partitionWarnings()
partitionWarnings<
W>(warnings,profile):NcpdpWarningPartition<W>
Split a parse's warnings against a profile's expected-warning union. A
warning whose code is in the profile's expectedWarnings lands in
expected; everything else lands in unexpected. Order within each bucket
preserves the input order.
Type Parameters
W
W extends object
Parameters
warnings
readonly W[]
profile
Returns
Example
import { parseTelecom } from "@cosyte/ncpdp/telecom";
import { partitionWarnings, profiles } from "@cosyte/ncpdp/profiles";
const tx = parseTelecom(raw, { profile: profiles.pbm });
const { expected, unexpected } = partitionWarnings(tx.warnings, profiles.pbm);
if (unexpected.length > 0) flagForReview(unexpected);
recognizeCodeSystem()
recognizeCodeSystem(
qualifier):CodeSystem
Recognize a normalized CodeSystem from a SCRIPT code qualifier.
Matching is case-insensitive; unrecognized qualifiers yield "UNKNOWN" (a
lenient default, never a throw).
Parameters
qualifier
string
The qualifier string accompanying a coded value.
Returns
The normalized code system.
Example
recognizeCodeSystem("ND"); // "NDC"
recognizeCodeSystem("RxCUI"); // "RXNORM"
recognizeCodeSystem("zzz"); // "UNKNOWN"
rxChangeRequest()
rxChangeRequest(
message):RxChangeRequest|undefined
Convenience accessor: the RxChangeRequest body, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
RxChangeRequest | undefined
The change-request body, or undefined.
Example
rxChangeRequest(parseScript(xml))?.medicationPrescribed?.description;
rxChangeResponse()
rxChangeResponse(
message):RxChangeResponse|undefined
Convenience accessor: the RxChangeResponse body, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
RxChangeResponse | undefined
The change-response body, or undefined.
Example
rxChangeResponse(parseScript(xml))?.outcome; // "approved" | "denied" | "validated" | …
rxRenewalRequest()
rxRenewalRequest(
message):RxRenewalRequest|undefined
Convenience accessor: the RxRenewalRequest body, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
RxRenewalRequest | undefined
The renewal-request body, or undefined.
Example
rxRenewalRequest(parseScript(xml))?.medicationPrescribed?.description;
rxRenewalResponse()
rxRenewalResponse(
message):RxRenewalResponse|undefined
Convenience accessor: the RxRenewalResponse body, or undefined. Read
.outcome for the prescriber's decision: a denial never reads as an approval.
Parameters
message
A parsed ScriptMessage.
Returns
RxRenewalResponse | undefined
The renewal-response body, or undefined.
Example
rxRenewalResponse(parseScript(xml))?.outcome; // "approved" | "denied" | …
scriptPosition()
scriptPosition(
path):ScriptPosition
Build a ScriptPosition from an XPath-style location string.
Parameters
path
string
XPath-style location, e.g. /Message/Header/To.
Returns
A frozen positional context.
Example
const pos = scriptPosition("/Message/Body/NewRx/Patient");
pos.path; // "/Message/Body/NewRx/Patient"
scriptWarning()
scriptWarning(
code,position):NcpdpScriptWarning
Construct a frozen NcpdpScriptWarning from a code and a position.
There is deliberately no value parameter. That absence is the whole safety property: a factory that accepts a value grows interpolation sites, and every parser in this family that leaked patient data into a log line did so through one.
Parameters
code
The stable warning code, which selects the message.
position
XPath-style location of the condition.
Returns
A frozen warning.
Example
scriptWarning(SCRIPT_WARNING_CODES.VERSION_ABSENT, scriptPosition("/Message"));
serializeScript()
serializeScript(
message):string
Serialize a parsed ScriptMessage back to canonical NCPDP SCRIPT XML. The conservative (emit) half of Postel's Law: it walks the model faithfully and never warns. Only the modeled fields are emitted: SCRIPT is a lossy structural read, so a value the parser does not surface cannot be reproduced; this is the honest round-trip contract.
The output is canonical, not byte-identical to the input: namespace
prefixes and wrapper elements the parser flattens (e.g. <HumanPatient>) are
dropped, and indentation is normalized. Serializing is idempotent:
serialize(parse(serialize(m))) equals serialize(m). Values are XML-escaped;
because the XXE-safe loader does not resolve entities, a value carrying a raw
<, >, or & survives only when it was entity-free to begin with (the
synthetic corpus is).
Parameters
message
A parsed message from "./parse".parseScript.
Returns
string
The canonical SCRIPT XML string.
Example
import { parseScript, serializeScript } from "@cosyte/ncpdp/script";
const xml = serializeScript(parseScript(raw));
parseScript(xml); // re-parses cleanly
serializeTelecom()
serializeTelecom(
transaction):string
Serialize a TelecomTransaction back to its canonical NCPDP Telecommunication vD.0 wire form. The conservative (emit) half of Postel's Law: it walks the model faithfully and never warns: a model produced by "./parse".parseTelecom or "./builder".buildTelecomRequest is trusted as valid by construction.
The output is canonical, not byte-identical to a quirky input: header
fields are re-padded to their fixed widths and segments are re-joined with
single FS/GS/RS control characters. Serializing is idempotent:
serialize(parse(serialize(t))) equals serialize(t), which is the
round-trip contract this library guarantees (a normalizing serializer cannot
reproduce arbitrary whitespace or duplicate separators).
A request emits the 56-byte fixed header immediately followed by the framed body; a response emits the fixed response header, a Group Separator, then the RS-framed segment body.
Parameters
transaction
A transaction from parseTelecom or buildTelecomRequest.
Returns
string
The canonical wire string.
Example
import { parseTelecom, serializeTelecom } from "@cosyte/ncpdp/telecom";
const wire = serializeTelecom(parseTelecom(raw));
parseTelecom(wire); // re-parses cleanly
setDefaultProfile()
setDefaultProfile(
profile):void
Register a process-scoped default profile. parseScript(raw) /
parseTelecom(raw) (no explicit profile arg) consult getDefaultProfile()
and attach the returned profile to the result. Pass null (or undefined)
to clear.
Explicit args ALWAYS win: parseTelecom(raw, { profile: myProfile }) uses
myProfile regardless of the default; parseTelecom(raw, { profile: null })
opts out of the default for a single call without changing the registered
default.
Test hygiene: the only mutable module-scoped state in the library. Tests
that call this MUST clean up in afterEach (setDefaultProfile(null)).
Parameters
profile
NcpdpProfile | null
Returns
void
Example
import { setDefaultProfile, getDefaultProfile, profiles } from "@cosyte/ncpdp/profiles";
import { parseTelecom } from "@cosyte/ncpdp/telecom";
setDefaultProfile(profiles.pbm);
const tx = parseTelecom(raw);
tx.profile?.name; // "pbm"
setDefaultProfile(null); // clear (or in test teardown)
splitWithOffsets()
splitWithOffsets(
s,sep,base):Part[]
Split a string on a single-character separator, carrying each piece's absolute byte offset. Empty pieces are retained (the caller decides whether to drop the leading empty that a leading separator produces).
Parameters
s
string
The string to split.
sep
string
The single-character separator.
base
number
The absolute offset of s[0] in the original message.
Returns
Part[]
The pieces with their absolute offsets.
Example
splitWithOffsets("\x1cD7123", "\x1c", 56);
// [{ text: "", offset: 56 }, { text: "D7123", offset: 57 }]
status()
status(
message):StatusBody|undefined
Convenience accessor: the <Status> (positive-acknowledgment) body of a
message, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
StatusBody | undefined
The Status body, or undefined when the message is not a Status.
Example
status(parseScript(xml))?.code;
telecomPosition()
telecomPosition(
byteOffset,fieldId?):TelecomPosition
Build a TelecomPosition from a byte offset and an optional field id.
Parameters
byteOffset
number
Zero-based byte offset into the raw message.
fieldId?
string
The 2-character field identifier in scope, if any.
Returns
A frozen positional context.
Example
telecomPosition(56).byteOffset; // 56
telecomPosition(72, "D7").fieldId; // "D7"
telecomQuantity()
telecomQuantity(
source):TelecomQuantity
Wrap a verbatim Quantity Dispensed value as a TelecomQuantity, applying the implied 3-place decimal string-wise when the value is all digits.
Parameters
source
string
The quantity exactly as it appeared on the wire.
Returns
A frozen TelecomQuantity.
Example
telecomQuantity("30000").impliedDecimal; // "30.000"
telecomWarning()
telecomWarning(
code,position):NcpdpTelecomWarning
Construct a frozen NcpdpTelecomWarning from a code and a position.
There is deliberately no value parameter. That absence is the whole safety property: a factory that accepts a value grows interpolation sites, and every parser in this family that leaked patient data into a log line did so through one.
Parameters
code
The stable warning code, which selects the message.
position
Byte-offset location of the condition.
Returns
A frozen warning.
Example
telecomWarning(TELECOM_WARNING_CODES.UNKNOWN_SEGMENT, telecomPosition(56, "AM"));
tokenizeBody()
tokenizeBody(
body,base,warnings):TelecomSegment[]
Tokenize the variable body of a Telecom transmission (everything after the
fixed header) into segments. The body is split into group-separated
transactions; only the first transaction's segments are decoded (a
MULTI_TRANSACTION_TRUNCATED warning is raised when more are present so they
are never silently ignored). Within a transaction, segments are
segment-separator delimited and fields are field-separator delimited; the first
field of each segment is the Segment Identification (AM).
Parameters
body
string
The raw message body (the portion after the fixed header).
base
number
The absolute offset of body[0] in the raw message.
warnings
Sink that collects non-fatal warnings.
Returns
The decoded segments of the first transaction, in wire order.
Example
const warnings: NcpdpTelecomWarning[] = [];
const segs = tokenizeBody("\x1cAM07\x1cD2RX1", 56, warnings);
segs[0]?.segmentId; // "07"
undecodedHeader()
undecodedHeader(
versionStamp):TelecomHeader
A minimal header for a recognized-but-undecoded version (F6): the version stamp is surfaced and every positional field is left empty, since the layout differs from D.0 and decoding it here would misalign safety-critical fields.
Parameters
versionStamp
string
The recognized version stamp, e.g. "F6".
Returns
A frozen TelecomHeader with only versionRelease populated.
Example
undecodedHeader("F6").versionRelease; // "F6"
verify()
verify(
message):VerifyBody|undefined
Convenience accessor: the <Verify> (verification-acknowledgment) body of a
message, or undefined.
Parameters
message
A parsed ScriptMessage.
Returns
VerifyBody | undefined
The Verify body, or undefined when the message is not a Verify.
Example
verify(parseScript(xml))?.code;