@rethinkhealth/hl7v2-ack 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ function extractOriginFields(tree) {
|
|
|
58
58
|
sendingApp: value(tree, "MSH-3")?.value ?? "",
|
|
59
59
|
sendingFac: value(tree, "MSH-4")?.value ?? "",
|
|
60
60
|
triggerEvent: value(tree, "MSH-9.2")?.value ?? "",
|
|
61
|
-
version: value(tree, "MSH-12")?.value ?? ""
|
|
61
|
+
version: value(tree, "MSH-12.1")?.value ?? ""
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
function buildMsh(origin, options) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/acknowledge.ts","../src/constants.ts","../src/uid.ts","../src/exception.ts","../src/errors/application-internal-error.ts","../src/errors/commit-internal-error.ts","../src/errors/unsupported-message-type-reject.ts"],"sourcesContent":["import type { Root, Segment } from \"@rethinkhealth/hl7v2-ast\";\nimport { c, f, m, s } from \"@rethinkhealth/hl7v2-builder\";\nimport { value } from \"@rethinkhealth/hl7v2-util-query\";\nimport { Timestamp } from \"@rethinkhealth/hl7v2-util-timestamp\";\n\nimport { AckCode } from \"./constants\";\nimport type { AckSuccessCode } from \"./constants\";\nimport type { AckException } from \"./exception\";\nimport { uid } from \"./uid\";\n\nexport interface SendingInfo {\n application: string;\n facility: string;\n}\n\nexport type AcknowledgeOptions = {\n /** Custom MSH-10 control ID. Auto-generated via `uid()` when omitted. */\n id?: string;\n /** MSH-3/MSH-4 of the ACK. Defaults to the original message's MSH-5/MSH-6. */\n sending?: SendingInfo;\n /** MSH-11 processing ID. Defaults to the original message's MSH-11. */\n processingId?: string;\n} & (\n | {\n /** Sets the ACK code (AE/AR/CE/CR) and populates MSA-3 with the error message. */\n error: AckException;\n /** Include ERR segment when an error is provided. Defaults to `true`. */\n includeErrSegment?: boolean;\n successCode?: never;\n }\n | {\n error?: never;\n includeErrSegment?: never;\n /** MSA-1 code when no error is present. Defaults to `AckCode.ApplicationAccept`. */\n successCode?: AckSuccessCode;\n }\n);\n\n// -- Field extraction ----\n\ninterface OriginFields {\n controlId: string;\n version: string;\n triggerEvent: string;\n processingId: string;\n sendingApp: string;\n sendingFac: string;\n receivingApp: string;\n receivingFac: string;\n}\n\nfunction extractOriginFields(tree: Root): OriginFields {\n return {\n controlId: value(tree, \"MSH-10\")?.value ?? \"\",\n processingId: value(tree, \"MSH-11\")?.value ?? \"P\",\n receivingApp: value(tree, \"MSH-5\")?.value ?? \"\",\n receivingFac: value(tree, \"MSH-6\")?.value ?? \"\",\n sendingApp: value(tree, \"MSH-3\")?.value ?? \"\",\n sendingFac: value(tree, \"MSH-4\")?.value ?? \"\",\n triggerEvent: value(tree, \"MSH-9.2\")?.value ?? \"\",\n version: value(tree, \"MSH-12\")?.value ?? \"\",\n };\n}\n\n// -- Segment builders ----\n\nfunction buildMsh(\n origin: OriginFields,\n options: Pick<AcknowledgeOptions, \"id\" | \"sending\" | \"processingId\">\n): Segment {\n const sendApp = options.sending?.application ?? origin.receivingApp;\n const sendFac = options.sending?.facility ?? origin.receivingFac;\n const pid = options.processingId ?? origin.processingId;\n const controlId = options.id ?? uid();\n const msgType = origin.triggerEvent\n ? f(c(\"ACK\"), c(origin.triggerEvent))\n : f(\"ACK\");\n\n return s(\n \"MSH\",\n f(\"|\"),\n f(\"^~\\\\&\"),\n f(sendApp),\n f(sendFac),\n f(origin.sendingApp),\n f(origin.sendingFac),\n f(Timestamp.now().toString()),\n f(\"\"),\n msgType,\n f(controlId),\n f(pid),\n f(origin.version)\n );\n}\n\nfunction buildMsa(code: string, controlId: string, message?: string): Segment {\n return message\n ? s(\"MSA\", f(code), f(controlId), f(message))\n : s(\"MSA\", f(code), f(controlId));\n}\n\n// -- Public API ----\n\nexport function acknowledge(\n origin: Root,\n {\n id,\n processingId,\n sending,\n error,\n includeErrSegment = true,\n successCode = AckCode.ApplicationAccept,\n }: AcknowledgeOptions = {}\n): Root {\n const fields = extractOriginFields(origin);\n const code = error?.code ?? successCode;\n\n const segments: Segment[] = [\n buildMsh(fields, {\n id,\n processingId,\n sending,\n }),\n buildMsa(code, fields.controlId, error?.message),\n ];\n\n if (error && includeErrSegment) {\n segments.push(error.toErrSegment());\n }\n\n return m(...segments);\n}\n","/** HL7v2 Table 0008 — Acknowledgment codes used in MSA-1. */\nexport const AckCode = {\n ApplicationAccept: \"AA\",\n ApplicationError: \"AE\",\n ApplicationReject: \"AR\",\n CommitAccept: \"CA\",\n CommitError: \"CE\",\n CommitReject: \"CR\",\n} as const;\n\nexport type AckCodeValue = (typeof AckCode)[keyof typeof AckCode];\n\n/** Accept codes used as `successCode` in `acknowledge()`. */\nexport type AckSuccessCode =\n | typeof AckCode.ApplicationAccept\n | typeof AckCode.CommitAccept;\n\n/** HL7v2 Table 0357 — Message error condition codes used in ERR-3. Stable across all versions (v2.1–v2.9). */\nexport const Hl7ErrorCode = {\n MessageAccepted: \"0\",\n SegmentSequenceError: \"100\",\n RequiredFieldMissing: \"101\",\n DataTypeError: \"102\",\n TableValueNotFound: \"103\",\n UnsupportedMessageType: \"200\",\n UnsupportedEventCode: \"201\",\n UnsupportedProcessingId: \"202\",\n UnsupportedVersionId: \"203\",\n UnknownKeyIdentifier: \"204\",\n DuplicateKeyIdentifier: \"205\",\n ApplicationRecordLocked: \"206\",\n ApplicationInternalError: \"207\",\n} as const;\n\nexport type Hl7ErrorCodeValue =\n (typeof Hl7ErrorCode)[keyof typeof Hl7ErrorCode];\n\n/** HL7v2 Table 0516 — Error severity codes used in ERR-4. */\nexport const Severity = {\n Info: \"I\",\n Warning: \"W\",\n Error: \"E\",\n} as const;\n\nexport type SeverityValue = (typeof Severity)[keyof typeof Severity];\n","import { nanoid } from \"nanoid\";\n\nconst MAX_LENGTH = 20;\n\nexport interface Options {\n prefix?: string;\n size?: number;\n}\n\nexport function uid(options: Options = {}): string {\n const { prefix, size = MAX_LENGTH } = options;\n\n if (!prefix) {\n return nanoid(size);\n }\n\n const remaining = size - prefix.length;\n\n if (remaining <= 0) {\n return prefix.slice(0, size);\n }\n\n return `${prefix}${nanoid(remaining)}`;\n}\n","import type { Segment } from \"@rethinkhealth/hl7v2-ast\";\nimport { f, s } from \"@rethinkhealth/hl7v2-builder\";\n\nimport { AckCode, Severity } from \"./constants\";\nimport type {\n AckCodeValue,\n Hl7ErrorCodeValue,\n SeverityValue,\n} from \"./constants\";\n\nexport interface AckExceptionOptions extends ErrorOptions {\n errorCode: Hl7ErrorCodeValue;\n severity?: SeverityValue;\n}\n\n/**\n * Abstract base class for all HL7v2 acknowledgment exceptions.\n *\n * Subclasses map to specific MSA-1 acknowledgment codes (Table 0008).\n * Each exception carries an error code (Table 0357), optional severity\n * (Table 0516), and can build its own ERR segment AST via {@link toErrSegment}.\n *\n * Use `instanceof AckException` to detect any ACK-level error in middleware.\n */\nexport abstract class AckException extends Error {\n abstract readonly code: AckCodeValue;\n readonly errorCode: Hl7ErrorCodeValue;\n readonly severity: SeverityValue | undefined;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, { cause: options.cause });\n this.errorCode = options.errorCode;\n this.severity = options.severity;\n }\n\n /** Build an ERR segment AST node from this exception's error code and severity. */\n toErrSegment(): Segment {\n return s(\n \"ERR\",\n f(\"\"),\n f(\"\"),\n f(this.errorCode),\n f(this.severity ?? Severity.Error)\n );\n }\n}\n\n/**\n * Application-level error (MSA-1 = `AE`).\n *\n * Throw when the message was understood but could not be processed\n * due to an application-level problem (e.g. validation failure, unknown key).\n */\nexport class AckApplicationError extends AckException {\n readonly code = AckCode.ApplicationError;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckApplicationError\";\n }\n}\n\n/**\n * Application-level reject (MSA-1 = `AR`).\n *\n * Throw when the message is rejected outright at the application level\n * (e.g. unsupported message type, unsupported version).\n */\nexport class AckApplicationReject extends AckException {\n readonly code = AckCode.ApplicationReject;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckApplicationReject\";\n }\n}\n\n/**\n * Commit-level error (MSA-1 = `CE`).\n *\n * Throw when the message could not be safely persisted/committed\n * (e.g. storage failure). Used in enhanced acknowledgment mode.\n */\nexport class AckCommitError extends AckException {\n readonly code = AckCode.CommitError;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckCommitError\";\n }\n}\n\n/**\n * Commit-level reject (MSA-1 = `CR`).\n *\n * Throw when the message is rejected at the commit level\n * (e.g. message cannot be stored). Used in enhanced acknowledgment mode.\n */\nexport class AckCommitReject extends AckException {\n readonly code = AckCode.CommitReject;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckCommitReject\";\n }\n}\n","import { Hl7ErrorCode, Severity } from \"../constants\";\nimport { AckApplicationError } from \"../exception\";\n\n/**\n * Application internal error (MSA-1 = `AE`, ERR-3 = `207`, ERR-4 = `E`).\n *\n * Used to wrap unexpected/unknown errors that don't map to a specific\n * HL7v2 error condition. This is the default error produced by\n * `ackMiddleware` when a handler throws an unrecognized exception.\n */\nexport class ApplicationInternalError extends AckApplicationError {\n constructor(message: string, cause?: Error) {\n super(message, {\n errorCode: Hl7ErrorCode.ApplicationInternalError,\n severity: Severity.Error,\n cause,\n });\n this.name = \"ApplicationInternalError\";\n }\n}\n","import { Hl7ErrorCode, Severity } from \"../constants\";\nimport { AckCommitError } from \"../exception\";\n\n/**\n * Commit-level internal error (MSA-1 = `CE`, ERR-3 = `207`, ERR-4 = `E`).\n *\n * Used when the message could not be persisted due to an internal\n * infrastructure failure (e.g. database unavailable).\n */\nexport class CommitInternalError extends AckCommitError {\n constructor(message: string, cause?: Error) {\n super(message, {\n errorCode: Hl7ErrorCode.ApplicationInternalError,\n severity: Severity.Error,\n cause,\n });\n this.name = \"CommitInternalError\";\n }\n}\n","import { Hl7ErrorCode, Severity } from \"../constants\";\nimport { AckApplicationReject } from \"../exception\";\n\n/**\n * Unsupported message type reject (MSA-1 = `AR`, ERR-3 = `200`, ERR-4 = `E`).\n *\n * Throw when the receiving application does not handle the inbound\n * message type (e.g. ADT^A01 sent to a system that only accepts ORU).\n */\nexport class UnsupportedMessageTypeReject extends AckApplicationReject {\n constructor(message: string) {\n super(message, {\n errorCode: Hl7ErrorCode.UnsupportedMessageType,\n severity: Severity.Error,\n });\n this.name = \"UnsupportedMessageTypeReject\";\n }\n}\n"],"mappings":";AACA,SAAS,GAAG,GAAG,GAAG,SAAS;AAC3B,SAAS,aAAa;AACtB,SAAS,iBAAiB;;;ACFnB,IAAM,UAAU;AAAA,EACrB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,cAAc;AAChB;AAUO,IAAM,eAAe;AAAA,EAC1B,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,0BAA0B;AAC5B;AAMO,IAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AACT;;;AC1CA,SAAS,cAAc;AAEvB,IAAM,aAAa;AAOZ,SAAS,IAAI,UAAmB,CAAC,GAAW;AACjD,QAAM,EAAE,QAAQ,OAAO,WAAW,IAAI;AAEtC,MAAI,CAAC,QAAQ;AACX,WAAO,OAAO,IAAI;AAAA,EACpB;AAEA,QAAM,YAAY,OAAO,OAAO;AAEhC,MAAI,aAAa,GAAG;AAClB,WAAO,OAAO,MAAM,GAAG,IAAI;AAAA,EAC7B;AAEA,SAAO,GAAG,MAAM,GAAG,OAAO,SAAS,CAAC;AACtC;;;AF4BA,SAAS,oBAAoB,MAA0B;AACrD,SAAO;AAAA,IACL,WAAW,MAAM,MAAM,QAAQ,GAAG,SAAS;AAAA,IAC3C,cAAc,MAAM,MAAM,QAAQ,GAAG,SAAS;AAAA,IAC9C,cAAc,MAAM,MAAM,OAAO,GAAG,SAAS;AAAA,IAC7C,cAAc,MAAM,MAAM,OAAO,GAAG,SAAS;AAAA,IAC7C,YAAY,MAAM,MAAM,OAAO,GAAG,SAAS;AAAA,IAC3C,YAAY,MAAM,MAAM,OAAO,GAAG,SAAS;AAAA,IAC3C,cAAc,MAAM,MAAM,SAAS,GAAG,SAAS;AAAA,IAC/C,SAAS,MAAM,MAAM,QAAQ,GAAG,SAAS;AAAA,EAC3C;AACF;AAIA,SAAS,SACP,QACA,SACS;AACT,QAAM,UAAU,QAAQ,SAAS,eAAe,OAAO;AACvD,QAAM,UAAU,QAAQ,SAAS,YAAY,OAAO;AACpD,QAAM,MAAM,QAAQ,gBAAgB,OAAO;AAC3C,QAAM,YAAY,QAAQ,MAAM,IAAI;AACpC,QAAM,UAAU,OAAO,eACnB,EAAE,EAAE,KAAK,GAAG,EAAE,OAAO,YAAY,CAAC,IAClC,EAAE,KAAK;AAEX,SAAO;AAAA,IACL;AAAA,IACA,EAAE,GAAG;AAAA,IACL,EAAE,OAAO;AAAA,IACT,EAAE,OAAO;AAAA,IACT,EAAE,OAAO;AAAA,IACT,EAAE,OAAO,UAAU;AAAA,IACnB,EAAE,OAAO,UAAU;AAAA,IACnB,EAAE,UAAU,IAAI,EAAE,SAAS,CAAC;AAAA,IAC5B,EAAE,EAAE;AAAA,IACJ;AAAA,IACA,EAAE,SAAS;AAAA,IACX,EAAE,GAAG;AAAA,IACL,EAAE,OAAO,OAAO;AAAA,EAClB;AACF;AAEA,SAAS,SAAS,MAAc,WAAmB,SAA2B;AAC5E,SAAO,UACH,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,EAAE,OAAO,CAAC,IAC1C,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,CAAC;AACpC;AAIO,SAAS,YACd,QACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,cAAc,QAAQ;AACxB,IAAwB,CAAC,GACnB;AACN,QAAM,SAAS,oBAAoB,MAAM;AACzC,QAAM,OAAO,OAAO,QAAQ;AAE5B,QAAM,WAAsB;AAAA,IAC1B,SAAS,QAAQ;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACD,SAAS,MAAM,OAAO,WAAW,OAAO,OAAO;AAAA,EACjD;AAEA,MAAI,SAAS,mBAAmB;AAC9B,aAAS,KAAK,MAAM,aAAa,CAAC;AAAA,EACpC;AAEA,SAAO,EAAE,GAAG,QAAQ;AACtB;;;AGlIA,SAAS,KAAAA,IAAG,KAAAC,UAAS;AAuBd,IAAe,eAAf,cAAoC,MAAM;AAAA,EAEtC;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,SAA8B;AACzD,UAAM,SAAS,EAAE,OAAO,QAAQ,MAAM,CAAC;AACvC,SAAK,YAAY,QAAQ;AACzB,SAAK,WAAW,QAAQ;AAAA,EAC1B;AAAA;AAAA,EAGA,eAAwB;AACtB,WAAOC;AAAA,MACL;AAAA,MACAC,GAAE,EAAE;AAAA,MACJA,GAAE,EAAE;AAAA,MACJA,GAAE,KAAK,SAAS;AAAA,MAChBA,GAAE,KAAK,YAAY,SAAS,KAAK;AAAA,IACnC;AAAA,EACF;AACF;AAQO,IAAM,sBAAN,cAAkC,aAAa;AAAA,EAC3C,OAAO,QAAQ;AAAA,EAExB,YAAY,SAAiB,SAA8B;AACzD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AACF;AAQO,IAAM,uBAAN,cAAmC,aAAa;AAAA,EAC5C,OAAO,QAAQ;AAAA,EAExB,YAAY,SAAiB,SAA8B;AACzD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AACF;AAQO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EACtC,OAAO,QAAQ;AAAA,EAExB,YAAY,SAAiB,SAA8B;AACzD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AACF;AAQO,IAAM,kBAAN,cAA8B,aAAa;AAAA,EACvC,OAAO,QAAQ;AAAA,EAExB,YAAY,SAAiB,SAA8B;AACzD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AACF;;;AC/FO,IAAM,2BAAN,cAAuC,oBAAoB;AAAA,EAChE,YAAY,SAAiB,OAAe;AAC1C,UAAM,SAAS;AAAA,MACb,WAAW,aAAa;AAAA,MACxB,UAAU,SAAS;AAAA,MACnB;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;;;ACVO,IAAM,sBAAN,cAAkC,eAAe;AAAA,EACtD,YAAY,SAAiB,OAAe;AAC1C,UAAM,SAAS;AAAA,MACb,WAAW,aAAa;AAAA,MACxB,UAAU,SAAS;AAAA,MACnB;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;;;ACTO,IAAM,+BAAN,cAA2C,qBAAqB;AAAA,EACrE,YAAY,SAAiB;AAC3B,UAAM,SAAS;AAAA,MACb,WAAW,aAAa;AAAA,MACxB,UAAU,SAAS;AAAA,IACrB,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;","names":["f","s","s","f"]}
|
|
1
|
+
{"version":3,"sources":["../src/acknowledge.ts","../src/constants.ts","../src/uid.ts","../src/exception.ts","../src/errors/application-internal-error.ts","../src/errors/commit-internal-error.ts","../src/errors/unsupported-message-type-reject.ts"],"sourcesContent":["import type { Root, Segment } from \"@rethinkhealth/hl7v2-ast\";\nimport { c, f, m, s } from \"@rethinkhealth/hl7v2-builder\";\nimport { value } from \"@rethinkhealth/hl7v2-util-query\";\nimport { Timestamp } from \"@rethinkhealth/hl7v2-util-timestamp\";\n\nimport { AckCode } from \"./constants\";\nimport type { AckSuccessCode } from \"./constants\";\nimport type { AckException } from \"./exception\";\nimport { uid } from \"./uid\";\n\nexport interface SendingInfo {\n application: string;\n facility: string;\n}\n\nexport type AcknowledgeOptions = {\n /** Custom MSH-10 control ID. Auto-generated via `uid()` when omitted. */\n id?: string;\n /** MSH-3/MSH-4 of the ACK. Defaults to the original message's MSH-5/MSH-6. */\n sending?: SendingInfo;\n /** MSH-11 processing ID. Defaults to the original message's MSH-11. */\n processingId?: string;\n} & (\n | {\n /** Sets the ACK code (AE/AR/CE/CR) and populates MSA-3 with the error message. */\n error: AckException;\n /** Include ERR segment when an error is provided. Defaults to `true`. */\n includeErrSegment?: boolean;\n successCode?: never;\n }\n | {\n error?: never;\n includeErrSegment?: never;\n /** MSA-1 code when no error is present. Defaults to `AckCode.ApplicationAccept`. */\n successCode?: AckSuccessCode;\n }\n);\n\n// -- Field extraction ----\n\ninterface OriginFields {\n controlId: string;\n version: string;\n triggerEvent: string;\n processingId: string;\n sendingApp: string;\n sendingFac: string;\n receivingApp: string;\n receivingFac: string;\n}\n\nfunction extractOriginFields(tree: Root): OriginFields {\n return {\n controlId: value(tree, \"MSH-10\")?.value ?? \"\",\n processingId: value(tree, \"MSH-11\")?.value ?? \"P\",\n receivingApp: value(tree, \"MSH-5\")?.value ?? \"\",\n receivingFac: value(tree, \"MSH-6\")?.value ?? \"\",\n sendingApp: value(tree, \"MSH-3\")?.value ?? \"\",\n sendingFac: value(tree, \"MSH-4\")?.value ?? \"\",\n triggerEvent: value(tree, \"MSH-9.2\")?.value ?? \"\",\n version: value(tree, \"MSH-12.1\")?.value ?? \"\",\n };\n}\n\n// -- Segment builders ----\n\nfunction buildMsh(\n origin: OriginFields,\n options: Pick<AcknowledgeOptions, \"id\" | \"sending\" | \"processingId\">\n): Segment {\n const sendApp = options.sending?.application ?? origin.receivingApp;\n const sendFac = options.sending?.facility ?? origin.receivingFac;\n const pid = options.processingId ?? origin.processingId;\n const controlId = options.id ?? uid();\n const msgType = origin.triggerEvent\n ? f(c(\"ACK\"), c(origin.triggerEvent))\n : f(\"ACK\");\n\n return s(\n \"MSH\",\n f(\"|\"),\n f(\"^~\\\\&\"),\n f(sendApp),\n f(sendFac),\n f(origin.sendingApp),\n f(origin.sendingFac),\n f(Timestamp.now().toString()),\n f(\"\"),\n msgType,\n f(controlId),\n f(pid),\n f(origin.version)\n );\n}\n\nfunction buildMsa(code: string, controlId: string, message?: string): Segment {\n return message\n ? s(\"MSA\", f(code), f(controlId), f(message))\n : s(\"MSA\", f(code), f(controlId));\n}\n\n// -- Public API ----\n\nexport function acknowledge(\n origin: Root,\n {\n id,\n processingId,\n sending,\n error,\n includeErrSegment = true,\n successCode = AckCode.ApplicationAccept,\n }: AcknowledgeOptions = {}\n): Root {\n const fields = extractOriginFields(origin);\n const code = error?.code ?? successCode;\n\n const segments: Segment[] = [\n buildMsh(fields, {\n id,\n processingId,\n sending,\n }),\n buildMsa(code, fields.controlId, error?.message),\n ];\n\n if (error && includeErrSegment) {\n segments.push(error.toErrSegment());\n }\n\n return m(...segments);\n}\n","/** HL7v2 Table 0008 — Acknowledgment codes used in MSA-1. */\nexport const AckCode = {\n ApplicationAccept: \"AA\",\n ApplicationError: \"AE\",\n ApplicationReject: \"AR\",\n CommitAccept: \"CA\",\n CommitError: \"CE\",\n CommitReject: \"CR\",\n} as const;\n\nexport type AckCodeValue = (typeof AckCode)[keyof typeof AckCode];\n\n/** Accept codes used as `successCode` in `acknowledge()`. */\nexport type AckSuccessCode =\n | typeof AckCode.ApplicationAccept\n | typeof AckCode.CommitAccept;\n\n/** HL7v2 Table 0357 — Message error condition codes used in ERR-3. Stable across all versions (v2.1–v2.9). */\nexport const Hl7ErrorCode = {\n MessageAccepted: \"0\",\n SegmentSequenceError: \"100\",\n RequiredFieldMissing: \"101\",\n DataTypeError: \"102\",\n TableValueNotFound: \"103\",\n UnsupportedMessageType: \"200\",\n UnsupportedEventCode: \"201\",\n UnsupportedProcessingId: \"202\",\n UnsupportedVersionId: \"203\",\n UnknownKeyIdentifier: \"204\",\n DuplicateKeyIdentifier: \"205\",\n ApplicationRecordLocked: \"206\",\n ApplicationInternalError: \"207\",\n} as const;\n\nexport type Hl7ErrorCodeValue =\n (typeof Hl7ErrorCode)[keyof typeof Hl7ErrorCode];\n\n/** HL7v2 Table 0516 — Error severity codes used in ERR-4. */\nexport const Severity = {\n Info: \"I\",\n Warning: \"W\",\n Error: \"E\",\n} as const;\n\nexport type SeverityValue = (typeof Severity)[keyof typeof Severity];\n","import { nanoid } from \"nanoid\";\n\nconst MAX_LENGTH = 20;\n\nexport interface Options {\n prefix?: string;\n size?: number;\n}\n\nexport function uid(options: Options = {}): string {\n const { prefix, size = MAX_LENGTH } = options;\n\n if (!prefix) {\n return nanoid(size);\n }\n\n const remaining = size - prefix.length;\n\n if (remaining <= 0) {\n return prefix.slice(0, size);\n }\n\n return `${prefix}${nanoid(remaining)}`;\n}\n","import type { Segment } from \"@rethinkhealth/hl7v2-ast\";\nimport { f, s } from \"@rethinkhealth/hl7v2-builder\";\n\nimport { AckCode, Severity } from \"./constants\";\nimport type {\n AckCodeValue,\n Hl7ErrorCodeValue,\n SeverityValue,\n} from \"./constants\";\n\nexport interface AckExceptionOptions extends ErrorOptions {\n errorCode: Hl7ErrorCodeValue;\n severity?: SeverityValue;\n}\n\n/**\n * Abstract base class for all HL7v2 acknowledgment exceptions.\n *\n * Subclasses map to specific MSA-1 acknowledgment codes (Table 0008).\n * Each exception carries an error code (Table 0357), optional severity\n * (Table 0516), and can build its own ERR segment AST via {@link toErrSegment}.\n *\n * Use `instanceof AckException` to detect any ACK-level error in middleware.\n */\nexport abstract class AckException extends Error {\n abstract readonly code: AckCodeValue;\n readonly errorCode: Hl7ErrorCodeValue;\n readonly severity: SeverityValue | undefined;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, { cause: options.cause });\n this.errorCode = options.errorCode;\n this.severity = options.severity;\n }\n\n /** Build an ERR segment AST node from this exception's error code and severity. */\n toErrSegment(): Segment {\n return s(\n \"ERR\",\n f(\"\"),\n f(\"\"),\n f(this.errorCode),\n f(this.severity ?? Severity.Error)\n );\n }\n}\n\n/**\n * Application-level error (MSA-1 = `AE`).\n *\n * Throw when the message was understood but could not be processed\n * due to an application-level problem (e.g. validation failure, unknown key).\n */\nexport class AckApplicationError extends AckException {\n readonly code = AckCode.ApplicationError;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckApplicationError\";\n }\n}\n\n/**\n * Application-level reject (MSA-1 = `AR`).\n *\n * Throw when the message is rejected outright at the application level\n * (e.g. unsupported message type, unsupported version).\n */\nexport class AckApplicationReject extends AckException {\n readonly code = AckCode.ApplicationReject;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckApplicationReject\";\n }\n}\n\n/**\n * Commit-level error (MSA-1 = `CE`).\n *\n * Throw when the message could not be safely persisted/committed\n * (e.g. storage failure). Used in enhanced acknowledgment mode.\n */\nexport class AckCommitError extends AckException {\n readonly code = AckCode.CommitError;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckCommitError\";\n }\n}\n\n/**\n * Commit-level reject (MSA-1 = `CR`).\n *\n * Throw when the message is rejected at the commit level\n * (e.g. message cannot be stored). Used in enhanced acknowledgment mode.\n */\nexport class AckCommitReject extends AckException {\n readonly code = AckCode.CommitReject;\n\n constructor(message: string, options: AckExceptionOptions) {\n super(message, options);\n this.name = \"AckCommitReject\";\n }\n}\n","import { Hl7ErrorCode, Severity } from \"../constants\";\nimport { AckApplicationError } from \"../exception\";\n\n/**\n * Application internal error (MSA-1 = `AE`, ERR-3 = `207`, ERR-4 = `E`).\n *\n * Used to wrap unexpected/unknown errors that don't map to a specific\n * HL7v2 error condition. This is the default error produced by\n * `ackMiddleware` when a handler throws an unrecognized exception.\n */\nexport class ApplicationInternalError extends AckApplicationError {\n constructor(message: string, cause?: Error) {\n super(message, {\n errorCode: Hl7ErrorCode.ApplicationInternalError,\n severity: Severity.Error,\n cause,\n });\n this.name = \"ApplicationInternalError\";\n }\n}\n","import { Hl7ErrorCode, Severity } from \"../constants\";\nimport { AckCommitError } from \"../exception\";\n\n/**\n * Commit-level internal error (MSA-1 = `CE`, ERR-3 = `207`, ERR-4 = `E`).\n *\n * Used when the message could not be persisted due to an internal\n * infrastructure failure (e.g. database unavailable).\n */\nexport class CommitInternalError extends AckCommitError {\n constructor(message: string, cause?: Error) {\n super(message, {\n errorCode: Hl7ErrorCode.ApplicationInternalError,\n severity: Severity.Error,\n cause,\n });\n this.name = \"CommitInternalError\";\n }\n}\n","import { Hl7ErrorCode, Severity } from \"../constants\";\nimport { AckApplicationReject } from \"../exception\";\n\n/**\n * Unsupported message type reject (MSA-1 = `AR`, ERR-3 = `200`, ERR-4 = `E`).\n *\n * Throw when the receiving application does not handle the inbound\n * message type (e.g. ADT^A01 sent to a system that only accepts ORU).\n */\nexport class UnsupportedMessageTypeReject extends AckApplicationReject {\n constructor(message: string) {\n super(message, {\n errorCode: Hl7ErrorCode.UnsupportedMessageType,\n severity: Severity.Error,\n });\n this.name = \"UnsupportedMessageTypeReject\";\n }\n}\n"],"mappings":"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","names":["f","s","s","f"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rethinkhealth/hl7v2-ack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "HL7v2 acknowledgment message builder and typed error classes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ack",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"nanoid": "5.1.
|
|
34
|
-
"@rethinkhealth/hl7v2-ast": "0.
|
|
35
|
-
"@rethinkhealth/hl7v2-builder": "0.
|
|
36
|
-
"@rethinkhealth/hl7v2-util-timestamp": "0.
|
|
37
|
-
"@rethinkhealth/hl7v2-util-query": "0.
|
|
33
|
+
"nanoid": "5.1.7",
|
|
34
|
+
"@rethinkhealth/hl7v2-ast": "0.10.0",
|
|
35
|
+
"@rethinkhealth/hl7v2-builder": "0.10.0",
|
|
36
|
+
"@rethinkhealth/hl7v2-util-timestamp": "0.10.0",
|
|
37
|
+
"@rethinkhealth/hl7v2-util-query": "0.10.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^25.5.0",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"tsup": "^8.5.1",
|
|
43
43
|
"typescript": "^5.9.3",
|
|
44
44
|
"vitest": "4.1.0",
|
|
45
|
+
"@rethinkhealth/testing": "0.0.2",
|
|
45
46
|
"@rethinkhealth/tsconfig": "0.0.1",
|
|
46
|
-
"@rethinkhealth/hl7v2-to-hl7v2": "0.
|
|
47
|
-
"@rethinkhealth/testing": "0.0.2"
|
|
47
|
+
"@rethinkhealth/hl7v2-to-hl7v2": "0.10.0"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=18"
|