ezmedicationinput 0.1.19 → 0.1.21

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/maps.js CHANGED
@@ -1349,6 +1349,17 @@ const DEFAULT_PRN_REASON_SOURCE = [
1349
1349
  text: "Constipation"
1350
1350
  }
1351
1351
  },
1352
+ {
1353
+ names: ["irritation", "irritated"],
1354
+ definition: {
1355
+ coding: {
1356
+ system: SNOMED_SYSTEM,
1357
+ code: "257553007",
1358
+ display: "Irritation"
1359
+ },
1360
+ text: "Irritation"
1361
+ }
1362
+ },
1352
1363
  {
1353
1364
  names: ["dyspnea", "shortness of breath", "sob", "breathlessness"],
1354
1365
  definition: {
package/dist/parser.js CHANGED
@@ -1069,13 +1069,10 @@ function reconcileMealTimingSpecificity(internal) {
1069
1069
  // Optionally replace generic meal tokens with concrete breakfast/lunch/dinner
1070
1070
  // EventTiming codes when the cadence makes the intent obvious.
1071
1071
  function expandMealTimings(internal, options) {
1072
- var _a;
1072
+ var _a, _b, _c;
1073
1073
  if (!(options === null || options === void 0 ? void 0 : options.smartMealExpansion)) {
1074
1074
  return;
1075
1075
  }
1076
- if (!internal.when.length) {
1077
- return;
1078
- }
1079
1076
  if (internal.when.some((code) => SPECIFIC_MEAL_TIMINGS.has(code))) {
1080
1077
  return;
1081
1078
  }
@@ -1083,6 +1080,13 @@ function expandMealTimings(internal, options) {
1083
1080
  if (!frequency || frequency < 1 || frequency > 4) {
1084
1081
  return;
1085
1082
  }
1083
+ const hasGeneralMealToken = (0, array_1.arrayIncludes)(internal.when, types_1.EventTiming["Before Meal"]) ||
1084
+ (0, array_1.arrayIncludes)(internal.when, types_1.EventTiming["After Meal"]) ||
1085
+ (0, array_1.arrayIncludes)(internal.when, types_1.EventTiming.Meal);
1086
+ const needsDefaultExpansion = internal.when.length === 0 && frequency >= 2;
1087
+ if (!hasGeneralMealToken && !needsDefaultExpansion) {
1088
+ return;
1089
+ }
1086
1090
  if (internal.period !== undefined &&
1087
1091
  internal.periodUnit !== undefined &&
1088
1092
  (internal.periodUnit !== types_1.FhirPeriodUnit.Day || internal.period !== 1)) {
@@ -1101,26 +1105,34 @@ function expandMealTimings(internal, options) {
1101
1105
  }
1102
1106
  const pairPreference = (_a = options.twoPerDayPair) !== null && _a !== void 0 ? _a : "breakfast+dinner";
1103
1107
  const replacements = [];
1104
- if ((0, array_1.arrayIncludes)(internal.when, types_1.EventTiming["Before Meal"])) {
1105
- const specifics = computeMealExpansions("before", frequency, pairPreference);
1108
+ const addReplacement = (general, base, removeGeneral) => {
1109
+ const specifics = computeMealExpansions(base, frequency, pairPreference);
1106
1110
  if (specifics) {
1107
- replacements.push({ general: types_1.EventTiming["Before Meal"], specifics });
1111
+ replacements.push({ general, specifics, removeGeneral });
1108
1112
  }
1113
+ };
1114
+ if ((0, array_1.arrayIncludes)(internal.when, types_1.EventTiming["Before Meal"])) {
1115
+ addReplacement(types_1.EventTiming["Before Meal"], "before", true);
1109
1116
  }
1110
1117
  if ((0, array_1.arrayIncludes)(internal.when, types_1.EventTiming["After Meal"])) {
1111
- const specifics = computeMealExpansions("after", frequency, pairPreference);
1112
- if (specifics) {
1113
- replacements.push({ general: types_1.EventTiming["After Meal"], specifics });
1114
- }
1118
+ addReplacement(types_1.EventTiming["After Meal"], "after", true);
1115
1119
  }
1116
1120
  if ((0, array_1.arrayIncludes)(internal.when, types_1.EventTiming.Meal)) {
1117
- const specifics = computeMealExpansions("with", frequency, pairPreference);
1118
- if (specifics) {
1119
- replacements.push({ general: types_1.EventTiming.Meal, specifics });
1120
- }
1121
+ addReplacement(types_1.EventTiming.Meal, "with", true);
1121
1122
  }
1122
- for (const { general, specifics } of replacements) {
1123
- removeWhen(internal.when, general);
1123
+ if (needsDefaultExpansion) {
1124
+ const relation = (_c = (_b = options === null || options === void 0 ? void 0 : options.context) === null || _b === void 0 ? void 0 : _b.mealRelation) !== null && _c !== void 0 ? _c : types_1.EventTiming.Meal;
1125
+ const base = relation === types_1.EventTiming["Before Meal"]
1126
+ ? "before"
1127
+ : relation === types_1.EventTiming["After Meal"]
1128
+ ? "after"
1129
+ : "with";
1130
+ addReplacement(relation, base, false);
1131
+ }
1132
+ for (const { general, specifics, removeGeneral } of replacements) {
1133
+ if (removeGeneral) {
1134
+ removeWhen(internal.when, general);
1135
+ }
1124
1136
  for (const specific of specifics) {
1125
1137
  addWhen(internal.when, specific);
1126
1138
  }
@@ -1413,7 +1425,7 @@ function applyCountLimit(internal, value) {
1413
1425
  return true;
1414
1426
  }
1415
1427
  function parseInternal(input, options) {
1416
- var _a, _b, _c, _d, _e, _f;
1428
+ var _a, _b, _c, _d, _e, _f, _g;
1417
1429
  const tokens = tokenize(input);
1418
1430
  const internal = {
1419
1431
  input,
@@ -1952,13 +1964,25 @@ function parseInternal(input, options) {
1952
1964
  }
1953
1965
  }
1954
1966
  }
1967
+ let canonicalPrefix;
1955
1968
  if (reasonTokens.length > 0) {
1956
- const suffixTokens = findTrailingPrnSiteSuffix(reasonObjects, internal, options);
1957
- if (suffixTokens === null || suffixTokens === void 0 ? void 0 : suffixTokens.length) {
1958
- for (const token of suffixTokens) {
1969
+ const suffixInfo = findTrailingPrnSiteSuffix(reasonObjects, internal, options);
1970
+ if ((_g = suffixInfo === null || suffixInfo === void 0 ? void 0 : suffixInfo.tokens) === null || _g === void 0 ? void 0 : _g.length) {
1971
+ for (const token of suffixInfo.tokens) {
1959
1972
  prnSiteSuffixIndices.add(token.index);
1960
1973
  }
1961
1974
  }
1975
+ if (suffixInfo && suffixInfo.startIndex > 0) {
1976
+ const prefixTokens = reasonObjects
1977
+ .slice(0, suffixInfo.startIndex)
1978
+ .map((token) => token.original)
1979
+ .join(" ")
1980
+ .replace(/\s+/g, " ")
1981
+ .trim();
1982
+ if (prefixTokens) {
1983
+ canonicalPrefix = prefixTokens.replace(/[{}]/g, " ").replace(/\s+/g, " ").trim();
1984
+ }
1985
+ }
1962
1986
  }
1963
1987
  if (reasonTokens.length > 0) {
1964
1988
  const joined = reasonTokens.join(" ").trim();
@@ -1974,8 +1998,9 @@ function parseInternal(input, options) {
1974
1998
  const text = sanitized || joined;
1975
1999
  internal.asNeededReason = text;
1976
2000
  const normalized = text.toLowerCase();
1977
- const canonical = sanitized
1978
- ? (0, maps_1.normalizePrnReasonKey)(sanitized)
2001
+ const canonicalSource = canonicalPrefix || sanitized || text;
2002
+ const canonical = canonicalSource
2003
+ ? (0, maps_1.normalizePrnReasonKey)(canonicalSource)
1979
2004
  : (0, maps_1.normalizePrnReasonKey)(text);
1980
2005
  internal.prnReasonLookupRequest = {
1981
2006
  originalText: joined,
@@ -2932,7 +2957,10 @@ function findTrailingPrnSiteSuffix(tokens, internal, options) {
2932
2957
  if (!definition) {
2933
2958
  return undefined;
2934
2959
  }
2935
- return siteHintTokens;
2960
+ return {
2961
+ tokens: siteHintTokens,
2962
+ startIndex: suffixStart
2963
+ };
2936
2964
  }
2937
2965
  function lookupPrnReasonDefinition(map, canonical) {
2938
2966
  if (!map) {
package/dist/types.d.ts CHANGED
@@ -285,6 +285,7 @@ export interface MedicationContext {
285
285
  containerValue?: number;
286
286
  containerUnit?: string;
287
287
  defaultUnit?: string;
288
+ mealRelation?: (typeof EventTiming)["Before Meal"] | (typeof EventTiming)["After Meal"] | (typeof EventTiming)["Meal"];
288
289
  }
289
290
  export interface FormatOptions {
290
291
  locale?: "en" | "th" | string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ezmedicationinput",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Parse concise medication sigs into FHIR R5 Dosage JSON",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",