@glion/lint-profile-field-repetition 0.23.0 → 0.24.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/README.md +15 -16
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -30
- package/dist/index.js.map +1 -1
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @glion/lint-profile-field-repetition
|
|
2
2
|
|
|
3
|
-
Lint rule that
|
|
3
|
+
Lint rule that reports a field with more repetitions than HL7v2 allows.
|
|
4
4
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
|
-
Flags
|
|
7
|
+
Flags a field with more repetitions (separated by `~`) than the HL7v2 standard for the message's version allows: one for a field that does not repeat, or a set number such as 2 for `OBR-17` in v2.6. Fields with no limit on repetitions are never reported. It needs the plugins `@glion/annotate-profile-context` and `@glion/annotate-profile-fields` to run before it; `@glion/preset-lint-profile-recommended` includes them.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -16,21 +16,24 @@ npm install @glion/lint-profile-field-repetition
|
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
18
|
import { hl7v2AnnotateProfileContext } from "@glion/annotate-profile-context";
|
|
19
|
-
import {
|
|
19
|
+
import { hl7v2AnnotateProfileFields } from "@glion/annotate-profile-fields";
|
|
20
20
|
import hl7v2LintFieldRepetition from "@glion/lint-profile-field-repetition";
|
|
21
|
+
import { parseHL7v2 } from "@glion/parser";
|
|
21
22
|
import { unified } from "unified";
|
|
23
|
+
import { VFile } from "vfile";
|
|
22
24
|
import { reporter } from "vfile-reporter";
|
|
23
25
|
|
|
24
26
|
const message = [
|
|
25
27
|
"MSH|^~\\&|SENDER|FAC|RECV|RFAC|20250601120000||ADT^A01^ADT_A01|MSG00001|P|2.5",
|
|
26
|
-
"PID|1||PATID1234^^^HOSP^MR||DOE^JANE||19800101|F",
|
|
28
|
+
"PID|1||PATID1234^^^HOSP^MR||DOE^JANE||19800101~19800102|F",
|
|
27
29
|
].join("\r");
|
|
28
30
|
|
|
29
|
-
const file =
|
|
30
|
-
|
|
31
|
+
const file = new VFile();
|
|
32
|
+
await unified()
|
|
31
33
|
.use(hl7v2AnnotateProfileContext)
|
|
34
|
+
.use(hl7v2AnnotateProfileFields)
|
|
32
35
|
.use(hl7v2LintFieldRepetition)
|
|
33
|
-
.
|
|
36
|
+
.run(parseHL7v2(message), file);
|
|
34
37
|
|
|
35
38
|
console.error(reporter([file]));
|
|
36
39
|
```
|
|
@@ -39,9 +42,7 @@ console.error(reporter([file]));
|
|
|
39
42
|
|
|
40
43
|
### `unified().use(hl7v2LintFieldRepetition)`
|
|
41
44
|
|
|
42
|
-
A `unified` lint rule plugin. Takes no options.
|
|
43
|
-
|
|
44
|
-
Reads `file.data.profile`. For each field under a segment with a known profile it looks up the field entry by sequence. If the field's profile sets `repeatable: false` and the AST has more than one repetition, the rule emits one message for that field.
|
|
45
|
+
A `unified` lint rule plugin. Takes no options. Reports one message for each field with too many repetitions.
|
|
45
46
|
|
|
46
47
|
```ts
|
|
47
48
|
import type { Plugin } from "unified";
|
|
@@ -53,11 +54,11 @@ export default hl7v2LintFieldRepetition;
|
|
|
53
54
|
|
|
54
55
|
## What it checks
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
A field has at most as many repetitions as its repetition limit in the message's version. For example, `PID-7` (Date/Time of Birth) does not repeat in v2.5.
|
|
57
58
|
|
|
58
59
|
### Valid
|
|
59
60
|
|
|
60
|
-
`PID-7`
|
|
61
|
+
`PID-7` has one value:
|
|
61
62
|
|
|
62
63
|
```hl7
|
|
63
64
|
MSH|^~\&|SENDER|FAC|RECV|RFAC|20250601120000||ADT^A01^ADT_A01|MSG00001|P|2.5
|
|
@@ -66,7 +67,7 @@ PID|1||PATID1234^^^HOSP^MR||DOE^JANE||19800101|F
|
|
|
66
67
|
|
|
67
68
|
### Invalid
|
|
68
69
|
|
|
69
|
-
`PID-7`
|
|
70
|
+
`PID-7` has two values:
|
|
70
71
|
|
|
71
72
|
```hl7
|
|
72
73
|
MSH|^~\&|SENDER|FAC|RECV|RFAC|20250601120000||ADT^A01^ADT_A01|MSG00001|P|2.5
|
|
@@ -76,11 +77,9 @@ PID|1||PATID1234^^^HOSP^MR||DOE^JANE||19800101~19800102|F
|
|
|
76
77
|
Reported message:
|
|
77
78
|
|
|
78
79
|
```
|
|
79
|
-
Field PID-7 (Date/Time of Birth)
|
|
80
|
+
Field `PID-7` (Date/Time of Birth) has 2 repetitions; it allows at most 1 repetition.
|
|
80
81
|
```
|
|
81
82
|
|
|
82
|
-
When the field name is available in the profile it appears in parentheses after the position. The reported count equals the number of repetitions present in the field.
|
|
83
|
-
|
|
84
83
|
## Part of Glion
|
|
85
84
|
|
|
86
85
|
`@glion/lint-profile-field-repetition` is part of **[Glion]**, the application framework for HL7v2. See the [Glion README] for the full package catalog and architecture.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { Root } from "@glion/ast";
|
|
2
2
|
/**
|
|
3
|
-
* Lint rule that
|
|
4
|
-
* declares `repeatable: false`.
|
|
3
|
+
* Lint rule that reports a field with more repetitions than its RP/# allows.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Segments without a known profile (e.g., Z-segments) are silently skipped.
|
|
5
|
+
* Reads `repetitions` from `field.data`, so `@glion/annotate-profile-fields`
|
|
6
|
+
* MUST run before it. A field whose `repetitions` is `"unbounded"` is never
|
|
7
|
+
* reported.
|
|
11
8
|
*
|
|
12
9
|
* @example
|
|
13
10
|
* ```typescript
|
|
14
|
-
* unified()
|
|
11
|
+
* unified()
|
|
12
|
+
* .use(hl7v2AnnotateProfileContext)
|
|
13
|
+
* .use(hl7v2AnnotateProfileFields)
|
|
14
|
+
* .use(hl7v2LintFieldRepetition);
|
|
15
15
|
* ```;
|
|
16
16
|
*/
|
|
17
17
|
declare const hl7v2LintFieldRepetition: import("unified-lint-rule").Plugin<Root, unknown>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAevC;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,wBAAwB,mDAuB7B,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,44 +1,37 @@
|
|
|
1
1
|
import { SKIP, visit } from "@glion/util-visit";
|
|
2
|
+
import pluralize from "pluralize";
|
|
2
3
|
import { lintRule } from "unified-lint-rule";
|
|
3
4
|
//#region src/index.ts
|
|
5
|
+
const messages = { tooManyRepetitions: (field, name, count, max) => `Field \`${field}\` (${name}) has ${pluralize("repetition", count, true)}; it allows at most ${pluralize("repetition", max, true)}.` };
|
|
4
6
|
/**
|
|
5
|
-
* Lint rule that
|
|
6
|
-
* declares `repeatable: false`.
|
|
7
|
+
* Lint rule that reports a field with more repetitions than its RP/# allows.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Segments without a known profile (e.g., Z-segments) are silently skipped.
|
|
9
|
+
* Reads `repetitions` from `field.data`, so `@glion/annotate-profile-fields`
|
|
10
|
+
* MUST run before it. A field whose `repetitions` is `"unbounded"` is never
|
|
11
|
+
* reported.
|
|
13
12
|
*
|
|
14
13
|
* @example
|
|
15
14
|
* ```typescript
|
|
16
|
-
* unified()
|
|
15
|
+
* unified()
|
|
16
|
+
* .use(hl7v2AnnotateProfileContext)
|
|
17
|
+
* .use(hl7v2AnnotateProfileFields)
|
|
18
|
+
* .use(hl7v2LintFieldRepetition);
|
|
17
19
|
* ```;
|
|
18
20
|
*/
|
|
19
|
-
const hl7v2LintFieldRepetition = lintRule({
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
file.message(`Field ${segment.name}-${info.sequence}${name} is not repeatable but has ${count} repetitions`, {
|
|
32
|
-
ancestors: [
|
|
33
|
-
...segmentAncestors,
|
|
34
|
-
segment,
|
|
35
|
-
fieldNode
|
|
36
|
-
],
|
|
37
|
-
place: fieldNode.position
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
return SKIP;
|
|
21
|
+
const hl7v2LintFieldRepetition = lintRule({
|
|
22
|
+
origin: "hl7v2-lint:field-repetition",
|
|
23
|
+
url: "https://github.com/rethinkhealth/glion/tree/main/packages/lint-profile-field-repetition#readme"
|
|
24
|
+
}, (tree, file) => {
|
|
25
|
+
visit(tree, "field", (field, ancestors) => {
|
|
26
|
+
const id = field.data?.id;
|
|
27
|
+
const limit = field.data?.repetitions;
|
|
28
|
+
const count = field.children.length;
|
|
29
|
+
if (id === void 0 || typeof limit !== "number" || count <= limit) return SKIP;
|
|
30
|
+
const message = file.message(messages.tooManyRepetitions(id, field.data?.name ?? "", count, limit), {
|
|
31
|
+
ancestors: [...ancestors, field],
|
|
32
|
+
place: field.position
|
|
41
33
|
});
|
|
34
|
+
message.actual = String(count);
|
|
42
35
|
return SKIP;
|
|
43
36
|
});
|
|
44
37
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["// oxlint-disable-next-line no-unused-vars -- triggers
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["// oxlint-disable-next-line no-unused-vars -- triggers FieldData augmentation\nimport type { hl7v2AnnotateProfileFields } from \"@glion/annotate-profile-fields\";\nimport type { Root } from \"@glion/ast\";\nimport { SKIP, visit } from \"@glion/util-visit\";\nimport pluralize from \"pluralize\";\nimport { lintRule } from \"unified-lint-rule\";\n\nconst messages = {\n tooManyRepetitions: (\n field: string,\n name: string,\n count: number,\n max: number\n ) =>\n `Field \\`${field}\\` (${name}) has ${pluralize(\"repetition\", count, true)}; it allows at most ${pluralize(\"repetition\", max, true)}.`,\n} as const;\n\n/**\n * Lint rule that reports a field with more repetitions than its RP/# allows.\n *\n * Reads `repetitions` from `field.data`, so `@glion/annotate-profile-fields`\n * MUST run before it. A field whose `repetitions` is `\"unbounded\"` is never\n * reported.\n *\n * @example\n * ```typescript\n * unified()\n * .use(hl7v2AnnotateProfileContext)\n * .use(hl7v2AnnotateProfileFields)\n * .use(hl7v2LintFieldRepetition);\n * ```;\n */\nconst hl7v2LintFieldRepetition = lintRule<Root>(\n {\n origin: \"hl7v2-lint:field-repetition\",\n url: \"https://github.com/rethinkhealth/glion/tree/main/packages/lint-profile-field-repetition#readme\",\n },\n (tree, file) => {\n visit(tree, \"field\", (field, ancestors) => {\n const id = field.data?.id;\n const limit = field.data?.repetitions;\n const count = field.children.length;\n // A limit of \"unbounded\" is never exceeded.\n if (id === undefined || typeof limit !== \"number\" || count <= limit) {\n return SKIP;\n }\n\n const message = file.message(\n messages.tooManyRepetitions(id, field.data?.name ?? \"\", count, limit),\n { ancestors: [...ancestors, field], place: field.position }\n );\n message.actual = String(count);\n return SKIP;\n });\n }\n);\n\nexport default hl7v2LintFieldRepetition;\n"],"mappings":";;;;AAOA,MAAM,WAAW,EACf,qBACE,OACA,MACA,OACA,QAEA,WAAW,MAAM,MAAM,KAAK,QAAQ,UAAU,cAAc,OAAO,KAAK,CAAC,sBAAsB,UAAU,cAAc,KAAK,KAAK,CAAC,IACrI;;;;;;;;;;;;;;;;AAiBD,MAAM,2BAA2B,SAC/B;CACE,QAAQ;CACR,KAAK;CACN,GACA,MAAM,SAAS;AACd,OAAM,MAAM,UAAU,OAAO,cAAc;EACzC,MAAM,KAAK,MAAM,MAAM;EACvB,MAAM,QAAQ,MAAM,MAAM;EAC1B,MAAM,QAAQ,MAAM,SAAS;AAE7B,MAAI,OAAO,KAAA,KAAa,OAAO,UAAU,YAAY,SAAS,MAC5D,QAAO;EAGT,MAAM,UAAU,KAAK,QACnB,SAAS,mBAAmB,IAAI,MAAM,MAAM,QAAQ,IAAI,OAAO,MAAM,EACrE;GAAE,WAAW,CAAC,GAAG,WAAW,MAAM;GAAE,OAAO,MAAM;GAAU,CAC5D;AACD,UAAQ,SAAS,OAAO,MAAM;AAC9B,SAAO;GACP;EAEL"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glion/lint-profile-field-repetition",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Lint rule that flags non-repeatable fields with multiple repetitions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"health",
|
|
@@ -33,12 +33,15 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"pluralize": "8.0.0",
|
|
36
37
|
"unified-lint-rule": "3.0.1",
|
|
37
|
-
"@glion/
|
|
38
|
-
"@glion/
|
|
38
|
+
"@glion/annotate-profile-fields": "0.24.0",
|
|
39
|
+
"@glion/ast": "0.24.0",
|
|
40
|
+
"@glion/util-visit": "0.24.0"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@types/node": "25.6.0",
|
|
44
|
+
"@types/pluralize": "^0.0.33",
|
|
42
45
|
"@vitest/coverage-v8": "4.1.11",
|
|
43
46
|
"publint": "0.3.18",
|
|
44
47
|
"tsdown": "0.21.10",
|
|
@@ -46,9 +49,10 @@
|
|
|
46
49
|
"unified": "^11.0.5",
|
|
47
50
|
"vfile": "^6.0.3",
|
|
48
51
|
"vitest": "4.1.11",
|
|
49
|
-
"@glion/annotate-profile-context": "0.
|
|
50
|
-
"@glion/builder": "0.
|
|
52
|
+
"@glion/annotate-profile-context": "0.24.0",
|
|
53
|
+
"@glion/builder": "0.24.0",
|
|
51
54
|
"@glion/check-readme": "0.18.0",
|
|
55
|
+
"@glion/parser": "0.24.0",
|
|
52
56
|
"@glion/testing": "0.18.0",
|
|
53
57
|
"@glion/tsconfig": "0.18.0"
|
|
54
58
|
},
|