ezmedicationinput 0.1.15 → 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 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
- dosage.asNeededFor = [{ text: internal.asNeededReason }];
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 doseAndRate = (_5 = dosage.doseAndRate) === null || _5 === void 0 ? void 0 : _5[0];
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 = (_7 = (_6 = low === null || low === void 0 ? void 0 : low.unit) !== null && _6 !== void 0 ? _6 : high === null || high === void 0 ? void 0 : high.unit) !== null && _7 !== void 0 ? _7 : 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
- return `${grammar.verb}.`;
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 `${grammar.verb} ${body}.`;
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
  }
@@ -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