ezmedicationinput 0.1.14 → 0.1.16
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/fhir.js +62 -7
- package/dist/format.js +26 -2
- package/dist/index.js +78 -4
- package/dist/internal-types.d.ts +12 -1
- package/dist/maps.d.ts +17 -1
- package/dist/maps.js +314 -1
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +647 -30
- package/dist/types.d.ts +65 -1
- package/package.json +1 -1
package/dist/fhir.js
CHANGED
|
@@ -9,7 +9,7 @@ const object_1 = require("./utils/object");
|
|
|
9
9
|
const array_1 = require("./utils/array");
|
|
10
10
|
const SNOMED_SYSTEM = "http://snomed.info/sct";
|
|
11
11
|
function toFhir(internal) {
|
|
12
|
-
var _a, _b, _c, _d, _e;
|
|
12
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
13
13
|
const dosage = {};
|
|
14
14
|
const repeat = {};
|
|
15
15
|
let hasRepeat = false;
|
|
@@ -115,10 +115,40 @@ function toFhir(internal) {
|
|
|
115
115
|
coding
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
+
if ((_f = internal.additionalInstructions) === null || _f === void 0 ? void 0 : _f.length) {
|
|
119
|
+
dosage.additionalInstruction = internal.additionalInstructions.map((instruction) => {
|
|
120
|
+
var _a, _b;
|
|
121
|
+
return ({
|
|
122
|
+
text: instruction.text,
|
|
123
|
+
coding: ((_a = instruction.coding) === null || _a === void 0 ? void 0 : _a.code)
|
|
124
|
+
? [
|
|
125
|
+
{
|
|
126
|
+
system: (_b = instruction.coding.system) !== null && _b !== void 0 ? _b : SNOMED_SYSTEM,
|
|
127
|
+
code: instruction.coding.code,
|
|
128
|
+
display: instruction.coding.display
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
: undefined
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
118
135
|
if (internal.asNeeded) {
|
|
119
136
|
dosage.asNeededBoolean = true;
|
|
120
|
-
if (internal.asNeededReason) {
|
|
121
|
-
|
|
137
|
+
if (internal.asNeededReason || ((_g = internal.asNeededReasonCoding) === null || _g === void 0 ? void 0 : _g.code)) {
|
|
138
|
+
const concept = {};
|
|
139
|
+
if (internal.asNeededReason) {
|
|
140
|
+
concept.text = internal.asNeededReason;
|
|
141
|
+
}
|
|
142
|
+
if ((_h = internal.asNeededReasonCoding) === null || _h === void 0 ? void 0 : _h.code) {
|
|
143
|
+
concept.coding = [
|
|
144
|
+
{
|
|
145
|
+
system: (_j = internal.asNeededReasonCoding.system) !== null && _j !== void 0 ? _j : SNOMED_SYSTEM,
|
|
146
|
+
code: internal.asNeededReasonCoding.code,
|
|
147
|
+
display: internal.asNeededReasonCoding.display
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
dosage.asNeededFor = [concept];
|
|
122
152
|
}
|
|
123
153
|
}
|
|
124
154
|
const longText = (0, format_1.formatInternal)(internal, "long");
|
|
@@ -128,7 +158,7 @@ function toFhir(internal) {
|
|
|
128
158
|
return dosage;
|
|
129
159
|
}
|
|
130
160
|
function internalFromFhir(dosage) {
|
|
131
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7;
|
|
161
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
|
|
132
162
|
const internal = {
|
|
133
163
|
input: (_a = dosage.text) !== null && _a !== void 0 ? _a : "",
|
|
134
164
|
tokens: [],
|
|
@@ -152,7 +182,9 @@ function internalFromFhir(dosage) {
|
|
|
152
182
|
asNeeded: dosage.asNeededBoolean,
|
|
153
183
|
asNeededReason: (_0 = (_z = dosage.asNeededFor) === null || _z === void 0 ? void 0 : _z[0]) === null || _0 === void 0 ? void 0 : _0.text,
|
|
154
184
|
siteTokenIndices: new Set(),
|
|
155
|
-
siteLookups: []
|
|
185
|
+
siteLookups: [],
|
|
186
|
+
prnReasonLookups: [],
|
|
187
|
+
additionalInstructions: []
|
|
156
188
|
};
|
|
157
189
|
const routeCoding = (_2 = (_1 = dosage.route) === null || _1 === void 0 ? void 0 : _1.coding) === null || _2 === void 0 ? void 0 : _2.find((code) => code.system === SNOMED_SYSTEM);
|
|
158
190
|
if (routeCoding === null || routeCoding === void 0 ? void 0 : routeCoding.code) {
|
|
@@ -171,13 +203,36 @@ function internalFromFhir(dosage) {
|
|
|
171
203
|
system: siteCoding.system
|
|
172
204
|
};
|
|
173
205
|
}
|
|
174
|
-
const
|
|
206
|
+
const reasonCoding = (_7 = (_6 = (_5 = dosage.asNeededFor) === null || _5 === void 0 ? void 0 : _5[0]) === null || _6 === void 0 ? void 0 : _6.coding) === null || _7 === void 0 ? void 0 : _7[0];
|
|
207
|
+
if (reasonCoding === null || reasonCoding === void 0 ? void 0 : reasonCoding.code) {
|
|
208
|
+
internal.asNeededReasonCoding = {
|
|
209
|
+
code: reasonCoding.code,
|
|
210
|
+
display: reasonCoding.display,
|
|
211
|
+
system: reasonCoding.system
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if ((_8 = dosage.additionalInstruction) === null || _8 === void 0 ? void 0 : _8.length) {
|
|
215
|
+
internal.additionalInstructions = dosage.additionalInstruction.map((concept) => {
|
|
216
|
+
var _a;
|
|
217
|
+
return ({
|
|
218
|
+
text: concept.text,
|
|
219
|
+
coding: ((_a = concept.coding) === null || _a === void 0 ? void 0 : _a[0])
|
|
220
|
+
? {
|
|
221
|
+
code: concept.coding[0].code,
|
|
222
|
+
display: concept.coding[0].display,
|
|
223
|
+
system: concept.coding[0].system
|
|
224
|
+
}
|
|
225
|
+
: undefined
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
const doseAndRate = (_9 = dosage.doseAndRate) === null || _9 === void 0 ? void 0 : _9[0];
|
|
175
230
|
if (doseAndRate === null || doseAndRate === void 0 ? void 0 : doseAndRate.doseRange) {
|
|
176
231
|
const { low, high } = doseAndRate.doseRange;
|
|
177
232
|
if ((low === null || low === void 0 ? void 0 : low.value) !== undefined && (high === null || high === void 0 ? void 0 : high.value) !== undefined) {
|
|
178
233
|
internal.doseRange = { low: low.value, high: high.value };
|
|
179
234
|
}
|
|
180
|
-
internal.unit = (
|
|
235
|
+
internal.unit = (_11 = (_10 = low === null || low === void 0 ? void 0 : low.unit) !== null && _10 !== void 0 ? _10 : high === null || high === void 0 ? void 0 : high.unit) !== null && _11 !== void 0 ? _11 : internal.unit;
|
|
181
236
|
}
|
|
182
237
|
else if (doseAndRate === null || doseAndRate === void 0 ? void 0 : doseAndRate.doseQuantity) {
|
|
183
238
|
const dose = doseAndRate.doseQuantity;
|
package/dist/format.js
CHANGED
|
@@ -603,9 +603,33 @@ function formatLong(internal) {
|
|
|
603
603
|
}
|
|
604
604
|
const body = segments.filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
|
|
605
605
|
if (!body) {
|
|
606
|
-
|
|
606
|
+
const instructionText = formatAdditionalInstructions(internal);
|
|
607
|
+
if (!instructionText) {
|
|
608
|
+
return `${grammar.verb}.`;
|
|
609
|
+
}
|
|
610
|
+
return `${grammar.verb}. ${instructionText}`.trim();
|
|
611
|
+
}
|
|
612
|
+
const instructionText = formatAdditionalInstructions(internal);
|
|
613
|
+
const baseSentence = `${grammar.verb} ${body}.`;
|
|
614
|
+
return instructionText ? `${baseSentence} ${instructionText}` : baseSentence;
|
|
615
|
+
}
|
|
616
|
+
function formatAdditionalInstructions(internal) {
|
|
617
|
+
var _a;
|
|
618
|
+
if (!((_a = internal.additionalInstructions) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
619
|
+
return undefined;
|
|
620
|
+
}
|
|
621
|
+
const phrases = internal.additionalInstructions
|
|
622
|
+
.map((instruction) => { var _a; return instruction.text || ((_a = instruction.coding) === null || _a === void 0 ? void 0 : _a.display); })
|
|
623
|
+
.filter((text) => Boolean(text))
|
|
624
|
+
.map((text) => text.trim())
|
|
625
|
+
.filter((text) => text.length > 0);
|
|
626
|
+
if (!phrases.length) {
|
|
627
|
+
return undefined;
|
|
607
628
|
}
|
|
608
|
-
return
|
|
629
|
+
return phrases
|
|
630
|
+
.map((phrase) => (/[.!?]$/.test(phrase) ? phrase : `${phrase}.`))
|
|
631
|
+
.join(" ")
|
|
632
|
+
.trim();
|
|
609
633
|
}
|
|
610
634
|
function stripTrailingZero(value) {
|
|
611
635
|
const text = value.toString();
|
package/dist/index.js
CHANGED
|
@@ -46,12 +46,14 @@ Object.defineProperty(exports, "resolveSigLocalization", { enumerable: true, get
|
|
|
46
46
|
Object.defineProperty(exports, "resolveSigTranslation", { enumerable: true, get: function () { return i18n_2.resolveSigTranslation; } });
|
|
47
47
|
function parseSig(input, options) {
|
|
48
48
|
const internal = (0, parser_1.parseInternal)(input, options);
|
|
49
|
+
(0, parser_1.applyPrnReasonCoding)(internal, options);
|
|
49
50
|
(0, parser_1.applySiteCoding)(internal, options);
|
|
50
51
|
return buildParseResult(internal, options);
|
|
51
52
|
}
|
|
52
53
|
function parseSigAsync(input, options) {
|
|
53
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54
55
|
const internal = (0, parser_1.parseInternal)(input, options);
|
|
56
|
+
yield (0, parser_1.applyPrnReasonCodingAsync)(internal, options);
|
|
55
57
|
yield (0, parser_1.applySiteCodingAsync)(internal, options);
|
|
56
58
|
return buildParseResult(internal, options);
|
|
57
59
|
});
|
|
@@ -62,7 +64,7 @@ function formatSig(dosage, style = "short", options) {
|
|
|
62
64
|
return (0, format_1.formatInternal)(internal, style, localization);
|
|
63
65
|
}
|
|
64
66
|
function fromFhirDosage(dosage, options) {
|
|
65
|
-
var _a, _b, _c;
|
|
67
|
+
var _a, _b, _c, _d, _e, _f;
|
|
66
68
|
const internal = (0, fhir_1.internalFromFhir)(dosage);
|
|
67
69
|
const localization = (0, i18n_1.resolveSigLocalization)(options === null || options === void 0 ? void 0 : options.locale, options === null || options === void 0 ? void 0 : options.i18n);
|
|
68
70
|
const shortText = (0, format_1.formatInternal)(internal, "short", localization);
|
|
@@ -89,13 +91,40 @@ function fromFhirDosage(dosage, options) {
|
|
|
89
91
|
}
|
|
90
92
|
: undefined
|
|
91
93
|
}
|
|
94
|
+
: undefined,
|
|
95
|
+
prnReason: internal.asNeededReason || ((_d = internal.asNeededReasonCoding) === null || _d === void 0 ? void 0 : _d.code)
|
|
96
|
+
? {
|
|
97
|
+
text: internal.asNeededReason,
|
|
98
|
+
coding: ((_e = internal.asNeededReasonCoding) === null || _e === void 0 ? void 0 : _e.code)
|
|
99
|
+
? {
|
|
100
|
+
code: internal.asNeededReasonCoding.code,
|
|
101
|
+
display: internal.asNeededReasonCoding.display,
|
|
102
|
+
system: internal.asNeededReasonCoding.system
|
|
103
|
+
}
|
|
104
|
+
: undefined
|
|
105
|
+
}
|
|
106
|
+
: undefined,
|
|
107
|
+
additionalInstructions: ((_f = internal.additionalInstructions) === null || _f === void 0 ? void 0 : _f.length)
|
|
108
|
+
? internal.additionalInstructions.map((instruction) => {
|
|
109
|
+
var _a;
|
|
110
|
+
return ({
|
|
111
|
+
text: instruction.text,
|
|
112
|
+
coding: ((_a = instruction.coding) === null || _a === void 0 ? void 0 : _a.code)
|
|
113
|
+
? {
|
|
114
|
+
code: instruction.coding.code,
|
|
115
|
+
display: instruction.coding.display,
|
|
116
|
+
system: instruction.coding.system
|
|
117
|
+
}
|
|
118
|
+
: undefined
|
|
119
|
+
});
|
|
120
|
+
})
|
|
92
121
|
: undefined
|
|
93
122
|
}
|
|
94
123
|
}
|
|
95
124
|
};
|
|
96
125
|
}
|
|
97
126
|
function buildParseResult(internal, options) {
|
|
98
|
-
var _a;
|
|
127
|
+
var _a, _b, _c;
|
|
99
128
|
const localization = (0, i18n_1.resolveSigLocalization)(options === null || options === void 0 ? void 0 : options.locale, options === null || options === void 0 ? void 0 : options.i18n);
|
|
100
129
|
const shortText = (0, format_1.formatInternal)(internal, "short", localization);
|
|
101
130
|
const longText = (0, format_1.formatInternal)(internal, "long", localization);
|
|
@@ -114,6 +143,28 @@ function buildParseResult(internal, options) {
|
|
|
114
143
|
system: internal.siteCoding.system
|
|
115
144
|
}
|
|
116
145
|
: undefined;
|
|
146
|
+
const prnReasonCoding = ((_b = internal.asNeededReasonCoding) === null || _b === void 0 ? void 0 : _b.code)
|
|
147
|
+
? {
|
|
148
|
+
code: internal.asNeededReasonCoding.code,
|
|
149
|
+
display: internal.asNeededReasonCoding.display,
|
|
150
|
+
system: internal.asNeededReasonCoding.system
|
|
151
|
+
}
|
|
152
|
+
: undefined;
|
|
153
|
+
const additionalInstructions = ((_c = internal.additionalInstructions) === null || _c === void 0 ? void 0 : _c.length)
|
|
154
|
+
? internal.additionalInstructions.map((instruction) => {
|
|
155
|
+
var _a;
|
|
156
|
+
return ({
|
|
157
|
+
text: instruction.text,
|
|
158
|
+
coding: ((_a = instruction.coding) === null || _a === void 0 ? void 0 : _a.code)
|
|
159
|
+
? {
|
|
160
|
+
code: instruction.coding.code,
|
|
161
|
+
display: instruction.coding.display,
|
|
162
|
+
system: instruction.coding.system
|
|
163
|
+
}
|
|
164
|
+
: undefined
|
|
165
|
+
});
|
|
166
|
+
})
|
|
167
|
+
: undefined;
|
|
117
168
|
const siteLookups = internal.siteLookups.length
|
|
118
169
|
? internal.siteLookups.map((entry) => ({
|
|
119
170
|
request: entry.request,
|
|
@@ -127,6 +178,21 @@ function buildParseResult(internal, options) {
|
|
|
127
178
|
}))
|
|
128
179
|
}))
|
|
129
180
|
: undefined;
|
|
181
|
+
const prnReasonLookups = internal.prnReasonLookups.length
|
|
182
|
+
? internal.prnReasonLookups.map((entry) => ({
|
|
183
|
+
request: entry.request,
|
|
184
|
+
suggestions: entry.suggestions.map((suggestion) => ({
|
|
185
|
+
coding: suggestion.coding
|
|
186
|
+
? {
|
|
187
|
+
code: suggestion.coding.code,
|
|
188
|
+
display: suggestion.coding.display,
|
|
189
|
+
system: suggestion.coding.system
|
|
190
|
+
}
|
|
191
|
+
: undefined,
|
|
192
|
+
text: suggestion.text
|
|
193
|
+
}))
|
|
194
|
+
}))
|
|
195
|
+
: undefined;
|
|
130
196
|
return {
|
|
131
197
|
fhir,
|
|
132
198
|
shortText,
|
|
@@ -145,9 +211,17 @@ function buildParseResult(internal, options) {
|
|
|
145
211
|
text: internal.siteText,
|
|
146
212
|
coding: siteCoding
|
|
147
213
|
}
|
|
148
|
-
: undefined
|
|
214
|
+
: undefined,
|
|
215
|
+
prnReason: internal.asNeededReason || prnReasonCoding
|
|
216
|
+
? {
|
|
217
|
+
text: internal.asNeededReason,
|
|
218
|
+
coding: prnReasonCoding
|
|
219
|
+
}
|
|
220
|
+
: undefined,
|
|
221
|
+
additionalInstructions
|
|
149
222
|
},
|
|
150
|
-
siteLookups
|
|
223
|
+
siteLookups,
|
|
224
|
+
prnReasonLookups
|
|
151
225
|
}
|
|
152
226
|
};
|
|
153
227
|
}
|
package/dist/internal-types.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { EventTiming, FhirCoding, FhirDayOfWeek, FhirPeriodUnit, RouteCode, SiteCodeLookupRequest, SiteCodeSuggestion } from "./types";
|
|
1
|
+
import { EventTiming, FhirCoding, FhirDayOfWeek, FhirPeriodUnit, PrnReasonLookupRequest, PrnReasonSuggestion, RouteCode, SiteCodeLookupRequest, SiteCodeSuggestion } from "./types";
|
|
2
2
|
export interface SiteLookupDetail {
|
|
3
3
|
request: SiteCodeLookupRequest;
|
|
4
4
|
suggestions: SiteCodeSuggestion[];
|
|
5
5
|
}
|
|
6
|
+
export interface PrnReasonLookupDetail {
|
|
7
|
+
request: PrnReasonLookupRequest;
|
|
8
|
+
suggestions: PrnReasonSuggestion[];
|
|
9
|
+
}
|
|
6
10
|
export interface Token {
|
|
7
11
|
original: string;
|
|
8
12
|
lower: string;
|
|
@@ -31,6 +35,7 @@ export interface ParsedSigInternal {
|
|
|
31
35
|
timingCode?: string;
|
|
32
36
|
asNeeded?: boolean;
|
|
33
37
|
asNeededReason?: string;
|
|
38
|
+
asNeededReasonCoding?: FhirCoding;
|
|
34
39
|
warnings: string[];
|
|
35
40
|
siteText?: string;
|
|
36
41
|
siteSource?: "abbreviation" | "text";
|
|
@@ -39,4 +44,10 @@ export interface ParsedSigInternal {
|
|
|
39
44
|
siteLookupRequest?: SiteCodeLookupRequest;
|
|
40
45
|
siteLookups: SiteLookupDetail[];
|
|
41
46
|
customSiteHints?: Set<string>;
|
|
47
|
+
prnReasonLookupRequest?: PrnReasonLookupRequest;
|
|
48
|
+
prnReasonLookups: PrnReasonLookupDetail[];
|
|
49
|
+
additionalInstructions: Array<{
|
|
50
|
+
text?: string;
|
|
51
|
+
coding?: FhirCoding;
|
|
52
|
+
}>;
|
|
42
53
|
}
|
package/dist/maps.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BodySiteDefinition, EventTiming, FhirDayOfWeek, FhirPeriodUnit, RouteCode, SNOMEDCTRouteCodes } from "./types";
|
|
1
|
+
import { AdditionalInstructionDefinition, BodySiteDefinition, EventTiming, FhirDayOfWeek, FhirPeriodUnit, PrnReasonDefinition, RouteCode, SNOMEDCTRouteCodes } from "./types";
|
|
2
2
|
/**
|
|
3
3
|
* SNOMED CT codings aligned with every known RouteCode. Keeping the structure
|
|
4
4
|
* data-driven ensures any additions to the enumeration are surfaced
|
|
@@ -58,3 +58,19 @@ export declare const KNOWN_DOSAGE_FORMS_TO_DOSE: Record<string, string>;
|
|
|
58
58
|
export declare const KNOWN_TMT_DOSAGE_FORM_TO_SNOMED_ROUTE: Record<string, SNOMEDCTRouteCodes>;
|
|
59
59
|
export declare const DEFAULT_UNIT_BY_NORMALIZED_FORM: Record<string, string>;
|
|
60
60
|
export declare const DEFAULT_UNIT_BY_ROUTE: Partial<Record<RouteCode, string>>;
|
|
61
|
+
export declare function normalizePrnReasonKey(value: string): string;
|
|
62
|
+
export declare function normalizeAdditionalInstructionKey(value: string): string;
|
|
63
|
+
export interface PrnReasonDictionaryEntry {
|
|
64
|
+
canonical: string;
|
|
65
|
+
definition: PrnReasonDefinition;
|
|
66
|
+
terms: string[];
|
|
67
|
+
}
|
|
68
|
+
export declare const DEFAULT_PRN_REASON_ENTRIES: PrnReasonDictionaryEntry[];
|
|
69
|
+
export declare const DEFAULT_PRN_REASON_DEFINITIONS: Record<string, PrnReasonDefinition>;
|
|
70
|
+
export interface AdditionalInstructionDictionaryEntry {
|
|
71
|
+
canonical: string;
|
|
72
|
+
definition: AdditionalInstructionDefinition;
|
|
73
|
+
terms: string[];
|
|
74
|
+
}
|
|
75
|
+
export declare const DEFAULT_ADDITIONAL_INSTRUCTION_ENTRIES: AdditionalInstructionDictionaryEntry[];
|
|
76
|
+
export declare const DEFAULT_ADDITIONAL_INSTRUCTION_DEFINITIONS: Record<string, AdditionalInstructionDefinition>;
|
package/dist/maps.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_UNIT_BY_ROUTE = exports.DEFAULT_UNIT_BY_NORMALIZED_FORM = exports.KNOWN_TMT_DOSAGE_FORM_TO_SNOMED_ROUTE = exports.KNOWN_DOSAGE_FORMS_TO_DOSE = exports.WORD_FREQUENCIES = exports.DAY_OF_WEEK_TOKENS = exports.DISCOURAGED_TOKENS = exports.MEAL_KEYWORDS = exports.EVENT_TIMING_TOKENS = exports.TIMING_ABBREVIATIONS = exports.DEFAULT_UNIT_SYNONYMS = exports.HOUSEHOLD_VOLUME_UNITS = exports.DEFAULT_BODY_SITE_SNOMED = exports.DEFAULT_ROUTE_SYNONYMS = exports.ROUTE_BY_SNOMED = exports.ROUTE_TEXT = exports.ROUTE_SNOMED = void 0;
|
|
3
|
+
exports.DEFAULT_ADDITIONAL_INSTRUCTION_DEFINITIONS = exports.DEFAULT_ADDITIONAL_INSTRUCTION_ENTRIES = exports.DEFAULT_PRN_REASON_DEFINITIONS = exports.DEFAULT_PRN_REASON_ENTRIES = exports.DEFAULT_UNIT_BY_ROUTE = exports.DEFAULT_UNIT_BY_NORMALIZED_FORM = exports.KNOWN_TMT_DOSAGE_FORM_TO_SNOMED_ROUTE = exports.KNOWN_DOSAGE_FORMS_TO_DOSE = exports.WORD_FREQUENCIES = exports.DAY_OF_WEEK_TOKENS = exports.DISCOURAGED_TOKENS = exports.MEAL_KEYWORDS = exports.EVENT_TIMING_TOKENS = exports.TIMING_ABBREVIATIONS = exports.DEFAULT_UNIT_SYNONYMS = exports.HOUSEHOLD_VOLUME_UNITS = exports.DEFAULT_BODY_SITE_SNOMED = exports.DEFAULT_ROUTE_SYNONYMS = exports.ROUTE_BY_SNOMED = exports.ROUTE_TEXT = exports.ROUTE_SNOMED = void 0;
|
|
4
4
|
exports.normalizeBodySiteKey = normalizeBodySiteKey;
|
|
5
|
+
exports.normalizePrnReasonKey = normalizePrnReasonKey;
|
|
6
|
+
exports.normalizeAdditionalInstructionKey = normalizeAdditionalInstructionKey;
|
|
5
7
|
const types_1 = require("./types");
|
|
6
8
|
const object_1 = require("./utils/object");
|
|
9
|
+
const SNOMED_SYSTEM = "http://snomed.info/sct";
|
|
7
10
|
const ROUTE_TEXT_OVERRIDES = {
|
|
8
11
|
[types_1.RouteCode["Oral route"]]: "by mouth",
|
|
9
12
|
[types_1.RouteCode["Sublingual route"]]: "sublingual",
|
|
@@ -1253,3 +1256,313 @@ exports.DEFAULT_UNIT_BY_ROUTE = (() => {
|
|
|
1253
1256
|
ensure(types_1.RouteCode["Transdermal route"], "patch");
|
|
1254
1257
|
return resolved;
|
|
1255
1258
|
})();
|
|
1259
|
+
function normalizePrnReasonKey(value) {
|
|
1260
|
+
return value
|
|
1261
|
+
.trim()
|
|
1262
|
+
.toLowerCase()
|
|
1263
|
+
.replace(/[^\p{L}\p{N}]+/gu, " ")
|
|
1264
|
+
.replace(/\s+/g, " ")
|
|
1265
|
+
.trim();
|
|
1266
|
+
}
|
|
1267
|
+
function normalizeAdditionalInstructionKey(value) {
|
|
1268
|
+
return value
|
|
1269
|
+
.trim()
|
|
1270
|
+
.toLowerCase()
|
|
1271
|
+
.replace(/[^\p{L}\p{N}]+/gu, " ")
|
|
1272
|
+
.replace(/\s+/g, " ")
|
|
1273
|
+
.trim();
|
|
1274
|
+
}
|
|
1275
|
+
const DEFAULT_PRN_REASON_SOURCE = [
|
|
1276
|
+
{
|
|
1277
|
+
names: ["pain", "ache", "aches", "pains"],
|
|
1278
|
+
definition: {
|
|
1279
|
+
coding: { system: SNOMED_SYSTEM, code: "22253000", display: "Pain" },
|
|
1280
|
+
text: "Pain"
|
|
1281
|
+
}
|
|
1282
|
+
},
|
|
1283
|
+
{
|
|
1284
|
+
names: ["nausea", "queasiness"],
|
|
1285
|
+
definition: {
|
|
1286
|
+
coding: { system: SNOMED_SYSTEM, code: "422587007", display: "Nausea" },
|
|
1287
|
+
text: "Nausea"
|
|
1288
|
+
}
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
names: ["itch", "itching", "itchy"],
|
|
1292
|
+
definition: {
|
|
1293
|
+
coding: {
|
|
1294
|
+
system: SNOMED_SYSTEM,
|
|
1295
|
+
code: "418363000",
|
|
1296
|
+
display: "Itching of skin"
|
|
1297
|
+
},
|
|
1298
|
+
text: "Itching"
|
|
1299
|
+
}
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
names: ["anxiety", "nervousness"],
|
|
1303
|
+
definition: {
|
|
1304
|
+
coding: { system: SNOMED_SYSTEM, code: "48694002", display: "Anxiety" },
|
|
1305
|
+
text: "Anxiety"
|
|
1306
|
+
}
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
names: ["sleep", "sleeping", "insomnia", "sleep issues"],
|
|
1310
|
+
definition: {
|
|
1311
|
+
coding: {
|
|
1312
|
+
system: SNOMED_SYSTEM,
|
|
1313
|
+
code: "193462001",
|
|
1314
|
+
display: "Insomnia"
|
|
1315
|
+
},
|
|
1316
|
+
text: "Sleep"
|
|
1317
|
+
}
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
names: ["cough", "coughing"],
|
|
1321
|
+
definition: {
|
|
1322
|
+
coding: { system: SNOMED_SYSTEM, code: "49727002", display: "Cough" },
|
|
1323
|
+
text: "Cough"
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
names: ["fever", "temperature", "pyrexia"],
|
|
1328
|
+
definition: {
|
|
1329
|
+
coding: { system: SNOMED_SYSTEM, code: "386661006", display: "Fever" },
|
|
1330
|
+
text: "Fever"
|
|
1331
|
+
}
|
|
1332
|
+
},
|
|
1333
|
+
{
|
|
1334
|
+
names: ["spasm", "spasms", "muscle spasm"],
|
|
1335
|
+
definition: {
|
|
1336
|
+
coding: { system: SNOMED_SYSTEM, code: "45352006", display: "Spasm" },
|
|
1337
|
+
text: "Spasm"
|
|
1338
|
+
}
|
|
1339
|
+
},
|
|
1340
|
+
{
|
|
1341
|
+
names: ["constipation"],
|
|
1342
|
+
definition: {
|
|
1343
|
+
coding: {
|
|
1344
|
+
system: SNOMED_SYSTEM,
|
|
1345
|
+
code: "14760008",
|
|
1346
|
+
display: "Constipation"
|
|
1347
|
+
},
|
|
1348
|
+
text: "Constipation"
|
|
1349
|
+
}
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
names: ["dyspnea", "shortness of breath", "sob", "breathlessness"],
|
|
1353
|
+
definition: {
|
|
1354
|
+
coding: {
|
|
1355
|
+
system: SNOMED_SYSTEM,
|
|
1356
|
+
code: "267036007",
|
|
1357
|
+
display: "Dyspnea"
|
|
1358
|
+
},
|
|
1359
|
+
text: "Shortness of breath"
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
];
|
|
1363
|
+
exports.DEFAULT_PRN_REASON_ENTRIES = DEFAULT_PRN_REASON_SOURCE.map((source) => {
|
|
1364
|
+
var _a, _b, _c;
|
|
1365
|
+
const canonicalTerm = (_c = (_a = source.definition.text) !== null && _a !== void 0 ? _a : (_b = source.definition.coding) === null || _b === void 0 ? void 0 : _b.display) !== null && _c !== void 0 ? _c : source.names[0];
|
|
1366
|
+
return {
|
|
1367
|
+
canonical: normalizePrnReasonKey(canonicalTerm !== null && canonicalTerm !== void 0 ? canonicalTerm : ""),
|
|
1368
|
+
definition: source.definition,
|
|
1369
|
+
terms: [...source.names]
|
|
1370
|
+
};
|
|
1371
|
+
});
|
|
1372
|
+
exports.DEFAULT_PRN_REASON_DEFINITIONS = (0, object_1.objectFromEntries)(DEFAULT_PRN_REASON_SOURCE.reduce((entries, source) => {
|
|
1373
|
+
for (const name of source.names) {
|
|
1374
|
+
const key = normalizePrnReasonKey(name);
|
|
1375
|
+
if (!key) {
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
entries.push([key, source.definition]);
|
|
1379
|
+
}
|
|
1380
|
+
if (source.definition.aliases) {
|
|
1381
|
+
for (const alias of source.definition.aliases) {
|
|
1382
|
+
const key = normalizePrnReasonKey(alias);
|
|
1383
|
+
if (!key) {
|
|
1384
|
+
continue;
|
|
1385
|
+
}
|
|
1386
|
+
entries.push([key, source.definition]);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
return entries;
|
|
1390
|
+
}, []));
|
|
1391
|
+
const DEFAULT_ADDITIONAL_INSTRUCTION_SOURCE = [
|
|
1392
|
+
{
|
|
1393
|
+
names: ["with food", "with meals", "with meal", "after food", "after meals"],
|
|
1394
|
+
definition: {
|
|
1395
|
+
coding: {
|
|
1396
|
+
system: SNOMED_SYSTEM,
|
|
1397
|
+
code: "311504000",
|
|
1398
|
+
display: "With or after food"
|
|
1399
|
+
},
|
|
1400
|
+
text: "Take with or after food"
|
|
1401
|
+
}
|
|
1402
|
+
},
|
|
1403
|
+
{
|
|
1404
|
+
names: ["before food", "before meals", "before meal", "1 hour before food"],
|
|
1405
|
+
definition: {
|
|
1406
|
+
coding: {
|
|
1407
|
+
system: SNOMED_SYSTEM,
|
|
1408
|
+
code: "311501008",
|
|
1409
|
+
display: "Half to one hour before food"
|
|
1410
|
+
},
|
|
1411
|
+
text: "Take before food"
|
|
1412
|
+
}
|
|
1413
|
+
},
|
|
1414
|
+
{
|
|
1415
|
+
names: ["empty stomach", "on empty stomach"],
|
|
1416
|
+
definition: {
|
|
1417
|
+
coding: {
|
|
1418
|
+
system: SNOMED_SYSTEM,
|
|
1419
|
+
code: "717154004",
|
|
1420
|
+
display: "Take on an empty stomach (qualifier value)"
|
|
1421
|
+
},
|
|
1422
|
+
text: "Take on an empty stomach"
|
|
1423
|
+
}
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
names: ["with water", "with plenty of water", "drink water", "with lots of water"],
|
|
1427
|
+
definition: {
|
|
1428
|
+
coding: {
|
|
1429
|
+
system: SNOMED_SYSTEM,
|
|
1430
|
+
code: "419303009",
|
|
1431
|
+
display: "With plenty of water"
|
|
1432
|
+
},
|
|
1433
|
+
text: "Take with plenty of water"
|
|
1434
|
+
}
|
|
1435
|
+
},
|
|
1436
|
+
{
|
|
1437
|
+
names: ["dissolve in water", "mix with water", "mix in water"],
|
|
1438
|
+
definition: {
|
|
1439
|
+
coding: {
|
|
1440
|
+
system: SNOMED_SYSTEM,
|
|
1441
|
+
code: "417995008",
|
|
1442
|
+
display: "Dissolve or mix with water before taking"
|
|
1443
|
+
},
|
|
1444
|
+
text: "Dissolve or mix with water before taking"
|
|
1445
|
+
}
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
names: ["avoid alcohol", "no alcohol", "no alc", "avoid alcoholic drink"],
|
|
1449
|
+
definition: {
|
|
1450
|
+
coding: {
|
|
1451
|
+
system: SNOMED_SYSTEM,
|
|
1452
|
+
code: "419822006",
|
|
1453
|
+
display: "Warning. Avoid alcoholic drink (qualifier value)"
|
|
1454
|
+
},
|
|
1455
|
+
text: "Avoid alcoholic drinks"
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
names: ["may cause drowsiness", "do not drive", "avoid driving", "no driving", "no drive"],
|
|
1460
|
+
definition: {
|
|
1461
|
+
coding: {
|
|
1462
|
+
system: SNOMED_SYSTEM,
|
|
1463
|
+
code: "418954008",
|
|
1464
|
+
display: "Warning. May cause drowsiness. If affected do not drive or operate machinery (qualifier value)"
|
|
1465
|
+
},
|
|
1466
|
+
text: "May cause drowsiness; do not drive if affected"
|
|
1467
|
+
}
|
|
1468
|
+
},
|
|
1469
|
+
{
|
|
1470
|
+
names: [
|
|
1471
|
+
"drowsiness avoid alcohol",
|
|
1472
|
+
"may cause drowsiness avoid alcohol",
|
|
1473
|
+
"do not drive avoid alcohol",
|
|
1474
|
+
"drowsy avoid alc",
|
|
1475
|
+
"drowsy avoid drive",
|
|
1476
|
+
"drowsy avoid driving",
|
|
1477
|
+
"drowsy no drive",
|
|
1478
|
+
"drowsy no driving",
|
|
1479
|
+
"drowsy no alc"
|
|
1480
|
+
],
|
|
1481
|
+
definition: {
|
|
1482
|
+
coding: {
|
|
1483
|
+
system: SNOMED_SYSTEM,
|
|
1484
|
+
code: "418914006",
|
|
1485
|
+
display: "Warning. May cause drowsiness. If affected do not drive or operate machinery. Avoid alcoholic drink (qualifier value)"
|
|
1486
|
+
},
|
|
1487
|
+
text: "May cause drowsiness; avoid driving or alcohol"
|
|
1488
|
+
}
|
|
1489
|
+
},
|
|
1490
|
+
{
|
|
1491
|
+
names: [
|
|
1492
|
+
"drowsiness next day",
|
|
1493
|
+
"drowsiness next day avoid alcohol",
|
|
1494
|
+
"may cause drowsiness next day",
|
|
1495
|
+
"may next day drowsy",
|
|
1496
|
+
"may drowsy next day"
|
|
1497
|
+
],
|
|
1498
|
+
definition: {
|
|
1499
|
+
coding: {
|
|
1500
|
+
system: SNOMED_SYSTEM,
|
|
1501
|
+
code: "418071006",
|
|
1502
|
+
display: "Warning. Causes drowsiness which may continue the next day. If affected do not drive or operate machinery. Avoid alcoholic drink (qualifier value)"
|
|
1503
|
+
},
|
|
1504
|
+
text: "May cause next-day drowsiness; avoid driving or alcohol"
|
|
1505
|
+
}
|
|
1506
|
+
},
|
|
1507
|
+
{
|
|
1508
|
+
names: ["avoid sun", "avoid sunlight", "avoid sun lamps"],
|
|
1509
|
+
definition: {
|
|
1510
|
+
coding: {
|
|
1511
|
+
system: SNOMED_SYSTEM,
|
|
1512
|
+
code: "418521000",
|
|
1513
|
+
display: "Avoid exposure of skin to direct sunlight or sun lamps (qualifier value)"
|
|
1514
|
+
},
|
|
1515
|
+
text: "Avoid sunlight or sun lamps"
|
|
1516
|
+
}
|
|
1517
|
+
},
|
|
1518
|
+
{
|
|
1519
|
+
names: ["swallow whole", "do not chew", "do not crush", "do not crush or chew", "no chewing"],
|
|
1520
|
+
definition: {
|
|
1521
|
+
coding: {
|
|
1522
|
+
system: SNOMED_SYSTEM,
|
|
1523
|
+
code: "418693002",
|
|
1524
|
+
display: "Swallowed whole, not chewed (qualifier value)"
|
|
1525
|
+
},
|
|
1526
|
+
text: "Swallow whole; do not crush or chew"
|
|
1527
|
+
}
|
|
1528
|
+
},
|
|
1529
|
+
{
|
|
1530
|
+
names: ["chew", "chewed", "sucked or chewed", "please chew", "must chew"],
|
|
1531
|
+
definition: {
|
|
1532
|
+
coding: {
|
|
1533
|
+
system: SNOMED_SYSTEM,
|
|
1534
|
+
code: "418991002",
|
|
1535
|
+
display: "Sucked or chewed (qualifier value)"
|
|
1536
|
+
},
|
|
1537
|
+
text: "Suck or chew before swallowing"
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
];
|
|
1541
|
+
exports.DEFAULT_ADDITIONAL_INSTRUCTION_ENTRIES = DEFAULT_ADDITIONAL_INSTRUCTION_SOURCE.map((source) => {
|
|
1542
|
+
var _a, _b, _c;
|
|
1543
|
+
const canonicalTerm = (_c = (_a = source.definition.text) !== null && _a !== void 0 ? _a : (_b = source.definition.coding) === null || _b === void 0 ? void 0 : _b.display) !== null && _c !== void 0 ? _c : source.names[0];
|
|
1544
|
+
return {
|
|
1545
|
+
canonical: normalizeAdditionalInstructionKey(canonicalTerm !== null && canonicalTerm !== void 0 ? canonicalTerm : ""),
|
|
1546
|
+
definition: source.definition,
|
|
1547
|
+
terms: [...source.names]
|
|
1548
|
+
};
|
|
1549
|
+
});
|
|
1550
|
+
exports.DEFAULT_ADDITIONAL_INSTRUCTION_DEFINITIONS = (0, object_1.objectFromEntries)(DEFAULT_ADDITIONAL_INSTRUCTION_SOURCE.reduce((entries, source) => {
|
|
1551
|
+
for (const name of source.names) {
|
|
1552
|
+
const key = normalizeAdditionalInstructionKey(name);
|
|
1553
|
+
if (!key) {
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
entries.push([key, source.definition]);
|
|
1557
|
+
}
|
|
1558
|
+
if (source.definition.aliases) {
|
|
1559
|
+
for (const alias of source.definition.aliases) {
|
|
1560
|
+
const key = normalizeAdditionalInstructionKey(alias);
|
|
1561
|
+
if (!key) {
|
|
1562
|
+
continue;
|
|
1563
|
+
}
|
|
1564
|
+
entries.push([key, source.definition]);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
return entries;
|
|
1568
|
+
}, []));
|
package/dist/parser.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export declare function parseInternal(input: string, options?: ParseOptions): Pa
|
|
|
6
6
|
* Resolves parsed site text against SNOMED dictionaries and synchronous
|
|
7
7
|
* callbacks, applying the best match to the in-progress parse result.
|
|
8
8
|
*/
|
|
9
|
+
export declare function applyPrnReasonCoding(internal: ParsedSigInternal, options?: ParseOptions): void;
|
|
10
|
+
export declare function applyPrnReasonCodingAsync(internal: ParsedSigInternal, options?: ParseOptions): Promise<void>;
|
|
9
11
|
export declare function applySiteCoding(internal: ParsedSigInternal, options?: ParseOptions): void;
|
|
10
12
|
/**
|
|
11
13
|
* Asynchronous counterpart to {@link applySiteCoding} that awaits resolver and
|