@glion/lint-profile-extra-components 0.23.0 → 0.25.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 +11 -7
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -35
- package/dist/index.js.map +1 -1
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Lint rule to warn when a composite field contains more components than its datat
|
|
|
4
4
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
|
-
Flags
|
|
7
|
+
Flags a field repetition with more components than its datatype defines in the message's version. A primitive datatype defines one component. Empty fields, fields on unknown segments, and fields with no datatype are skipped. 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,6 +16,7 @@ npm install @glion/lint-profile-extra-components
|
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
18
|
import { hl7v2AnnotateProfileContext } from "@glion/annotate-profile-context";
|
|
19
|
+
import { hl7v2AnnotateProfileFields } from "@glion/annotate-profile-fields";
|
|
19
20
|
import { hl7v2Parser } from "@glion/parser";
|
|
20
21
|
import hl7v2LintExtraComponents from "@glion/lint-profile-extra-components";
|
|
21
22
|
import { unified } from "unified";
|
|
@@ -29,6 +30,7 @@ const message = [
|
|
|
29
30
|
const file = await unified()
|
|
30
31
|
.use(hl7v2Parser)
|
|
31
32
|
.use(hl7v2AnnotateProfileContext)
|
|
33
|
+
.use(hl7v2AnnotateProfileFields)
|
|
32
34
|
.use(hl7v2LintExtraComponents)
|
|
33
35
|
.process(message);
|
|
34
36
|
|
|
@@ -39,9 +41,7 @@ console.error(reporter([file]));
|
|
|
39
41
|
|
|
40
42
|
### `unified().use(hl7v2LintExtraComponents)`
|
|
41
43
|
|
|
42
|
-
A `unified` lint rule plugin. Takes no options.
|
|
43
|
-
|
|
44
|
-
Reads `file.data.profile`. For each non-empty field it resolves the datatype definition. For primitives the allowed component count is 1; for composites it is the highest key in `dtDef.componentsBySequence`. Every component at a position greater than that max produces one message per offending repetition.
|
|
44
|
+
A `unified` lint rule plugin. Takes no options. Reports one message for each repetition with too many components, with the number of components in `actual`.
|
|
45
45
|
|
|
46
46
|
```ts
|
|
47
47
|
import type { Plugin } from "unified";
|
|
@@ -53,7 +53,7 @@ export default hl7v2LintExtraComponents;
|
|
|
53
53
|
|
|
54
54
|
## What it checks
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
A field repetition has at most as many components as its datatype defines. `PID-8` (Administrative Sex) is a primitive field in v2.5, so it allows one component.
|
|
57
57
|
|
|
58
58
|
### Valid
|
|
59
59
|
|
|
@@ -76,10 +76,14 @@ PID|1||PATID1234^^^HOSP^MR||DOE^JANE||19800101|F^EXTRA
|
|
|
76
76
|
Reported message:
|
|
77
77
|
|
|
78
78
|
```
|
|
79
|
-
|
|
79
|
+
Field `PID-8` (Administrative Sex) has 2 components; it allows at most 1 component.
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
The
|
|
82
|
+
The limit comes from the field's datatype in the message's version. `PID-3` is a `CX` field, which defines 10 components in v2.5, so a repetition with 11 is reported as:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
Field `PID-3` (Patient Identifier List) has 11 components; it allows at most 10 components.
|
|
86
|
+
```
|
|
83
87
|
|
|
84
88
|
## Part of Glion
|
|
85
89
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import type { Root } from "@glion/ast";
|
|
2
2
|
/**
|
|
3
|
-
* Lint rule that
|
|
4
|
-
* datatype
|
|
3
|
+
* Lint rule that reports a field repetition with more components than its
|
|
4
|
+
* datatype defines.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* For primitive datatypes, the maximum is 1 — any additional components
|
|
8
|
-
* are flagged as extra.
|
|
6
|
+
* A primitive datatype defines one component. Empty fields are not checked.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Reads `id` and `datatype` from `field.data`, so
|
|
9
|
+
* `@glion/annotate-profile-fields` MUST run before it.
|
|
12
10
|
*
|
|
13
11
|
* @example
|
|
14
12
|
* ```typescript
|
|
15
|
-
* unified()
|
|
13
|
+
* unified()
|
|
14
|
+
* .use(hl7v2AnnotateProfileContext)
|
|
15
|
+
* .use(hl7v2AnnotateProfileFields)
|
|
16
|
+
* .use(hl7v2LintExtraComponents);
|
|
16
17
|
* ```;
|
|
17
18
|
*/
|
|
18
19
|
declare const hl7v2LintExtraComponents: 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":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAgBvC;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,wBAAwB,mDAwC7B,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
import { SKIP, visit } from "@glion/util-visit";
|
|
2
2
|
import { isEmptyNode } from "@glion/utils";
|
|
3
|
+
import pluralize from "pluralize";
|
|
3
4
|
import { lintRule } from "unified-lint-rule";
|
|
4
5
|
//#region src/index.ts
|
|
6
|
+
const messages = { tooManyComponents: (field, name, count, max) => `Field \`${field}\` (${name}) has ${pluralize("component", count, true)}; it allows at most ${pluralize("component", max, true)}.` };
|
|
5
7
|
/**
|
|
6
|
-
* Lint rule that
|
|
7
|
-
* datatype
|
|
8
|
+
* Lint rule that reports a field repetition with more components than its
|
|
9
|
+
* datatype defines.
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
* For primitive datatypes, the maximum is 1 — any additional components
|
|
11
|
-
* are flagged as extra.
|
|
11
|
+
* A primitive datatype defines one component. Empty fields are not checked.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* Reads `id` and `datatype` from `field.data`, so
|
|
14
|
+
* `@glion/annotate-profile-fields` MUST run before it.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
17
|
* ```typescript
|
|
18
|
-
* unified()
|
|
18
|
+
* unified()
|
|
19
|
+
* .use(hl7v2AnnotateProfileContext)
|
|
20
|
+
* .use(hl7v2AnnotateProfileFields)
|
|
21
|
+
* .use(hl7v2LintExtraComponents);
|
|
19
22
|
* ```;
|
|
20
23
|
*/
|
|
21
|
-
const hl7v2LintExtraComponents = lintRule({
|
|
24
|
+
const hl7v2LintExtraComponents = lintRule({
|
|
25
|
+
origin: "hl7v2-lint:extra-components",
|
|
26
|
+
url: "https://github.com/rethinkhealth/glion/tree/main/packages/lint-profile-extra-components#readme"
|
|
27
|
+
}, (tree, file) => {
|
|
22
28
|
const ctx = file.data.profile;
|
|
23
29
|
if (!ctx) return;
|
|
24
|
-
visit(tree, "field", (
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
30
|
+
visit(tree, "field", (field, ancestors) => {
|
|
31
|
+
const id = field.data?.id;
|
|
32
|
+
const datatypeId = field.data?.datatype;
|
|
33
|
+
const datatype = datatypeId === void 0 ? void 0 : ctx.datatypes.get(datatypeId);
|
|
34
|
+
if (id === void 0 || datatype === void 0 || isEmptyNode(field)) return SKIP;
|
|
35
|
+
const max = Math.max(1, ...datatype.componentsBySequence.keys());
|
|
36
|
+
for (const repetition of field.children) {
|
|
37
|
+
const count = repetition.children.length;
|
|
38
|
+
if (count > max) {
|
|
39
|
+
const message = file.message(messages.tooManyComponents(id, field.data?.name ?? "", count, max), {
|
|
40
|
+
ancestors: [
|
|
41
|
+
...ancestors,
|
|
42
|
+
field,
|
|
43
|
+
repetition
|
|
44
|
+
],
|
|
45
|
+
place: repetition.position ?? field.position
|
|
46
|
+
});
|
|
47
|
+
message.actual = String(count);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
44
50
|
return SKIP;
|
|
45
51
|
});
|
|
46
52
|
});
|
|
47
|
-
/** Return the highest numeric key in a Map, or 0 if empty. */
|
|
48
|
-
function maxKey(map) {
|
|
49
|
-
let max = 0;
|
|
50
|
-
for (const key of map.keys()) if (key > max) max = key;
|
|
51
|
-
return max;
|
|
52
|
-
}
|
|
53
53
|
//#endregion
|
|
54
54
|
export { hl7v2LintExtraComponents as default };
|
|
55
55
|
|
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 VFile DataMap augmentation\nimport type { ProfileContext } from \"@glion/annotate-profile-context\";\nimport type {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["// oxlint-disable-next-line no-unused-vars -- triggers VFile DataMap augmentation\nimport type { ProfileContext } from \"@glion/annotate-profile-context\";\n// 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 { isEmptyNode } from \"@glion/utils\";\nimport pluralize from \"pluralize\";\nimport { lintRule } from \"unified-lint-rule\";\n\nconst messages = {\n tooManyComponents: (\n field: string,\n name: string,\n count: number,\n max: number\n ) =>\n `Field \\`${field}\\` (${name}) has ${pluralize(\"component\", count, true)}; it allows at most ${pluralize(\"component\", max, true)}.`,\n} as const;\n\n/**\n * Lint rule that reports a field repetition with more components than its\n * datatype defines.\n *\n * A primitive datatype defines one component. Empty fields are not checked.\n *\n * Reads `id` and `datatype` from `field.data`, so\n * `@glion/annotate-profile-fields` MUST run before it.\n *\n * @example\n * ```typescript\n * unified()\n * .use(hl7v2AnnotateProfileContext)\n * .use(hl7v2AnnotateProfileFields)\n * .use(hl7v2LintExtraComponents);\n * ```;\n */\nconst hl7v2LintExtraComponents = lintRule<Root>(\n {\n origin: \"hl7v2-lint:extra-components\",\n url: \"https://github.com/rethinkhealth/glion/tree/main/packages/lint-profile-extra-components#readme\",\n },\n (tree, file) => {\n const ctx = file.data.profile;\n if (!ctx) {\n return;\n }\n\n visit(tree, \"field\", (field, ancestors) => {\n const id = field.data?.id;\n const datatypeId = field.data?.datatype;\n const datatype =\n datatypeId === undefined ? undefined : ctx.datatypes.get(datatypeId);\n if (id === undefined || datatype === undefined || isEmptyNode(field)) {\n return SKIP;\n }\n\n // A primitive datatype has no component definitions; its value is\n // component 1.\n const max = Math.max(1, ...datatype.componentsBySequence.keys());\n\n for (const repetition of field.children) {\n const count = repetition.children.length;\n if (count > max) {\n const message = file.message(\n messages.tooManyComponents(id, field.data?.name ?? \"\", count, max),\n {\n ancestors: [...ancestors, field, repetition],\n place: repetition.position ?? field.position,\n }\n );\n message.actual = String(count);\n }\n }\n return SKIP;\n });\n }\n);\n\nexport default hl7v2LintExtraComponents;\n"],"mappings":";;;;;AAUA,MAAM,WAAW,EACf,oBACE,OACA,MACA,OACA,QAEA,WAAW,MAAM,MAAM,KAAK,QAAQ,UAAU,aAAa,OAAO,KAAK,CAAC,sBAAsB,UAAU,aAAa,KAAK,KAAK,CAAC,IACnI;;;;;;;;;;;;;;;;;;AAmBD,MAAM,2BAA2B,SAC/B;CACE,QAAQ;CACR,KAAK;CACN,GACA,MAAM,SAAS;CACd,MAAM,MAAM,KAAK,KAAK;AACtB,KAAI,CAAC,IACH;AAGF,OAAM,MAAM,UAAU,OAAO,cAAc;EACzC,MAAM,KAAK,MAAM,MAAM;EACvB,MAAM,aAAa,MAAM,MAAM;EAC/B,MAAM,WACJ,eAAe,KAAA,IAAY,KAAA,IAAY,IAAI,UAAU,IAAI,WAAW;AACtE,MAAI,OAAO,KAAA,KAAa,aAAa,KAAA,KAAa,YAAY,MAAM,CAClE,QAAO;EAKT,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,SAAS,qBAAqB,MAAM,CAAC;AAEhE,OAAK,MAAM,cAAc,MAAM,UAAU;GACvC,MAAM,QAAQ,WAAW,SAAS;AAClC,OAAI,QAAQ,KAAK;IACf,MAAM,UAAU,KAAK,QACnB,SAAS,kBAAkB,IAAI,MAAM,MAAM,QAAQ,IAAI,OAAO,IAAI,EAClE;KACE,WAAW;MAAC,GAAG;MAAW;MAAO;MAAW;KAC5C,OAAO,WAAW,YAAY,MAAM;KACrC,CACF;AACD,YAAQ,SAAS,OAAO,MAAM;;;AAGlC,SAAO;GACP;EAEL"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glion/lint-profile-extra-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Lint rule to warn when a composite field contains more components than its datatype profile defines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"health",
|
|
@@ -33,13 +33,16 @@
|
|
|
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/util-visit": "0.
|
|
39
|
-
"@glion/
|
|
38
|
+
"@glion/annotate-profile-fields": "0.25.0",
|
|
39
|
+
"@glion/util-visit": "0.25.0",
|
|
40
|
+
"@glion/ast": "0.25.0",
|
|
41
|
+
"@glion/utils": "0.25.0"
|
|
40
42
|
},
|
|
41
43
|
"devDependencies": {
|
|
42
44
|
"@types/node": "25.6.0",
|
|
45
|
+
"@types/pluralize": "^0.0.33",
|
|
43
46
|
"@vitest/coverage-v8": "4.1.11",
|
|
44
47
|
"publint": "0.3.18",
|
|
45
48
|
"tsdown": "0.21.10",
|
|
@@ -47,8 +50,8 @@
|
|
|
47
50
|
"unified": "^11.0.5",
|
|
48
51
|
"vfile": "^6.0.3",
|
|
49
52
|
"vitest": "4.1.11",
|
|
50
|
-
"@glion/annotate-profile-context": "0.
|
|
51
|
-
"@glion/builder": "0.
|
|
53
|
+
"@glion/annotate-profile-context": "0.25.0",
|
|
54
|
+
"@glion/builder": "0.25.0",
|
|
52
55
|
"@glion/check-readme": "0.18.0",
|
|
53
56
|
"@glion/testing": "0.18.0",
|
|
54
57
|
"@glion/tsconfig": "0.18.0"
|