ezmedicationinput 0.1.37 → 0.1.38
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 +4 -0
- package/dist/index.js +93 -3
- package/dist/types.d.ts +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -346,6 +346,10 @@ You can specify the number of times (total count) the medication is supposed to
|
|
|
346
346
|
combinations (e.g. `1x3` → breakfast/lunch/dinner). This also respects
|
|
347
347
|
`context.mealRelation` when provided and only applies to schedules with four
|
|
348
348
|
or fewer daily doses.
|
|
349
|
+
- `enableMealDashSyntax`: when `true`, enables shorthand meal-dose patterns
|
|
350
|
+
such as `1-0-1`, `1-0-1 pc`, `10-12-0 ac`, and `1-0-0-1 ac`. The parser
|
|
351
|
+
expands them into multiple dosage clauses aligned to breakfast/lunch/dinner
|
|
352
|
+
(plus bedtime for a 4th slot).
|
|
349
353
|
- `twoPerDayPair`: controls whether 2× AC/PC/C doses expand to breakfast+dinner (default) or breakfast+lunch.
|
|
350
354
|
- `assumeSingleDiscreteDose`: when `true`, missing discrete doses (such as
|
|
351
355
|
tablets or capsules) default to a single unit when the parser can infer a
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,96 @@ Object.defineProperty(exports, "DEFAULT_BODY_SITE_SNOMED_SOURCE", { enumerable:
|
|
|
58
58
|
Object.defineProperty(exports, "DEFAULT_ROUTE_SYNONYMS", { enumerable: true, get: function () { return maps_1.DEFAULT_ROUTE_SYNONYMS; } });
|
|
59
59
|
Object.defineProperty(exports, "DEFAULT_UNIT_BY_ROUTE", { enumerable: true, get: function () { return maps_1.DEFAULT_UNIT_BY_ROUTE; } });
|
|
60
60
|
Object.defineProperty(exports, "KNOWN_DOSAGE_FORMS_TO_DOSE", { enumerable: true, get: function () { return maps_1.KNOWN_DOSAGE_FORMS_TO_DOSE; } });
|
|
61
|
+
function parseMealDashValues(token) {
|
|
62
|
+
if (!/^[0-9]+(?:\.[0-9]+)?(?:-[0-9]+(?:\.[0-9]+)?){2,3}$/.test(token)) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const values = token.split("-").map((part) => Number(part));
|
|
66
|
+
if (values.length !== 3 && values.length !== 4) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
if (!values.every((value) => Number.isFinite(value) && value >= 0)) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
return values;
|
|
73
|
+
}
|
|
74
|
+
function mealDashEvents(length, relation) {
|
|
75
|
+
const base = relation === "ac"
|
|
76
|
+
? ["ACM", "ACD", "ACV"]
|
|
77
|
+
: relation === "pc"
|
|
78
|
+
? ["PCM", "PCD", "PCV"]
|
|
79
|
+
: ["CM", "CD", "CV"];
|
|
80
|
+
if (length === 4) {
|
|
81
|
+
return [...base, "HS"];
|
|
82
|
+
}
|
|
83
|
+
return base;
|
|
84
|
+
}
|
|
85
|
+
function formatMealDashAmount(value) {
|
|
86
|
+
if (Number.isInteger(value)) {
|
|
87
|
+
return String(value);
|
|
88
|
+
}
|
|
89
|
+
return String(value).replace(/\.0+$/, "").replace(/(\.\d*?)0+$/, "$1");
|
|
90
|
+
}
|
|
91
|
+
function expandMealDashSegment(segment) {
|
|
92
|
+
const tokens = (0, parser_1.tokenize)(segment.text);
|
|
93
|
+
if (tokens.length === 0) {
|
|
94
|
+
return [segment];
|
|
95
|
+
}
|
|
96
|
+
const firstToken = tokens[0];
|
|
97
|
+
const values = parseMealDashValues(firstToken.lower);
|
|
98
|
+
if (!values) {
|
|
99
|
+
return [segment];
|
|
100
|
+
}
|
|
101
|
+
let relation = "meal";
|
|
102
|
+
let relationIndex = -1;
|
|
103
|
+
for (let i = 1; i < tokens.length; i += 1) {
|
|
104
|
+
const lower = tokens[i].lower.replace(/[.,;:]/g, "");
|
|
105
|
+
if (lower === "ac") {
|
|
106
|
+
relation = "ac";
|
|
107
|
+
relationIndex = i;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
if (lower === "pc") {
|
|
111
|
+
relation = "pc";
|
|
112
|
+
relationIndex = i;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const suffixTokens = tokens
|
|
117
|
+
.filter((token, index) => index !== 0 && index !== relationIndex)
|
|
118
|
+
.map((token) => token.original);
|
|
119
|
+
const events = mealDashEvents(values.length, relation);
|
|
120
|
+
const expanded = values
|
|
121
|
+
.map((value, index) => ({ value, event: events[index] }))
|
|
122
|
+
.filter(({ value }) => value > 0)
|
|
123
|
+
.map(({ value, event }) => {
|
|
124
|
+
const text = [formatMealDashAmount(value), ...suffixTokens, event]
|
|
125
|
+
.filter((part) => part && part.trim().length > 0)
|
|
126
|
+
.join(" ")
|
|
127
|
+
.replace(/\s+/g, " ")
|
|
128
|
+
.trim();
|
|
129
|
+
return {
|
|
130
|
+
text,
|
|
131
|
+
start: segment.start,
|
|
132
|
+
end: segment.end
|
|
133
|
+
};
|
|
134
|
+
})
|
|
135
|
+
.filter((item) => item.text.length > 0);
|
|
136
|
+
if (expanded.length === 0) {
|
|
137
|
+
return [segment];
|
|
138
|
+
}
|
|
139
|
+
return expanded;
|
|
140
|
+
}
|
|
141
|
+
function expandMealDashSegments(segments, options) {
|
|
142
|
+
if (!(options === null || options === void 0 ? void 0 : options.enableMealDashSyntax)) {
|
|
143
|
+
return segments;
|
|
144
|
+
}
|
|
145
|
+
const expanded = [];
|
|
146
|
+
for (const segment of segments) {
|
|
147
|
+
expanded.push(...expandMealDashSegment(segment));
|
|
148
|
+
}
|
|
149
|
+
return expanded;
|
|
150
|
+
}
|
|
61
151
|
function toSegmentMeta(segments) {
|
|
62
152
|
return segments.map((segment, index) => ({
|
|
63
153
|
index,
|
|
@@ -66,7 +156,7 @@ function toSegmentMeta(segments) {
|
|
|
66
156
|
}));
|
|
67
157
|
}
|
|
68
158
|
function parseSig(input, options) {
|
|
69
|
-
const segments = (0, segment_1.splitSigSegments)(input);
|
|
159
|
+
const segments = expandMealDashSegments((0, segment_1.splitSigSegments)(input), options);
|
|
70
160
|
const carry = {};
|
|
71
161
|
const results = [];
|
|
72
162
|
for (const segment of segments) {
|
|
@@ -92,7 +182,7 @@ function parseSig(input, options) {
|
|
|
92
182
|
};
|
|
93
183
|
}
|
|
94
184
|
function lintSig(input, options) {
|
|
95
|
-
const segments = (0, segment_1.splitSigSegments)(input);
|
|
185
|
+
const segments = expandMealDashSegments((0, segment_1.splitSigSegments)(input), options);
|
|
96
186
|
const carry = {};
|
|
97
187
|
const results = [];
|
|
98
188
|
for (const segment of segments) {
|
|
@@ -132,7 +222,7 @@ function lintSig(input, options) {
|
|
|
132
222
|
}
|
|
133
223
|
function parseSigAsync(input, options) {
|
|
134
224
|
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
-
const segments = (0, segment_1.splitSigSegments)(input);
|
|
225
|
+
const segments = expandMealDashSegments((0, segment_1.splitSigSegments)(input), options);
|
|
136
226
|
const carry = {};
|
|
137
227
|
const results = [];
|
|
138
228
|
for (const segment of segments) {
|
package/dist/types.d.ts
CHANGED
|
@@ -457,6 +457,13 @@ export interface ParseOptions extends FormatOptions {
|
|
|
457
457
|
* `context.mealRelation` when provided.
|
|
458
458
|
*/
|
|
459
459
|
smartMealExpansion?: boolean;
|
|
460
|
+
/**
|
|
461
|
+
* Enables parsing meal dash shorthand like `1-0-1` / `1-0-0-1` into
|
|
462
|
+
* multiple dosage clauses aligned to breakfast/lunch/dinner/(bedtime).
|
|
463
|
+
* Optional trailing `ac` / `pc` maps meal anchors to before/after meal
|
|
464
|
+
* variants.
|
|
465
|
+
*/
|
|
466
|
+
enableMealDashSyntax?: boolean;
|
|
460
467
|
/**
|
|
461
468
|
* Controls which meal pair is assumed for twice-daily meal expansions.
|
|
462
469
|
* Defaults to "breakfast+dinner" to mirror common clinical practice.
|