@peerbits/medical-terminology 0.1.0 → 0.2.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 +13 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/registry.d.ts +2 -0
- package/dist/registry.js +2 -0
- package/dist/types.d.ts +4 -0
- package/dist/validate.d.ts +7 -3
- package/dist/validate.js +17 -5
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @peerbits/medical-terminology
|
|
2
2
|
|
|
3
|
+
Version 0.2 adds batch validation, canonical code-system URI resolution, and an optional strict mode that treats unknown systems as errors. The default remains backward compatible and reports unknown systems as warnings.
|
|
4
|
+
|
|
3
5
|
> Terminology system-URI registry and code format/checksum validation utilities — ships zero licensed terminology datasets (see [Licensing](./docs/LICENSING.md))
|
|
4
6
|
|
|
5
7
|
**Category:** Medical Coding — Terminology & Code-Handling Utilities · **License:** Apache-2.0 · **Status:** Stable
|
|
@@ -50,7 +52,7 @@ npm install @peerbits/medical-terminology
|
|
|
50
52
|
[Peerbits HealthTech - Medical Terminology Demo](https://healthcare.peerbits.com/demo/medical-terminology)
|
|
51
53
|
|
|
52
54
|
```ts
|
|
53
|
-
import {
|
|
55
|
+
import { canonicalizeSystemIdentifier, validate, validateMany } from "@peerbits/medical-terminology";
|
|
54
56
|
|
|
55
57
|
// 1. Validate a LOINC observation code
|
|
56
58
|
const loincResult = validate({
|
|
@@ -74,6 +76,16 @@ const invalidResult = validate({
|
|
|
74
76
|
console.log(invalidResult.valid); // false
|
|
75
77
|
console.log(invalidResult.issues);
|
|
76
78
|
// [ { severity: "error", path: "code", code: "invalid-format", message: "..." } ]
|
|
79
|
+
|
|
80
|
+
// Validate batches and reject unknown code systems when required
|
|
81
|
+
const batch = validateMany([
|
|
82
|
+
{ system: "LOINC", code: "8867-4" },
|
|
83
|
+
{ system: "UCUM", code: "mm[Hg]" },
|
|
84
|
+
], { unknownSystem: "error" });
|
|
85
|
+
|
|
86
|
+
// Resolve aliases and OIDs to the canonical URI
|
|
87
|
+
const canonicalUri = canonicalizeSystemIdentifier("LOINC");
|
|
88
|
+
// http://loinc.org
|
|
77
89
|
```
|
|
78
90
|
|
|
79
91
|
---
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export declare const VERSION = "
|
|
2
|
-
export { validate, validateWithProvider } from "./validate.js";
|
|
1
|
+
export declare const VERSION = "0.2.0";
|
|
2
|
+
export { validate, validateWithProvider, validateMany, validateManyWithProvider } from "./validate.js";
|
|
3
3
|
export { registerProvider, unregisterProvider, clearProviders, lookup, hasProvider, getRegisteredProviderSystems, } from "./provider.js";
|
|
4
|
-
export { SYSTEM_REGISTRY, getSupportedSystems, getSystemByIdentifier, getSystemByShortName, getSystemByUri, } from "./registry.js";
|
|
4
|
+
export { SYSTEM_REGISTRY, getSupportedSystems, getSystemByIdentifier, getSystemByShortName, getSystemByUri, canonicalizeSystemIdentifier, } from "./registry.js";
|
|
5
5
|
export { isValidLoincFormat } from "./validators/loinc.js";
|
|
6
6
|
export { isValidIcd10CmFormat } from "./validators/icd10cm.js";
|
|
7
7
|
export { isValidCptFormat } from "./validators/cpt.js";
|
|
8
8
|
export { isValidRxNormFormat } from "./validators/rxnorm.js";
|
|
9
9
|
export { isValidUcumSyntax } from "./validators/ucum.js";
|
|
10
10
|
export { calculateSctidCheckDigit, isValidSctid, } from "./validators/snomed.js";
|
|
11
|
-
export type { CodedConcept, ProviderLookupResult, SupportedTerminologySystem, TerminologyProvider, TerminologySystem, ValidationIssue, ValidationResult, ValidationSeverity, } from "./types.js";
|
|
11
|
+
export type { CodedConcept, ProviderLookupResult, SupportedTerminologySystem, TerminologyProvider, TerminologySystem, ValidationIssue, ValidationResult, ValidationSeverity, ValidationOptions, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export const VERSION = "
|
|
2
|
-
export { validate, validateWithProvider } from "./validate.js";
|
|
1
|
+
export const VERSION = "0.2.0";
|
|
2
|
+
export { validate, validateWithProvider, validateMany, validateManyWithProvider } from "./validate.js";
|
|
3
3
|
export { registerProvider, unregisterProvider, clearProviders, lookup, hasProvider, getRegisteredProviderSystems, } from "./provider.js";
|
|
4
|
-
export { SYSTEM_REGISTRY, getSupportedSystems, getSystemByIdentifier, getSystemByShortName, getSystemByUri, } from "./registry.js";
|
|
4
|
+
export { SYSTEM_REGISTRY, getSupportedSystems, getSystemByIdentifier, getSystemByShortName, getSystemByUri, canonicalizeSystemIdentifier, } from "./registry.js";
|
|
5
5
|
export { isValidLoincFormat } from "./validators/loinc.js";
|
|
6
6
|
export { isValidIcd10CmFormat } from "./validators/icd10cm.js";
|
|
7
7
|
export { isValidCptFormat } from "./validators/cpt.js";
|
package/dist/registry.d.ts
CHANGED
|
@@ -4,3 +4,5 @@ export declare const getSupportedSystems: () => readonly TerminologySystem[];
|
|
|
4
4
|
export declare const getSystemByShortName: (shortName: string) => TerminologySystem | undefined;
|
|
5
5
|
export declare const getSystemByUri: (uri: string) => TerminologySystem | undefined;
|
|
6
6
|
export declare const getSystemByIdentifier: (identifier: string) => TerminologySystem | undefined;
|
|
7
|
+
/** Resolves a short name, URI, or OID to the canonical FHIR system URI. */
|
|
8
|
+
export declare const canonicalizeSystemIdentifier: (identifier: string) => string | undefined;
|
package/dist/registry.js
CHANGED
|
@@ -65,3 +65,5 @@ export const getSystemByIdentifier = (identifier) => {
|
|
|
65
65
|
const clean = identifier.trim().toLowerCase();
|
|
66
66
|
return byUri.get(clean) ?? byShortName.get(clean) ?? byOid.get(clean);
|
|
67
67
|
};
|
|
68
|
+
/** Resolves a short name, URI, or OID to the canonical FHIR system URI. */
|
|
69
|
+
export const canonicalizeSystemIdentifier = (identifier) => getSystemByIdentifier(identifier)?.uri;
|
package/dist/types.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export interface ValidationResult {
|
|
|
24
24
|
system?: TerminologySystem;
|
|
25
25
|
providerConfigured: boolean;
|
|
26
26
|
}
|
|
27
|
+
export interface ValidationOptions {
|
|
28
|
+
/** Unknown code systems remain warnings by default for backward compatibility. */
|
|
29
|
+
unknownSystem?: "warning" | "error";
|
|
30
|
+
}
|
|
27
31
|
export interface ProviderLookupResult {
|
|
28
32
|
found: boolean;
|
|
29
33
|
display?: string;
|
package/dist/validate.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import type { ValidationResult } from "./types.js";
|
|
1
|
+
import type { ValidationResult, ValidationOptions } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Validates the structure and code format of a coded concept.
|
|
4
4
|
*
|
|
5
5
|
* @param concept The input concept object (e.g., { system, code, display? }).
|
|
6
6
|
* @returns ValidationResult with validity flag, issues, and system metadata.
|
|
7
7
|
*/
|
|
8
|
-
export declare function validate(concept: unknown): ValidationResult;
|
|
8
|
+
export declare function validate(concept: unknown, options?: ValidationOptions): ValidationResult;
|
|
9
9
|
/**
|
|
10
10
|
* Validates format and dispatches to a registered TerminologyProvider if configured.
|
|
11
11
|
*
|
|
12
12
|
* @param concept The input concept object (e.g., { system, code, display? }).
|
|
13
13
|
* @returns Promise<ValidationResult> with format & provider validation results.
|
|
14
14
|
*/
|
|
15
|
-
export declare function validateWithProvider(concept: unknown): Promise<ValidationResult>;
|
|
15
|
+
export declare function validateWithProvider(concept: unknown, options?: ValidationOptions): Promise<ValidationResult>;
|
|
16
|
+
/** Validates a list without stopping at the first invalid concept. */
|
|
17
|
+
export declare function validateMany(concepts: readonly unknown[], options?: ValidationOptions): ValidationResult[];
|
|
18
|
+
/** Provider-aware batch variant. Provider calls are independent and run concurrently. */
|
|
19
|
+
export declare function validateManyWithProvider(concepts: readonly unknown[], options?: ValidationOptions): Promise<ValidationResult[]>;
|
package/dist/validate.js
CHANGED
|
@@ -40,7 +40,7 @@ function extractString(target, key) {
|
|
|
40
40
|
* @param concept The input concept object (e.g., { system, code, display? }).
|
|
41
41
|
* @returns ValidationResult with validity flag, issues, and system metadata.
|
|
42
42
|
*/
|
|
43
|
-
export function validate(concept) {
|
|
43
|
+
export function validate(concept, options) {
|
|
44
44
|
const issues = [];
|
|
45
45
|
if (!concept || typeof concept !== "object" || Array.isArray(concept)) {
|
|
46
46
|
return {
|
|
@@ -87,13 +87,13 @@ export function validate(concept) {
|
|
|
87
87
|
const system = getSystemByUri(systemStr) ?? getSystemByIdentifier(systemStr);
|
|
88
88
|
if (!system) {
|
|
89
89
|
issues.push({
|
|
90
|
-
severity: "warning",
|
|
90
|
+
severity: options?.unknownSystem === "error" ? "error" : "warning",
|
|
91
91
|
path: "system",
|
|
92
92
|
code: "unknown-system",
|
|
93
93
|
message: `Unknown terminology system: "${systemStr}". Format validation was skipped.`,
|
|
94
94
|
});
|
|
95
95
|
return {
|
|
96
|
-
valid:
|
|
96
|
+
valid: options?.unknownSystem !== "error",
|
|
97
97
|
issues,
|
|
98
98
|
providerConfigured: false,
|
|
99
99
|
};
|
|
@@ -121,8 +121,8 @@ export function validate(concept) {
|
|
|
121
121
|
* @param concept The input concept object (e.g., { system, code, display? }).
|
|
122
122
|
* @returns Promise<ValidationResult> with format & provider validation results.
|
|
123
123
|
*/
|
|
124
|
-
export async function validateWithProvider(concept) {
|
|
125
|
-
const result = validate(concept);
|
|
124
|
+
export async function validateWithProvider(concept, options) {
|
|
125
|
+
const result = validate(concept, options);
|
|
126
126
|
if (!result.valid || !result.system || !result.providerConfigured) {
|
|
127
127
|
return result;
|
|
128
128
|
}
|
|
@@ -157,3 +157,15 @@ export async function validateWithProvider(concept) {
|
|
|
157
157
|
}
|
|
158
158
|
return result;
|
|
159
159
|
}
|
|
160
|
+
/** Validates a list without stopping at the first invalid concept. */
|
|
161
|
+
export function validateMany(concepts, options) {
|
|
162
|
+
if (!Array.isArray(concepts))
|
|
163
|
+
throw new TypeError("concepts must be an array");
|
|
164
|
+
return concepts.map((concept) => validate(concept, options));
|
|
165
|
+
}
|
|
166
|
+
/** Provider-aware batch variant. Provider calls are independent and run concurrently. */
|
|
167
|
+
export async function validateManyWithProvider(concepts, options) {
|
|
168
|
+
if (!Array.isArray(concepts))
|
|
169
|
+
throw new TypeError("concepts must be an array");
|
|
170
|
+
return Promise.all(concepts.map((concept) => validateWithProvider(concept, options)));
|
|
171
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peerbits/medical-terminology",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Terminology system-URI registry and code format/checksum validation utilities — ships zero licensed terminology datasets (see docs/LICENSING.md)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "PeerbitsSolution",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsc -p tsconfig.json",
|
|
29
|
-
"
|
|
29
|
+
"prepack": "npm run build && npm run typecheck && npm test",
|
|
30
|
+
"prepublishOnly": "npm run lint && npm run prepack",
|
|
30
31
|
"lint": "eslint .",
|
|
31
32
|
"typecheck": "tsc --noEmit",
|
|
32
33
|
"test": "vitest run"
|
|
@@ -49,12 +50,12 @@
|
|
|
49
50
|
],
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"typescript": "^5.5.0",
|
|
52
|
-
"vitest": "^
|
|
53
|
+
"vitest": "^4.0.0",
|
|
53
54
|
"eslint": "^9.0.0",
|
|
54
55
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
55
56
|
"@typescript-eslint/parser": "^8.0.0"
|
|
56
57
|
},
|
|
57
58
|
"engines": {
|
|
58
|
-
"node": ">=
|
|
59
|
+
"node": ">=20"
|
|
59
60
|
}
|
|
60
61
|
}
|