@rethinkhealth/hl7v2-utils 0.12.0 → 0.13.1
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 +184 -224
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,239 +1,199 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
//#region src/constants.ts
|
|
2
|
+
const DEFAULT_DELIMITERS = {
|
|
3
|
+
component: "^",
|
|
4
|
+
escape: "\\",
|
|
5
|
+
field: "|",
|
|
6
|
+
repetition: "~",
|
|
7
|
+
segment: "\r",
|
|
8
|
+
subcomponent: "&"
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/utils.ts
|
|
12
|
+
/**
|
|
13
|
+
* Check if an HL7v2 AST node is semantically empty.
|
|
14
|
+
*
|
|
15
|
+
* A node is empty when it contains no meaningful data — no subcomponent
|
|
16
|
+
* anywhere in its subtree has a non-empty string value.
|
|
17
|
+
*
|
|
18
|
+
* This follows the HL7v2 specification (Chapter 2, Section 2.5.3) and
|
|
19
|
+
* Conformance Methodology R1 (2019) definition of "non-empty value":
|
|
20
|
+
* at least one character must be a non-whitespace character.
|
|
21
|
+
*
|
|
22
|
+
* ## HL7v2 emptiness semantics
|
|
23
|
+
*
|
|
24
|
+
* | Encoding | Wire form | isEmpty? | Meaning |
|
|
25
|
+
* |-------------|---------------|----------|----------------------------------|
|
|
26
|
+
* | `value` | `\|value\|` | `false` | Field has data |
|
|
27
|
+
* | `^DOE` | `\|^DOE\|` | `false` | Component 2 has data |
|
|
28
|
+
* | `~value` | `\|~value\|` | `false` | Repetition 2 has data |
|
|
29
|
+
* | `""` | `\|""\|` | `false` | Explicit null (delete indicator) |
|
|
30
|
+
* | (empty) | `\|\|` | `true` | Not present |
|
|
31
|
+
* | `^^` | `\|^^\|` | `true` | Empty components |
|
|
32
|
+
* | `~` | `\|~\|` | `true` | Empty repetitions |
|
|
33
|
+
* | `~^^` | `\|~^^\|` | `true` | Empty reps with empty components |
|
|
34
|
+
*
|
|
35
|
+
* @param node - The HL7v2 AST node to check (or null/undefined)
|
|
36
|
+
* @returns `true` if the node has no meaningful data
|
|
37
|
+
*/
|
|
12
38
|
function isEmptyNode(node) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!node.children || node.children.length === 0) {
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
return node.children.every((child) => isEmptyNode(child));
|
|
24
|
-
}
|
|
25
|
-
return false;
|
|
39
|
+
if (!node) return true;
|
|
40
|
+
if ("value" in node) return !node.value || node.value.trim() === "";
|
|
41
|
+
if ("children" in node) {
|
|
42
|
+
if (!node.children || node.children.length === 0) return true;
|
|
43
|
+
return node.children.every((child) => isEmptyNode(child));
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
26
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Calculate the byte length of any HL7v2 AST node.
|
|
49
|
+
*
|
|
50
|
+
* For literal nodes (Subcomponent), returns the UTF-8 byte length of the value.
|
|
51
|
+
* For parent nodes, recursively calculates the length of all children. Delimiters are NOT included.
|
|
52
|
+
*
|
|
53
|
+
* @param node - The HL7v2 AST node to measure
|
|
54
|
+
* @returns The total byte length of the node content
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const field: Field = { type: "field", children: [...] };
|
|
59
|
+
* const length = getByteLength(field); // e.g., 42
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
27
62
|
function getByteLength(node) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if ("value" in node) {
|
|
32
|
-
return Buffer.byteLength(node.value, "utf8");
|
|
33
|
-
}
|
|
34
|
-
const nameLength = node.type === "segment" ? Buffer.byteLength(node.name, "utf8") : 0;
|
|
35
|
-
return nameLength + node.children.reduce((total, child) => total + getByteLength(child), 0);
|
|
63
|
+
if (!node) return 0;
|
|
64
|
+
if ("value" in node) return Buffer.byteLength(node.value, "utf8");
|
|
65
|
+
return (node.type === "segment" ? Buffer.byteLength(node.name, "utf8") : 0) + node.children.reduce((total, child) => total + getByteLength(child), 0);
|
|
36
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Calculate the string length of any HL7v2 AST node.
|
|
69
|
+
*
|
|
70
|
+
* For literal nodes (Subcomponent), returns `value.length`.
|
|
71
|
+
* For parent nodes, recursively calculates the length of all children. Delimiters are NOT included.
|
|
72
|
+
*
|
|
73
|
+
* Note: Returns JavaScript string length (UTF-16 code units). For UTF-8 byte
|
|
74
|
+
* length (e.g., for wire protocol), use `getByteLength` instead.
|
|
75
|
+
*
|
|
76
|
+
* @param node - The HL7v2 AST node to measure
|
|
77
|
+
* @returns The total string length of the node content
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const field: Field = { type: "field", children: [...] };
|
|
82
|
+
* const length = getLength(field); // e.g., 42
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
37
85
|
function getLength(node) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if ("value" in node) {
|
|
42
|
-
return node.value.length;
|
|
43
|
-
}
|
|
44
|
-
const nameLength = node.type === "segment" ? node.name.length : 0;
|
|
45
|
-
return nameLength + node.children.reduce((total, child) => total + getLength(child), 0);
|
|
86
|
+
if (!node) return 0;
|
|
87
|
+
if ("value" in node) return node.value.length;
|
|
88
|
+
return (node.type === "segment" ? node.name.length : 0) + node.children.reduce((total, child) => total + getLength(child), 0);
|
|
46
89
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
BackwardCompatible: "B",
|
|
58
|
-
/**
|
|
59
|
-
* Undeclared / Conditional.
|
|
60
|
-
*
|
|
61
|
-
* There are no implementation requirements. The “C” usage designation is a
|
|
62
|
-
* placeholder indicating that the usage for this element has not yet been
|
|
63
|
-
* specified.
|
|
64
|
-
*/
|
|
65
|
-
Conditional: "C",
|
|
66
|
-
/**
|
|
67
|
-
* Not Supported.
|
|
68
|
-
*
|
|
69
|
-
* There are no implementation requirements. The application must not value an
|
|
70
|
-
* element with an “X” usage designation.
|
|
71
|
-
*/
|
|
72
|
-
NotSupported: "X",
|
|
73
|
-
/**
|
|
74
|
-
* Optional
|
|
75
|
-
*
|
|
76
|
-
* There are no implementation requirements. The “O” usage designation is a
|
|
77
|
-
* placeholder indicating that the usage for this element has not yet been
|
|
78
|
-
* specified.
|
|
79
|
-
*/
|
|
80
|
-
Optional: "O",
|
|
81
|
-
/**
|
|
82
|
-
* Required
|
|
83
|
-
*/
|
|
84
|
-
Required: "R",
|
|
85
|
-
/**
|
|
86
|
-
* Required, but may be empty.
|
|
87
|
-
*
|
|
88
|
-
* The use of the RE usage code is qualified with the “if data is known”
|
|
89
|
-
* clause. The sender must interpret the clause as “the capability must always
|
|
90
|
-
* be supported, and data must always be sent if known”. To clarify, the
|
|
91
|
-
* sender does not determine whether the data should be sent; to be conformant
|
|
92
|
-
* to the rule, the data must be sent. There is a misconception where the RE
|
|
93
|
-
* usage is interpreted as “the capability must always be supported, and data
|
|
94
|
-
* may or may not be sent even when known based on a condition external to the
|
|
95
|
-
* profile specification”.
|
|
96
|
-
*
|
|
97
|
-
* The receiving application must process in a meaningful way the information
|
|
98
|
-
* conveyed by an element with an “RE” usage designation.
|
|
99
|
-
* The receiving application must process the message if the element is omitted
|
|
100
|
-
* (that is, an exception must not be raised because the element is missing). A
|
|
101
|
-
* receiving application must not raise an exception due to the presence of a
|
|
102
|
-
* required element.
|
|
103
|
-
*/
|
|
104
|
-
RequiredOrEmpty: "RE",
|
|
105
|
-
/**
|
|
106
|
-
* Withdrawn
|
|
107
|
-
*
|
|
108
|
-
* The element has been withdrawn from the standard. There are no
|
|
109
|
-
* implementation requirements. The application must not value an element with
|
|
110
|
-
* a "W" usage designation.
|
|
111
|
-
*/
|
|
112
|
-
Withdrawn: "W"
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/constraints.ts
|
|
92
|
+
const OptionalityCode = {
|
|
93
|
+
BackwardCompatible: "B",
|
|
94
|
+
Conditional: "C",
|
|
95
|
+
NotSupported: "X",
|
|
96
|
+
Optional: "O",
|
|
97
|
+
Required: "R",
|
|
98
|
+
RequiredOrEmpty: "RE",
|
|
99
|
+
Withdrawn: "W"
|
|
113
100
|
};
|
|
101
|
+
/**
|
|
102
|
+
* Checks if a field satisfies the cardinality constraint.
|
|
103
|
+
*/
|
|
114
104
|
function checkCardinality(node, min, max) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
code: "CARDINALITY_OVERFLOW",
|
|
138
|
-
expected: max,
|
|
139
|
-
message: `has ${count} repetitions but allows at most ${max}`
|
|
140
|
-
},
|
|
141
|
-
ok: false
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
return { ok: true };
|
|
105
|
+
if (min < 0 || max !== "*" && max < 0) throw new Error("Min and max lengths must be non-negative");
|
|
106
|
+
if (max !== "*" && min > max) throw new Error("Min length cannot be greater than max length");
|
|
107
|
+
const count = node?.children ? node.children.length : 0;
|
|
108
|
+
if (count < min) return {
|
|
109
|
+
error: {
|
|
110
|
+
actual: count,
|
|
111
|
+
code: "CARDINALITY_UNDERFLOW",
|
|
112
|
+
expected: min,
|
|
113
|
+
message: `has ${count} repetitions but requires at least ${min}`
|
|
114
|
+
},
|
|
115
|
+
ok: false
|
|
116
|
+
};
|
|
117
|
+
if (max !== "*" && count > max) return {
|
|
118
|
+
error: {
|
|
119
|
+
actual: count,
|
|
120
|
+
code: "CARDINALITY_OVERFLOW",
|
|
121
|
+
expected: max,
|
|
122
|
+
message: `has ${count} repetitions but allows at most ${max}`
|
|
123
|
+
},
|
|
124
|
+
ok: false
|
|
125
|
+
};
|
|
126
|
+
return { ok: true };
|
|
145
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Checks if a node satisfies the length constraint.
|
|
130
|
+
*/
|
|
146
131
|
function checkLength(node, max, min = 0) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
code: "LENGTH_OVERFLOW",
|
|
170
|
-
expected: max,
|
|
171
|
-
message: `has length ${length} but allows at most ${max}`
|
|
172
|
-
},
|
|
173
|
-
ok: false
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
return { ok: true };
|
|
132
|
+
if (min < 0 || max < 0) throw new Error("Min and max lengths must be non-negative");
|
|
133
|
+
if (min > max) throw new Error("Min length cannot be greater than max length");
|
|
134
|
+
const length = getLength(node);
|
|
135
|
+
if (length < min) return {
|
|
136
|
+
error: {
|
|
137
|
+
actual: length,
|
|
138
|
+
code: "LENGTH_UNDERFLOW",
|
|
139
|
+
expected: min,
|
|
140
|
+
message: `has length ${length} but requires at least ${min}`
|
|
141
|
+
},
|
|
142
|
+
ok: false
|
|
143
|
+
};
|
|
144
|
+
if (length > max) return {
|
|
145
|
+
error: {
|
|
146
|
+
actual: length,
|
|
147
|
+
code: "LENGTH_OVERFLOW",
|
|
148
|
+
expected: max,
|
|
149
|
+
message: `has length ${length} but allows at most ${max}`
|
|
150
|
+
},
|
|
151
|
+
ok: false
|
|
152
|
+
};
|
|
153
|
+
return { ok: true };
|
|
177
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Checks if a node satisfies the optionality constraint.
|
|
157
|
+
*/
|
|
178
158
|
function checkOptionality(node, optionality) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return { ok: true };
|
|
216
|
-
}
|
|
217
|
-
case OptionalityCode.RequiredOrEmpty:
|
|
218
|
-
case OptionalityCode.Optional:
|
|
219
|
-
case OptionalityCode.Conditional:
|
|
220
|
-
case OptionalityCode.BackwardCompatible:
|
|
221
|
-
case OptionalityCode.Withdrawn: {
|
|
222
|
-
return { ok: true };
|
|
223
|
-
}
|
|
224
|
-
default: {
|
|
225
|
-
return { ok: true };
|
|
226
|
-
}
|
|
227
|
-
}
|
|
159
|
+
switch (optionality.toUpperCase()) {
|
|
160
|
+
case OptionalityCode.Required:
|
|
161
|
+
if (!node) return {
|
|
162
|
+
error: {
|
|
163
|
+
code: "MISSING",
|
|
164
|
+
expected: "R",
|
|
165
|
+
message: "is required but missing"
|
|
166
|
+
},
|
|
167
|
+
ok: false
|
|
168
|
+
};
|
|
169
|
+
if (isEmptyNode(node)) return {
|
|
170
|
+
error: {
|
|
171
|
+
code: "EMPTY",
|
|
172
|
+
expected: "R",
|
|
173
|
+
message: "is required but empty"
|
|
174
|
+
},
|
|
175
|
+
ok: false
|
|
176
|
+
};
|
|
177
|
+
return { ok: true };
|
|
178
|
+
case OptionalityCode.NotSupported:
|
|
179
|
+
if (node && !isEmptyNode(node)) return {
|
|
180
|
+
error: {
|
|
181
|
+
code: "UNEXPECTED_CONTENT",
|
|
182
|
+
expected: "X",
|
|
183
|
+
message: "is not supported but present"
|
|
184
|
+
},
|
|
185
|
+
ok: false
|
|
186
|
+
};
|
|
187
|
+
return { ok: true };
|
|
188
|
+
case OptionalityCode.RequiredOrEmpty:
|
|
189
|
+
case OptionalityCode.Optional:
|
|
190
|
+
case OptionalityCode.Conditional:
|
|
191
|
+
case OptionalityCode.BackwardCompatible:
|
|
192
|
+
case OptionalityCode.Withdrawn: return { ok: true };
|
|
193
|
+
default: return { ok: true };
|
|
194
|
+
}
|
|
228
195
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
checkCardinality,
|
|
233
|
-
checkLength,
|
|
234
|
-
checkOptionality,
|
|
235
|
-
getByteLength,
|
|
236
|
-
getLength,
|
|
237
|
-
isEmptyNode
|
|
238
|
-
};
|
|
196
|
+
//#endregion
|
|
197
|
+
export { DEFAULT_DELIMITERS, OptionalityCode, checkCardinality, checkLength, checkOptionality, getByteLength, getLength, isEmptyNode };
|
|
198
|
+
|
|
239
199
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/utils.ts","../src/constraints.ts"],"sourcesContent":["// -------------\n// Delimiters\n// -------------\n\nexport const DEFAULT_DELIMITERS = {\n component: \"^\",\n escape: \"\\\\\",\n field: \"|\",\n repetition: \"~\",\n segment: \"\\r\",\n subcomponent: \"&\",\n};\n","import type { Nodes } from \"@rethinkhealth/hl7v2-ast\";\n\n// -------------\n// General\n// -------------\n\n/**\n * Check if an HL7v2 AST node is semantically empty.\n *\n * A node is empty when it contains no meaningful data — no subcomponent\n * anywhere in its subtree has a non-empty string value.\n *\n * This follows the HL7v2 specification (Chapter 2, Section 2.5.3) and\n * Conformance Methodology R1 (2019) definition of \"non-empty value\":\n * at least one character must be a non-whitespace character.\n *\n * ## HL7v2 emptiness semantics\n *\n * | Encoding | Wire form | isEmpty? | Meaning |\n * |-------------|---------------|----------|----------------------------------|\n * | `value` | `\\|value\\|` | `false` | Field has data |\n * | `^DOE` | `\\|^DOE\\|` | `false` | Component 2 has data |\n * | `~value` | `\\|~value\\|` | `false` | Repetition 2 has data |\n * | `\"\"` | `\\|\"\"\\|` | `false` | Explicit null (delete indicator) |\n * | (empty) | `\\|\\|` | `true` | Not present |\n * | `^^` | `\\|^^\\|` | `true` | Empty components |\n * | `~` | `\\|~\\|` | `true` | Empty repetitions |\n * | `~^^` | `\\|~^^\\|` | `true` | Empty reps with empty components |\n *\n * @param node - The HL7v2 AST node to check (or null/undefined)\n * @returns `true` if the node has no meaningful data\n */\nexport function isEmptyNode(node?: Nodes | null | undefined): boolean {\n if (!node) {\n return true;\n }\n\n // Leaf node (Subcomponent): check its string value\n if (\"value\" in node) {\n return !node.value || node.value.trim() === \"\";\n }\n\n // Parent node: empty if ALL children are empty\n if (\"children\" in node) {\n if (!node.children || node.children.length === 0) {\n return true;\n }\n\n return node.children.every((child) => isEmptyNode(child));\n }\n\n // Fallback: consider unknown node as non-empty\n return false;\n}\n\n// -------------\n// Byte Length\n// -------------\n\n/**\n * Calculate the byte length of any HL7v2 AST node.\n *\n * For literal nodes (Subcomponent), returns the UTF-8 byte length of the value.\n * For parent nodes, recursively calculates the length of all children. Delimiters are NOT included.\n *\n * @param node - The HL7v2 AST node to measure\n * @returns The total byte length of the node content\n *\n * @example\n * ```ts\n * const field: Field = { type: \"field\", children: [...] };\n * const length = getByteLength(field); // e.g., 42\n * ```\n */\nexport function getByteLength(node?: Nodes | null | undefined): number {\n if (!node) {\n return 0;\n }\n\n if (\"value\" in node) {\n return Buffer.byteLength(node.value, \"utf8\");\n }\n\n const nameLength =\n node.type === \"segment\" ? Buffer.byteLength(node.name, \"utf8\") : 0;\n\n return (\n nameLength +\n node.children.reduce((total, child) => total + getByteLength(child), 0)\n );\n}\n\n// -------------\n// Length\n// -------------\n\n/**\n * Calculate the string length of any HL7v2 AST node.\n *\n * For literal nodes (Subcomponent), returns `value.length`.\n * For parent nodes, recursively calculates the length of all children. Delimiters are NOT included.\n *\n * Note: Returns JavaScript string length (UTF-16 code units). For UTF-8 byte\n * length (e.g., for wire protocol), use `getByteLength` instead.\n *\n * @param node - The HL7v2 AST node to measure\n * @returns The total string length of the node content\n *\n * @example\n * ```ts\n * const field: Field = { type: \"field\", children: [...] };\n * const length = getLength(field); // e.g., 42\n * ```\n */\nexport function getLength(node?: Nodes | null | undefined): number {\n if (!node) {\n return 0;\n }\n\n if (\"value\" in node) {\n return node.value.length;\n }\n\n const nameLength = node.type === \"segment\" ? node.name.length : 0;\n\n return (\n nameLength +\n node.children.reduce((total, child) => total + getLength(child), 0)\n );\n}\n","import type { Field, Nodes } from \"@rethinkhealth/hl7v2-ast\";\n\nimport { getLength, isEmptyNode } from \"./utils\";\n\nexport type ValidationErrorCode =\n // Constraints\n | \"MISSING\"\n | \"EMPTY\"\n | \"UNEXPECTED_CONTENT\"\n | \"CARDINALITY_UNDERFLOW\"\n | \"CARDINALITY_OVERFLOW\"\n | \"LENGTH_UNDERFLOW\"\n | \"LENGTH_OVERFLOW\"\n // Value Sets\n | \"VALUE_NOT_IN_TABLE\";\n\nexport interface ValidationError {\n code: ValidationErrorCode;\n message: string;\n expected?: string | number | Array<string | number>;\n actual?: string | number | Array<string | number>;\n}\n\nexport interface ValidationSuccess {\n ok: true;\n}\n\nexport interface ValidationFailure {\n ok: false;\n error: ValidationError;\n}\n\nexport type ValidationResult = ValidationSuccess | ValidationFailure;\n\nexport const OptionalityCode = {\n /**\n * Backward Compatible\n *\n * There are no implementation requirements. The “B” usage indicates that the\n * element is retained for backwards compatibility of the element. Another\n * usage indicator may be assigned in a derived profile.\n */\n BackwardCompatible: \"B\",\n\n /**\n * Undeclared / Conditional.\n *\n * There are no implementation requirements. The “C” usage designation is a\n * placeholder indicating that the usage for this element has not yet been\n * specified.\n */\n Conditional: \"C\",\n\n /**\n * Not Supported.\n *\n * There are no implementation requirements. The application must not value an\n * element with an “X” usage designation.\n */\n NotSupported: \"X\",\n\n /**\n * Optional\n *\n * There are no implementation requirements. The “O” usage designation is a\n * placeholder indicating that the usage for this element has not yet been\n * specified.\n */\n Optional: \"O\",\n\n /**\n * Required\n */\n Required: \"R\",\n\n /**\n * Required, but may be empty.\n *\n * The use of the RE usage code is qualified with the “if data is known”\n * clause. The sender must interpret the clause as “the capability must always\n * be supported, and data must always be sent if known”. To clarify, the\n * sender does not determine whether the data should be sent; to be conformant\n * to the rule, the data must be sent. There is a misconception where the RE\n * usage is interpreted as “the capability must always be supported, and data\n * may or may not be sent even when known based on a condition external to the\n * profile specification”.\n *\n * The receiving application must process in a meaningful way the information\n * conveyed by an element with an “RE” usage designation.\n * The receiving application must process the message if the element is omitted\n * (that is, an exception must not be raised because the element is missing). A\n * receiving application must not raise an exception due to the presence of a\n * required element.\n */\n RequiredOrEmpty: \"RE\",\n\n /**\n * Withdrawn\n *\n * The element has been withdrawn from the standard. There are no\n * implementation requirements. The application must not value an element with\n * a \"W\" usage designation.\n */\n Withdrawn: \"W\",\n} as const;\n\nexport type OptionalityCode =\n (typeof OptionalityCode)[keyof typeof OptionalityCode];\n\n/**\n * Checks if a field satisfies the cardinality constraint.\n */\nexport function checkCardinality(\n node: Field | undefined,\n min: number,\n max: number | \"*\"\n): ValidationResult {\n if (min < 0 || (max !== \"*\" && max < 0)) {\n throw new Error(\"Min and max lengths must be non-negative\");\n }\n\n if (max !== \"*\" && min > max) {\n throw new Error(\"Min length cannot be greater than max length\");\n }\n\n const count = node?.children ? node.children.length : 0;\n\n if (count < min) {\n return {\n error: {\n actual: count,\n code: \"CARDINALITY_UNDERFLOW\",\n expected: min,\n message: `has ${count} repetitions but requires at least ${min}`,\n },\n ok: false,\n };\n }\n\n if (max !== \"*\" && count > max) {\n return {\n error: {\n actual: count,\n code: \"CARDINALITY_OVERFLOW\",\n expected: max,\n message: `has ${count} repetitions but allows at most ${max}`,\n },\n ok: false,\n };\n }\n\n return { ok: true };\n}\n\n/**\n * Checks if a node satisfies the length constraint.\n */\nexport function checkLength(\n node: Nodes | undefined,\n max: number,\n min = 0\n): ValidationResult {\n if (min < 0 || max < 0) {\n throw new Error(\"Min and max lengths must be non-negative\");\n }\n\n if (min > max) {\n throw new Error(\"Min length cannot be greater than max length\");\n }\n\n const length = getLength(node);\n\n if (length < min) {\n return {\n error: {\n actual: length,\n code: \"LENGTH_UNDERFLOW\",\n expected: min,\n message: `has length ${length} but requires at least ${min}`,\n },\n ok: false,\n };\n }\n\n if (length > max) {\n return {\n error: {\n actual: length,\n code: \"LENGTH_OVERFLOW\",\n expected: max,\n message: `has length ${length} but allows at most ${max}`,\n },\n ok: false,\n };\n }\n\n return { ok: true };\n}\n\n/**\n * Checks if a node satisfies the optionality constraint.\n */\nexport function checkOptionality(\n node: Nodes | undefined,\n optionality: OptionalityCode | string\n): ValidationResult {\n const code = optionality.toUpperCase();\n\n switch (code) {\n case OptionalityCode.Required: {\n if (!node) {\n return {\n error: {\n code: \"MISSING\",\n expected: \"R\",\n message: \"is required but missing\",\n },\n ok: false,\n };\n }\n if (isEmptyNode(node)) {\n return {\n error: {\n code: \"EMPTY\",\n expected: \"R\",\n message: \"is required but empty\",\n },\n ok: false,\n };\n }\n return { ok: true };\n }\n\n case OptionalityCode.NotSupported: {\n if (node && !isEmptyNode(node)) {\n return {\n error: {\n code: \"UNEXPECTED_CONTENT\",\n expected: \"X\",\n message: \"is not supported but present\",\n },\n ok: false,\n };\n }\n return { ok: true };\n }\n\n case OptionalityCode.RequiredOrEmpty:\n case OptionalityCode.Optional:\n case OptionalityCode.Conditional:\n case OptionalityCode.BackwardCompatible:\n case OptionalityCode.Withdrawn: {\n return { ok: true };\n }\n\n default: {\n return { ok: true };\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/utils.ts","../src/constraints.ts"],"sourcesContent":["// -------------\n// Delimiters\n// -------------\n\nexport const DEFAULT_DELIMITERS = {\n component: \"^\",\n escape: \"\\\\\",\n field: \"|\",\n repetition: \"~\",\n segment: \"\\r\",\n subcomponent: \"&\",\n};\n","import type { Nodes } from \"@rethinkhealth/hl7v2-ast\";\n\n// -------------\n// General\n// -------------\n\n/**\n * Check if an HL7v2 AST node is semantically empty.\n *\n * A node is empty when it contains no meaningful data — no subcomponent\n * anywhere in its subtree has a non-empty string value.\n *\n * This follows the HL7v2 specification (Chapter 2, Section 2.5.3) and\n * Conformance Methodology R1 (2019) definition of \"non-empty value\":\n * at least one character must be a non-whitespace character.\n *\n * ## HL7v2 emptiness semantics\n *\n * | Encoding | Wire form | isEmpty? | Meaning |\n * |-------------|---------------|----------|----------------------------------|\n * | `value` | `\\|value\\|` | `false` | Field has data |\n * | `^DOE` | `\\|^DOE\\|` | `false` | Component 2 has data |\n * | `~value` | `\\|~value\\|` | `false` | Repetition 2 has data |\n * | `\"\"` | `\\|\"\"\\|` | `false` | Explicit null (delete indicator) |\n * | (empty) | `\\|\\|` | `true` | Not present |\n * | `^^` | `\\|^^\\|` | `true` | Empty components |\n * | `~` | `\\|~\\|` | `true` | Empty repetitions |\n * | `~^^` | `\\|~^^\\|` | `true` | Empty reps with empty components |\n *\n * @param node - The HL7v2 AST node to check (or null/undefined)\n * @returns `true` if the node has no meaningful data\n */\nexport function isEmptyNode(node?: Nodes | null | undefined): boolean {\n if (!node) {\n return true;\n }\n\n // Leaf node (Subcomponent): check its string value\n if (\"value\" in node) {\n return !node.value || node.value.trim() === \"\";\n }\n\n // Parent node: empty if ALL children are empty\n if (\"children\" in node) {\n if (!node.children || node.children.length === 0) {\n return true;\n }\n\n return node.children.every((child) => isEmptyNode(child));\n }\n\n // Fallback: consider unknown node as non-empty\n return false;\n}\n\n// -------------\n// Byte Length\n// -------------\n\n/**\n * Calculate the byte length of any HL7v2 AST node.\n *\n * For literal nodes (Subcomponent), returns the UTF-8 byte length of the value.\n * For parent nodes, recursively calculates the length of all children. Delimiters are NOT included.\n *\n * @param node - The HL7v2 AST node to measure\n * @returns The total byte length of the node content\n *\n * @example\n * ```ts\n * const field: Field = { type: \"field\", children: [...] };\n * const length = getByteLength(field); // e.g., 42\n * ```\n */\nexport function getByteLength(node?: Nodes | null | undefined): number {\n if (!node) {\n return 0;\n }\n\n if (\"value\" in node) {\n return Buffer.byteLength(node.value, \"utf8\");\n }\n\n const nameLength =\n node.type === \"segment\" ? Buffer.byteLength(node.name, \"utf8\") : 0;\n\n return (\n nameLength +\n node.children.reduce((total, child) => total + getByteLength(child), 0)\n );\n}\n\n// -------------\n// Length\n// -------------\n\n/**\n * Calculate the string length of any HL7v2 AST node.\n *\n * For literal nodes (Subcomponent), returns `value.length`.\n * For parent nodes, recursively calculates the length of all children. Delimiters are NOT included.\n *\n * Note: Returns JavaScript string length (UTF-16 code units). For UTF-8 byte\n * length (e.g., for wire protocol), use `getByteLength` instead.\n *\n * @param node - The HL7v2 AST node to measure\n * @returns The total string length of the node content\n *\n * @example\n * ```ts\n * const field: Field = { type: \"field\", children: [...] };\n * const length = getLength(field); // e.g., 42\n * ```\n */\nexport function getLength(node?: Nodes | null | undefined): number {\n if (!node) {\n return 0;\n }\n\n if (\"value\" in node) {\n return node.value.length;\n }\n\n const nameLength = node.type === \"segment\" ? node.name.length : 0;\n\n return (\n nameLength +\n node.children.reduce((total, child) => total + getLength(child), 0)\n );\n}\n","import type { Field, Nodes } from \"@rethinkhealth/hl7v2-ast\";\n\nimport { getLength, isEmptyNode } from \"./utils\";\n\nexport type ValidationErrorCode =\n // Constraints\n | \"MISSING\"\n | \"EMPTY\"\n | \"UNEXPECTED_CONTENT\"\n | \"CARDINALITY_UNDERFLOW\"\n | \"CARDINALITY_OVERFLOW\"\n | \"LENGTH_UNDERFLOW\"\n | \"LENGTH_OVERFLOW\"\n // Value Sets\n | \"VALUE_NOT_IN_TABLE\";\n\nexport interface ValidationError {\n code: ValidationErrorCode;\n message: string;\n expected?: string | number | Array<string | number>;\n actual?: string | number | Array<string | number>;\n}\n\nexport interface ValidationSuccess {\n ok: true;\n}\n\nexport interface ValidationFailure {\n ok: false;\n error: ValidationError;\n}\n\nexport type ValidationResult = ValidationSuccess | ValidationFailure;\n\nexport const OptionalityCode = {\n /**\n * Backward Compatible\n *\n * There are no implementation requirements. The “B” usage indicates that the\n * element is retained for backwards compatibility of the element. Another\n * usage indicator may be assigned in a derived profile.\n */\n BackwardCompatible: \"B\",\n\n /**\n * Undeclared / Conditional.\n *\n * There are no implementation requirements. The “C” usage designation is a\n * placeholder indicating that the usage for this element has not yet been\n * specified.\n */\n Conditional: \"C\",\n\n /**\n * Not Supported.\n *\n * There are no implementation requirements. The application must not value an\n * element with an “X” usage designation.\n */\n NotSupported: \"X\",\n\n /**\n * Optional\n *\n * There are no implementation requirements. The “O” usage designation is a\n * placeholder indicating that the usage for this element has not yet been\n * specified.\n */\n Optional: \"O\",\n\n /**\n * Required\n */\n Required: \"R\",\n\n /**\n * Required, but may be empty.\n *\n * The use of the RE usage code is qualified with the “if data is known”\n * clause. The sender must interpret the clause as “the capability must always\n * be supported, and data must always be sent if known”. To clarify, the\n * sender does not determine whether the data should be sent; to be conformant\n * to the rule, the data must be sent. There is a misconception where the RE\n * usage is interpreted as “the capability must always be supported, and data\n * may or may not be sent even when known based on a condition external to the\n * profile specification”.\n *\n * The receiving application must process in a meaningful way the information\n * conveyed by an element with an “RE” usage designation.\n * The receiving application must process the message if the element is omitted\n * (that is, an exception must not be raised because the element is missing). A\n * receiving application must not raise an exception due to the presence of a\n * required element.\n */\n RequiredOrEmpty: \"RE\",\n\n /**\n * Withdrawn\n *\n * The element has been withdrawn from the standard. There are no\n * implementation requirements. The application must not value an element with\n * a \"W\" usage designation.\n */\n Withdrawn: \"W\",\n} as const;\n\nexport type OptionalityCode =\n (typeof OptionalityCode)[keyof typeof OptionalityCode];\n\n/**\n * Checks if a field satisfies the cardinality constraint.\n */\nexport function checkCardinality(\n node: Field | undefined,\n min: number,\n max: number | \"*\"\n): ValidationResult {\n if (min < 0 || (max !== \"*\" && max < 0)) {\n throw new Error(\"Min and max lengths must be non-negative\");\n }\n\n if (max !== \"*\" && min > max) {\n throw new Error(\"Min length cannot be greater than max length\");\n }\n\n const count = node?.children ? node.children.length : 0;\n\n if (count < min) {\n return {\n error: {\n actual: count,\n code: \"CARDINALITY_UNDERFLOW\",\n expected: min,\n message: `has ${count} repetitions but requires at least ${min}`,\n },\n ok: false,\n };\n }\n\n if (max !== \"*\" && count > max) {\n return {\n error: {\n actual: count,\n code: \"CARDINALITY_OVERFLOW\",\n expected: max,\n message: `has ${count} repetitions but allows at most ${max}`,\n },\n ok: false,\n };\n }\n\n return { ok: true };\n}\n\n/**\n * Checks if a node satisfies the length constraint.\n */\nexport function checkLength(\n node: Nodes | undefined,\n max: number,\n min = 0\n): ValidationResult {\n if (min < 0 || max < 0) {\n throw new Error(\"Min and max lengths must be non-negative\");\n }\n\n if (min > max) {\n throw new Error(\"Min length cannot be greater than max length\");\n }\n\n const length = getLength(node);\n\n if (length < min) {\n return {\n error: {\n actual: length,\n code: \"LENGTH_UNDERFLOW\",\n expected: min,\n message: `has length ${length} but requires at least ${min}`,\n },\n ok: false,\n };\n }\n\n if (length > max) {\n return {\n error: {\n actual: length,\n code: \"LENGTH_OVERFLOW\",\n expected: max,\n message: `has length ${length} but allows at most ${max}`,\n },\n ok: false,\n };\n }\n\n return { ok: true };\n}\n\n/**\n * Checks if a node satisfies the optionality constraint.\n */\nexport function checkOptionality(\n node: Nodes | undefined,\n optionality: OptionalityCode | string\n): ValidationResult {\n const code = optionality.toUpperCase();\n\n switch (code) {\n case OptionalityCode.Required: {\n if (!node) {\n return {\n error: {\n code: \"MISSING\",\n expected: \"R\",\n message: \"is required but missing\",\n },\n ok: false,\n };\n }\n if (isEmptyNode(node)) {\n return {\n error: {\n code: \"EMPTY\",\n expected: \"R\",\n message: \"is required but empty\",\n },\n ok: false,\n };\n }\n return { ok: true };\n }\n\n case OptionalityCode.NotSupported: {\n if (node && !isEmptyNode(node)) {\n return {\n error: {\n code: \"UNEXPECTED_CONTENT\",\n expected: \"X\",\n message: \"is not supported but present\",\n },\n ok: false,\n };\n }\n return { ok: true };\n }\n\n case OptionalityCode.RequiredOrEmpty:\n case OptionalityCode.Optional:\n case OptionalityCode.Conditional:\n case OptionalityCode.BackwardCompatible:\n case OptionalityCode.Withdrawn: {\n return { ok: true };\n }\n\n default: {\n return { ok: true };\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rethinkhealth/hl7v2-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "hl7v2 utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"health",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"@types/node": "^25.5.0",
|
|
33
33
|
"@types/unist": "^3.0.3",
|
|
34
34
|
"@vitest/coverage-v8": "4.1.0",
|
|
35
|
-
"
|
|
35
|
+
"tsdown": "0.21.7",
|
|
36
36
|
"typescript": "^5.9.3",
|
|
37
37
|
"unist-builder": "^4.0.0",
|
|
38
38
|
"vfile": "^6.0.3",
|
|
39
39
|
"vitest": "4.1.0",
|
|
40
|
-
"@rethinkhealth/hl7v2-ast": "0.
|
|
40
|
+
"@rethinkhealth/hl7v2-ast": "0.13.1",
|
|
41
41
|
"@rethinkhealth/testing": "0.0.2",
|
|
42
42
|
"@rethinkhealth/tsconfig": "0.0.1"
|
|
43
43
|
},
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"packageManager": "pnpm@10.14.0",
|
|
48
48
|
"scripts": {
|
|
49
|
-
"build": "
|
|
49
|
+
"build": "tsdown && tsc --emitDeclarationOnly",
|
|
50
50
|
"check-types": "tsc --noEmit",
|
|
51
51
|
"test": "vitest run",
|
|
52
52
|
"test:coverage": "vitest run --coverage",
|