ezmedicationinput 0.1.23 → 0.1.24
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.d.ts +2 -1
- package/dist/index.js +20 -0
- package/dist/parser.d.ts +5 -1
- package/dist/parser.js +63 -0
- package/dist/types.d.ts +16 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FhirDosage, FormatOptions, ParseOptions, ParseResult } from "./types";
|
|
1
|
+
import { FhirDosage, FormatOptions, LintResult, ParseOptions, ParseResult } from "./types";
|
|
2
2
|
export { parseInternal } from "./parser";
|
|
3
3
|
export { suggestSig } from "./suggest";
|
|
4
4
|
export * from "./types";
|
|
@@ -6,6 +6,7 @@ export { nextDueDoses } from "./schedule";
|
|
|
6
6
|
export { getRegisteredSigLocalizations, registerSigLocalization, resolveSigLocalization, resolveSigTranslation } from "./i18n";
|
|
7
7
|
export type { SigLocalization, SigLocalizationConfig, SigTranslation, SigTranslationConfig } from "./i18n";
|
|
8
8
|
export declare function parseSig(input: string, options?: ParseOptions): ParseResult;
|
|
9
|
+
export declare function lintSig(input: string, options?: ParseOptions): LintResult;
|
|
9
10
|
export declare function parseSigAsync(input: string, options?: ParseOptions): Promise<ParseResult>;
|
|
10
11
|
export declare function formatSig(dosage: FhirDosage, style?: "short" | "long", options?: FormatOptions): string;
|
|
11
12
|
export declare function fromFhirDosage(dosage: FhirDosage, options?: FormatOptions): ParseResult;
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.resolveSigTranslation = exports.resolveSigLocalization = exports.registerSigLocalization = exports.getRegisteredSigLocalizations = exports.nextDueDoses = exports.suggestSig = exports.parseInternal = void 0;
|
|
27
27
|
exports.parseSig = parseSig;
|
|
28
|
+
exports.lintSig = lintSig;
|
|
28
29
|
exports.parseSigAsync = parseSigAsync;
|
|
29
30
|
exports.formatSig = formatSig;
|
|
30
31
|
exports.fromFhirDosage = fromFhirDosage;
|
|
@@ -50,6 +51,25 @@ function parseSig(input, options) {
|
|
|
50
51
|
(0, parser_1.applySiteCoding)(internal, options);
|
|
51
52
|
return buildParseResult(internal, options);
|
|
52
53
|
}
|
|
54
|
+
function lintSig(input, options) {
|
|
55
|
+
const internal = (0, parser_1.parseInternal)(input, options);
|
|
56
|
+
(0, parser_1.applyPrnReasonCoding)(internal, options);
|
|
57
|
+
(0, parser_1.applySiteCoding)(internal, options);
|
|
58
|
+
const result = buildParseResult(internal, options);
|
|
59
|
+
const groups = (0, parser_1.findUnparsedTokenGroups)(internal);
|
|
60
|
+
const issues = groups.map((group) => {
|
|
61
|
+
const text = group.range
|
|
62
|
+
? internal.input.slice(group.range.start, group.range.end)
|
|
63
|
+
: group.tokens.map((token) => token.original).join(" ");
|
|
64
|
+
return {
|
|
65
|
+
message: "Unrecognized text",
|
|
66
|
+
text: text.trim() || text,
|
|
67
|
+
tokens: group.tokens.map((token) => token.original),
|
|
68
|
+
range: group.range
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
return { result, issues };
|
|
72
|
+
}
|
|
53
73
|
function parseSigAsync(input, options) {
|
|
54
74
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
75
|
const internal = (0, parser_1.parseInternal)(input, options);
|
package/dist/parser.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { ParsedSigInternal, Token } from "./internal-types";
|
|
2
|
-
import { ParseOptions } from "./types";
|
|
2
|
+
import { ParseOptions, TextRange } from "./types";
|
|
3
3
|
export declare function tokenize(input: string): Token[];
|
|
4
|
+
export declare function findUnparsedTokenGroups(internal: ParsedSigInternal): Array<{
|
|
5
|
+
tokens: Token[];
|
|
6
|
+
range?: TextRange;
|
|
7
|
+
}>;
|
|
4
8
|
export declare function parseInternal(input: string, options?: ParseOptions): ParsedSigInternal;
|
|
5
9
|
/**
|
|
6
10
|
* Resolves parsed site text against SNOMED dictionaries and synchronous
|
package/dist/parser.js
CHANGED
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.tokenize = tokenize;
|
|
13
|
+
exports.findUnparsedTokenGroups = findUnparsedTokenGroups;
|
|
13
14
|
exports.parseInternal = parseInternal;
|
|
14
15
|
exports.applyPrnReasonCoding = applyPrnReasonCoding;
|
|
15
16
|
exports.applyPrnReasonCodingAsync = applyPrnReasonCodingAsync;
|
|
@@ -885,6 +886,68 @@ function refineSiteRange(input, sanitized, tokenRange) {
|
|
|
885
886
|
}
|
|
886
887
|
return { start: startIndex, end: startIndex + lowerSanitized.length };
|
|
887
888
|
}
|
|
889
|
+
function findUnparsedTokenGroups(internal) {
|
|
890
|
+
const leftoverTokens = internal.tokens
|
|
891
|
+
.filter((token) => !internal.consumed.has(token.index))
|
|
892
|
+
.sort((a, b) => a.index - b.index);
|
|
893
|
+
if (leftoverTokens.length === 0) {
|
|
894
|
+
return [];
|
|
895
|
+
}
|
|
896
|
+
const groups = [];
|
|
897
|
+
let currentGroup = [];
|
|
898
|
+
let previousIndex;
|
|
899
|
+
let minimumStart = 0;
|
|
900
|
+
const locateRange = (tokensToLocate, initial) => {
|
|
901
|
+
const lowerInput = internal.input.toLowerCase();
|
|
902
|
+
let searchStart = minimumStart;
|
|
903
|
+
let rangeStart;
|
|
904
|
+
let rangeEnd;
|
|
905
|
+
for (const token of tokensToLocate) {
|
|
906
|
+
const segment = token.original.trim();
|
|
907
|
+
if (!segment) {
|
|
908
|
+
continue;
|
|
909
|
+
}
|
|
910
|
+
const lowerSegment = segment.toLowerCase();
|
|
911
|
+
const foundIndex = lowerInput.indexOf(lowerSegment, searchStart);
|
|
912
|
+
if (foundIndex === -1) {
|
|
913
|
+
return initial;
|
|
914
|
+
}
|
|
915
|
+
if (rangeStart === undefined) {
|
|
916
|
+
rangeStart = foundIndex;
|
|
917
|
+
}
|
|
918
|
+
const segmentEnd = foundIndex + lowerSegment.length;
|
|
919
|
+
rangeEnd = rangeEnd === undefined ? segmentEnd : Math.max(rangeEnd, segmentEnd);
|
|
920
|
+
searchStart = segmentEnd;
|
|
921
|
+
}
|
|
922
|
+
if (rangeStart === undefined || rangeEnd === undefined) {
|
|
923
|
+
return initial;
|
|
924
|
+
}
|
|
925
|
+
return { start: rangeStart, end: rangeEnd };
|
|
926
|
+
};
|
|
927
|
+
const flush = () => {
|
|
928
|
+
if (!currentGroup.length) {
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
const indices = currentGroup.map((token) => token.index);
|
|
932
|
+
const initialRange = computeTokenRange(internal.input, internal.tokens, indices);
|
|
933
|
+
const range = locateRange(currentGroup, initialRange);
|
|
934
|
+
groups.push({ tokens: currentGroup, range });
|
|
935
|
+
if (range) {
|
|
936
|
+
minimumStart = Math.max(minimumStart, range.end);
|
|
937
|
+
}
|
|
938
|
+
currentGroup = [];
|
|
939
|
+
previousIndex = undefined;
|
|
940
|
+
};
|
|
941
|
+
for (const token of leftoverTokens) {
|
|
942
|
+
if (previousIndex !== undefined && token.index !== previousIndex + 1) {
|
|
943
|
+
flush();
|
|
944
|
+
}
|
|
945
|
+
currentGroup.push(token);
|
|
946
|
+
previousIndex = token.index;
|
|
947
|
+
}
|
|
948
|
+
flush();
|
|
949
|
+
return groups;
|
|
950
|
+
}
|
|
888
951
|
function splitToken(token) {
|
|
889
952
|
if (/^[0-9]+(?:\.[0-9]+)?$/.test(token)) {
|
|
890
953
|
return [token];
|
package/dist/types.d.ts
CHANGED
|
@@ -527,6 +527,22 @@ export interface ParseResult {
|
|
|
527
527
|
}>;
|
|
528
528
|
};
|
|
529
529
|
}
|
|
530
|
+
export interface LintIssue {
|
|
531
|
+
/** Human-readable description of why the segment could not be parsed. */
|
|
532
|
+
message: string;
|
|
533
|
+
/** Original substring that triggered the issue. */
|
|
534
|
+
text: string;
|
|
535
|
+
/** Tokens contributing to the unparsed segment. */
|
|
536
|
+
tokens: string[];
|
|
537
|
+
/** Location of {@link text} relative to the caller's original input. */
|
|
538
|
+
range?: TextRange;
|
|
539
|
+
}
|
|
540
|
+
export interface LintResult {
|
|
541
|
+
/** Standard parse output including FHIR representation and metadata. */
|
|
542
|
+
result: ParseResult;
|
|
543
|
+
/** Segments of the input that could not be interpreted. */
|
|
544
|
+
issues: LintIssue[];
|
|
545
|
+
}
|
|
530
546
|
/**
|
|
531
547
|
* Maps EventTiming codes (or other institution-specific timing strings) to
|
|
532
548
|
* 24-hour clock representations such as "08:00".
|