@pharmatools/pubcrawl 2.6.4 → 2.7.0
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/lib/label-mapping.d.ts +5 -3
- package/dist/lib/label-mapping.d.ts.map +1 -1
- package/dist/lib/label-mapping.js +5 -3
- package/dist/lib/label-mapping.js.map +1 -1
- package/dist/lib/paging.d.ts +40 -0
- package/dist/lib/paging.d.ts.map +1 -0
- package/dist/lib/paging.js +50 -0
- package/dist/lib/paging.js.map +1 -0
- package/dist/tools/compare-labels.d.ts +2 -0
- package/dist/tools/compare-labels.d.ts.map +1 -1
- package/dist/tools/compare-labels.js +28 -8
- package/dist/tools/compare-labels.js.map +1 -1
- package/dist/tools/smpc.d.ts +4 -1
- package/dist/tools/smpc.d.ts.map +1 -1
- package/dist/tools/smpc.js +31 -7
- package/dist/tools/smpc.js.map +1 -1
- package/dist/tools/uspi.d.ts +4 -1
- package/dist/tools/uspi.d.ts.map +1 -1
- package/dist/tools/uspi.js +31 -7
- package/dist/tools/uspi.js.map +1 -1
- package/dist/types.d.ts +10 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
|
@@ -6,9 +6,11 @@ export interface SectionMapping {
|
|
|
6
6
|
export declare const SECTION_MAP: SectionMapping[];
|
|
7
7
|
export declare function filterSectionMap(requestedTopics?: string[]): SectionMapping[];
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Mark sections that arrive already cut (content ends with " …"), e.g. from an
|
|
10
|
+
* engine older than @pharmatools/drug-data 0.3.0, which capped every section at
|
|
11
|
+
* 1,400 characters. Current tools fetch full sections and page them with
|
|
12
|
+
* lib/paging.ts; this stays as a guard so a pre-cut section is never presented
|
|
13
|
+
* as complete.
|
|
12
14
|
*/
|
|
13
15
|
export declare function markTruncated<T extends {
|
|
14
16
|
content: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label-mapping.d.ts","sourceRoot":"","sources":["../../src/lib/label-mapping.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,WAAW,EAAE,cAAc,EAUvC,CAAC;AA4BF,wBAAgB,gBAAgB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAG7E;AAED
|
|
1
|
+
{"version":3,"file":"label-mapping.d.ts","sourceRoot":"","sources":["../../src/lib/label-mapping.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,WAAW,EAAE,cAAc,EAUvC,CAAC;AA4BF,wBAAgB,gBAAgB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAG7E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,CAE3G"}
|
|
@@ -44,9 +44,11 @@ export function filterSectionMap(requestedTopics) {
|
|
|
44
44
|
return SECTION_MAP.filter((mapping) => requestedTopics.some((req) => topicMatches(mapping, req)));
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
47
|
+
* Mark sections that arrive already cut (content ends with " …"), e.g. from an
|
|
48
|
+
* engine older than @pharmatools/drug-data 0.3.0, which capped every section at
|
|
49
|
+
* 1,400 characters. Current tools fetch full sections and page them with
|
|
50
|
+
* lib/paging.ts; this stays as a guard so a pre-cut section is never presented
|
|
51
|
+
* as complete.
|
|
50
52
|
*/
|
|
51
53
|
export function markTruncated(sections) {
|
|
52
54
|
return sections.map((s) => (/\u2026\s*$/.test(s.content) ? { ...s, truncated: true } : s));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label-mapping.js","sourceRoot":"","sources":["../../src/lib/label-mapping.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IAC7D,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IACxD,EAAE,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IACnE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IAC1D,EAAE,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IACnE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IAC3D,EAAE,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IACnE,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;IAC5D,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;CACxE,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,CAAS,EAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAE9E;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,OAAuB,EAAE,OAAe;IAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,IAAI,GAAG,KAAK,OAAO,CAAC,QAAQ,IAAI,GAAG,KAAK,OAAO,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,mFAAmF;IACnF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,gBAAgB,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACvG,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,eAA0B;IACzD,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IACzE,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACpG,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"label-mapping.js","sourceRoot":"","sources":["../../src/lib/label-mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paging for long label sections.
|
|
3
|
+
*
|
|
4
|
+
* The shared engine (@pharmatools/drug-data >= 0.3.0) can return full
|
|
5
|
+
* verbatim sections. Some are long (an SmPC 4.2 or a USPI Dosage and
|
|
6
|
+
* Administration section can run to tens of thousands of characters), so
|
|
7
|
+
* PubCrawl returns them a page at a time. A cut page is flagged `truncated`,
|
|
8
|
+
* and `next_offset` says where the next page starts in the full section text.
|
|
9
|
+
*/
|
|
10
|
+
/** Default page size for get_smpc / get_uspi. */
|
|
11
|
+
export declare const DEFAULT_SECTION_CHARS = 6000;
|
|
12
|
+
/** Default page size per side for compare_labels (two labels per topic). */
|
|
13
|
+
export declare const COMPARE_SECTION_CHARS = 4000;
|
|
14
|
+
/** Smallest and largest page a caller may ask for. */
|
|
15
|
+
export declare const MIN_SECTION_CHARS = 500;
|
|
16
|
+
export declare const MAX_SECTION_CHARS = 50000;
|
|
17
|
+
export interface PageFields {
|
|
18
|
+
/** True when more of this section follows; content ends with " …". */
|
|
19
|
+
truncated?: boolean;
|
|
20
|
+
/** Length of the full section text, present when paging applies. */
|
|
21
|
+
total_chars?: number;
|
|
22
|
+
/** Where this page starts in the full section (present when > 0). */
|
|
23
|
+
offset?: number;
|
|
24
|
+
/** Pass this as `offset` to get the next page (present when truncated). */
|
|
25
|
+
next_offset?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Return one page of a section. Pages end on a sentence or line boundary
|
|
29
|
+
* when one falls in the last 40% of the page, otherwise at the page size.
|
|
30
|
+
* A section that already carries `truncated` (cut upstream) keeps the flag.
|
|
31
|
+
*/
|
|
32
|
+
export declare function pageSection<T extends {
|
|
33
|
+
content: string;
|
|
34
|
+
truncated?: boolean;
|
|
35
|
+
}>(section: T, offset?: number, maxChars?: number): T & PageFields;
|
|
36
|
+
export declare function pageSections<T extends {
|
|
37
|
+
content: string;
|
|
38
|
+
truncated?: boolean;
|
|
39
|
+
}>(sections: T[], offset?: number, maxChars?: number): (T & PageFields)[];
|
|
40
|
+
//# sourceMappingURL=paging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paging.d.ts","sourceRoot":"","sources":["../../src/lib/paging.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,iDAAiD;AACjD,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5E,OAAO,EAAE,CAAC,EACV,MAAM,SAAI,EACV,QAAQ,SAAwB,GAC/B,CAAC,GAAG,UAAU,CA2BhB;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,EAC7E,QAAQ,EAAE,CAAC,EAAE,EACb,MAAM,SAAI,EACV,QAAQ,SAAwB,GAC/B,CAAC,CAAC,GAAG,UAAU,CAAC,EAAE,CAEpB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paging for long label sections.
|
|
3
|
+
*
|
|
4
|
+
* The shared engine (@pharmatools/drug-data >= 0.3.0) can return full
|
|
5
|
+
* verbatim sections. Some are long (an SmPC 4.2 or a USPI Dosage and
|
|
6
|
+
* Administration section can run to tens of thousands of characters), so
|
|
7
|
+
* PubCrawl returns them a page at a time. A cut page is flagged `truncated`,
|
|
8
|
+
* and `next_offset` says where the next page starts in the full section text.
|
|
9
|
+
*/
|
|
10
|
+
/** Default page size for get_smpc / get_uspi. */
|
|
11
|
+
export const DEFAULT_SECTION_CHARS = 6000;
|
|
12
|
+
/** Default page size per side for compare_labels (two labels per topic). */
|
|
13
|
+
export const COMPARE_SECTION_CHARS = 4000;
|
|
14
|
+
/** Smallest and largest page a caller may ask for. */
|
|
15
|
+
export const MIN_SECTION_CHARS = 500;
|
|
16
|
+
export const MAX_SECTION_CHARS = 50000;
|
|
17
|
+
/**
|
|
18
|
+
* Return one page of a section. Pages end on a sentence or line boundary
|
|
19
|
+
* when one falls in the last 40% of the page, otherwise at the page size.
|
|
20
|
+
* A section that already carries `truncated` (cut upstream) keeps the flag.
|
|
21
|
+
*/
|
|
22
|
+
export function pageSection(section, offset = 0, maxChars = DEFAULT_SECTION_CHARS) {
|
|
23
|
+
const full = section.content;
|
|
24
|
+
const total = full.length;
|
|
25
|
+
const start = Math.max(0, Math.floor(offset));
|
|
26
|
+
if (start >= total) {
|
|
27
|
+
return start === 0 ? { ...section } : { ...section, content: "", truncated: false, total_chars: total, offset: start };
|
|
28
|
+
}
|
|
29
|
+
const rest = full.slice(start);
|
|
30
|
+
if (rest.length <= maxChars) {
|
|
31
|
+
if (start === 0)
|
|
32
|
+
return { ...section };
|
|
33
|
+
return { ...section, content: rest.trimStart(), total_chars: total, offset: start };
|
|
34
|
+
}
|
|
35
|
+
const window = rest.slice(0, maxChars);
|
|
36
|
+
const lastStop = Math.max(window.lastIndexOf(". "), window.lastIndexOf("\n"));
|
|
37
|
+
const cut = lastStop > maxChars * 0.6 ? lastStop + 1 : maxChars;
|
|
38
|
+
return {
|
|
39
|
+
...section,
|
|
40
|
+
content: rest.slice(0, cut).trim() + " …",
|
|
41
|
+
truncated: true,
|
|
42
|
+
total_chars: total,
|
|
43
|
+
...(start > 0 ? { offset: start } : {}),
|
|
44
|
+
next_offset: start + cut,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function pageSections(sections, offset = 0, maxChars = DEFAULT_SECTION_CHARS) {
|
|
48
|
+
return sections.map((s) => pageSection(s, offset, maxChars));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=paging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paging.js","sourceRoot":"","sources":["../../src/lib/paging.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,iDAAiD;AACjD,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,sDAAsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAavC;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,OAAU,EACV,MAAM,GAAG,CAAC,EACV,QAAQ,GAAG,qBAAqB;IAEhC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAE9C,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACzH,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;QACvC,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACtF,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,QAAQ,GAAG,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEhE,OAAO;QACL,GAAG,OAAO;QACV,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI;QACzC,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,KAAK;QAClB,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,WAAW,EAAE,KAAK,GAAG,GAAG;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,QAAa,EACb,MAAM,GAAG,CAAC,EACV,QAAQ,GAAG,qBAAqB;IAEhC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -26,6 +26,8 @@ export interface CompareNames {
|
|
|
26
26
|
us?: string;
|
|
27
27
|
/** Name used for the UK lookup; defaults to `drug`. */
|
|
28
28
|
uk?: string;
|
|
29
|
+
/** Page size per side per section; defaults to COMPARE_SECTION_CHARS. */
|
|
30
|
+
maxChars?: number;
|
|
29
31
|
}
|
|
30
32
|
export declare function buildCompareResult(drug: string, sections?: string[], fetchers?: LabelFetchers, names?: CompareNames): Promise<CompareLabelsResult | {
|
|
31
33
|
error: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-labels.d.ts","sourceRoot":"","sources":["../../src/tools/compare-labels.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"compare-labels.d.ts","sourceRoot":"","sources":["../../src/tools/compare-labels.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,OAAO,EACL,mBAAmB,EAEnB,YAAY,EAEb,MAAM,aAAa,CAAC;AA6BrB,yEAAyE;AACzE,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,YAAY,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACxG,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,YAAY,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC,CAAC;CAChG;AAiCD;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,QAAQ,GAAE,aAA+B,EACzC,KAAK,GAAE,YAAiB,GACvB,OAAO,CAAC,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAwElD;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2BjE"}
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { getUsLabel, getUkSmpc } from "@pharmatools/drug-data";
|
|
3
3
|
import { cache, TTL } from "../lib/cache.js";
|
|
4
4
|
import { filterSectionMap, markTruncated } from "../lib/label-mapping.js";
|
|
5
|
+
import { pageSection, COMPARE_SECTION_CHARS, MIN_SECTION_CHARS, MAX_SECTION_CHARS } from "../lib/paging.js";
|
|
5
6
|
const schema = {
|
|
6
7
|
drug: z.string().describe("Drug name to compare across US and UK labelling"),
|
|
7
8
|
us_drug: z
|
|
@@ -16,13 +17,30 @@ const schema = {
|
|
|
16
17
|
.array(z.string())
|
|
17
18
|
.optional()
|
|
18
19
|
.describe("Specific topics to compare (e.g., ['indications', 'adverse reactions']). Compares all mapped sections if omitted."),
|
|
20
|
+
max_chars: z
|
|
21
|
+
.number()
|
|
22
|
+
.int()
|
|
23
|
+
.min(MIN_SECTION_CHARS)
|
|
24
|
+
.max(MAX_SECTION_CHARS)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe(`Maximum characters per side per section (default ${COMPARE_SECTION_CHARS}). Longer sections are cut and flagged truncated with total_chars and next_offset; read on with get_uspi / get_smpc.`),
|
|
27
|
+
};
|
|
28
|
+
// Full sections from the engine; PubCrawl pages them itself.
|
|
29
|
+
const defaultFetchers = {
|
|
30
|
+
getUsLabel: (drug, codes) => getUsLabel(drug, codes, { maxChars: Infinity }),
|
|
31
|
+
getUkSmpc: (drug, codes) => getUkSmpc(drug, codes, { maxChars: Infinity }),
|
|
19
32
|
};
|
|
20
|
-
const defaultFetchers = { getUsLabel, getUkSmpc };
|
|
21
33
|
const US_UNAVAILABLE = "US label not retrieved: no openFDA/DailyMed product matched this name, or the source was unreachable. " +
|
|
22
34
|
"If the name is a brand, try resolve_drug_name and retry with the generic.";
|
|
23
35
|
const UK_UNAVAILABLE = "UK SmPC not retrieved: no eMC product matched this name (the drug may not be licensed in the UK under it), " +
|
|
24
36
|
"or the source was unreachable. If the name is a brand, try resolve_drug_name and retry with the generic.";
|
|
25
|
-
const TRUNCATED_NOTE = (side, url
|
|
37
|
+
const TRUNCATED_NOTE = (side, url, section) => {
|
|
38
|
+
const tool = side.startsWith("US") ? "get_uspi" : "get_smpc";
|
|
39
|
+
const more = section.next_offset !== undefined
|
|
40
|
+
? `call ${tool} with sections ["${section.code}"] and offset ${section.next_offset} to read on (${section.total_chars} characters in total), or `
|
|
41
|
+
: "";
|
|
42
|
+
return `${side} text is verbatim but cut (ends with …); absence of a phrase here proves nothing — ${more}read the full section at ${url ?? "the source"}`;
|
|
43
|
+
};
|
|
26
44
|
const res_us_url = (us) => us?.dailymedUrl ?? null;
|
|
27
45
|
const res_uk_url = (uk) => uk?.url ?? null;
|
|
28
46
|
function sourceStatus(label, note) {
|
|
@@ -38,7 +56,8 @@ export async function buildCompareResult(drug, sections, fetchers = defaultFetch
|
|
|
38
56
|
}
|
|
39
57
|
const usName = names.us?.trim() || drug;
|
|
40
58
|
const ukName = names.uk?.trim() || drug;
|
|
41
|
-
const
|
|
59
|
+
const maxChars = names.maxChars ?? COMPARE_SECTION_CHARS;
|
|
60
|
+
const cacheKey = `compare:${usName.toLowerCase()}|${ukName.toLowerCase()}:${(sections ?? []).join(",").toLowerCase()}:${maxChars}`;
|
|
42
61
|
const cached = cache.get(cacheKey);
|
|
43
62
|
if (cached)
|
|
44
63
|
return cached;
|
|
@@ -61,8 +80,8 @@ export async function buildCompareResult(drug, sections, fetchers = defaultFetch
|
|
|
61
80
|
"or a source was unreachable.",
|
|
62
81
|
};
|
|
63
82
|
}
|
|
64
|
-
const usByCode = new Map(markTruncated(us?.sections ?? []).map((s) => [s.code, s]));
|
|
65
|
-
const ukByCode = new Map(markTruncated(uk?.sections ?? []).map((s) => [s.code, s]));
|
|
83
|
+
const usByCode = new Map(markTruncated(us?.sections ?? []).map((s) => [s.code, pageSection(s, 0, maxChars)]));
|
|
84
|
+
const ukByCode = new Map(markTruncated(uk?.sections ?? []).map((s) => [s.code, pageSection(s, 0, maxChars)]));
|
|
66
85
|
const comparisons = mappings.map((m) => {
|
|
67
86
|
const usSection = usByCode.get(m.us_loinc) ?? null;
|
|
68
87
|
const ukSection = ukByCode.get(m.uk_code) ?? null;
|
|
@@ -80,9 +99,9 @@ export async function buildCompareResult(drug, sections, fetchers = defaultFetch
|
|
|
80
99
|
: `UK SmPC retrieved but has no section ${m.uk_code} (${m.topic})`;
|
|
81
100
|
}
|
|
82
101
|
if (usSection?.truncated)
|
|
83
|
-
c.us_note = TRUNCATED_NOTE("US section", res_us_url(us));
|
|
102
|
+
c.us_note = TRUNCATED_NOTE("US section", res_us_url(us), usSection);
|
|
84
103
|
if (ukSection?.truncated)
|
|
85
|
-
c.uk_note = TRUNCATED_NOTE("UK section", res_uk_url(uk));
|
|
104
|
+
c.uk_note = TRUNCATED_NOTE("UK section", res_uk_url(uk), ukSection);
|
|
86
105
|
return c;
|
|
87
106
|
});
|
|
88
107
|
const result = {
|
|
@@ -98,11 +117,12 @@ export async function buildCompareResult(drug, sections, fetchers = defaultFetch
|
|
|
98
117
|
return result;
|
|
99
118
|
}
|
|
100
119
|
export function registerCompareLabelsTool(server) {
|
|
101
|
-
server.tool("compare_labels", "Compare US FDA Prescribing Information vs UK/EU SmPC for a drug side-by-side. Maps equivalent sections (e.g., US Indications ↔ UK 4.1) and returns paired verbatim content. A missing side is always explained: us_label/uk_label say whether the label was retrieved, each comparison notes why a section is null, and sections
|
|
120
|
+
server.tool("compare_labels", "Compare US FDA Prescribing Information vs UK/EU SmPC for a drug side-by-side. Maps equivalent sections (e.g., US Indications ↔ UK 4.1) and returns paired verbatim content. A missing side is always explained: us_label/uk_label say whether the label was retrieved, each comparison notes why a section is null, and sections longer than max_chars are flagged truncated with next_offset (read on with get_uspi / get_smpc).", schema, { readOnlyHint: true, destructiveHint: false, openWorldHint: true }, async (params) => {
|
|
102
121
|
try {
|
|
103
122
|
const result = await buildCompareResult(params.drug, params.sections, defaultFetchers, {
|
|
104
123
|
us: params.us_drug,
|
|
105
124
|
uk: params.uk_drug,
|
|
125
|
+
maxChars: params.max_chars,
|
|
106
126
|
});
|
|
107
127
|
const isError = "error" in result;
|
|
108
128
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-labels.js","sourceRoot":"","sources":["../../src/tools/compare-labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"compare-labels.js","sourceRoot":"","sources":["../../src/tools/compare-labels.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/smpc.d.ts
CHANGED
|
@@ -4,7 +4,10 @@ import { SmPCResult } from "../types.js";
|
|
|
4
4
|
* Build an SmPCResult from the shared drug-data engine (eMC). Result-shape
|
|
5
5
|
* compatible with the previous implementation. Cached for 24h.
|
|
6
6
|
*/
|
|
7
|
-
export declare function buildSmpcResult(drug: string, sections?: string[]
|
|
7
|
+
export declare function buildSmpcResult(drug: string, sections?: string[], paging?: {
|
|
8
|
+
offset?: number;
|
|
9
|
+
maxChars?: number;
|
|
10
|
+
}): Promise<SmPCResult | {
|
|
8
11
|
error: string;
|
|
9
12
|
}>;
|
|
10
13
|
export declare function registerSmpcTool(server: McpServer): void;
|
package/dist/tools/smpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smpc.d.ts","sourceRoot":"","sources":["../../src/tools/smpc.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"smpc.d.ts","sourceRoot":"","sources":["../../src/tools/smpc.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUpE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA4BzC;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,MAAM,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClD,OAAO,CAAC,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBzC;AAUD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0BxD"}
|
package/dist/tools/smpc.js
CHANGED
|
@@ -2,23 +2,37 @@ import { z } from "zod";
|
|
|
2
2
|
import { getUkSmpc } from "@pharmatools/drug-data";
|
|
3
3
|
import { cache, TTL } from "../lib/cache.js";
|
|
4
4
|
import { markTruncated } from "../lib/label-mapping.js";
|
|
5
|
+
import { pageSections, DEFAULT_SECTION_CHARS, MIN_SECTION_CHARS, MAX_SECTION_CHARS, } from "../lib/paging.js";
|
|
5
6
|
const schema = {
|
|
6
7
|
drug: z.string().describe("Drug name to look up (e.g., 'metformin', 'atorvastatin')"),
|
|
7
8
|
sections: z
|
|
8
9
|
.array(z.string())
|
|
9
10
|
.optional()
|
|
10
11
|
.describe("Specific sections to retrieve — accepts numbers like '4.1' or names like 'indications'. Returns all sections if omitted."),
|
|
12
|
+
max_chars: z
|
|
13
|
+
.number()
|
|
14
|
+
.int()
|
|
15
|
+
.min(MIN_SECTION_CHARS)
|
|
16
|
+
.max(MAX_SECTION_CHARS)
|
|
17
|
+
.optional()
|
|
18
|
+
.describe(`Maximum characters returned per section (default ${DEFAULT_SECTION_CHARS}). Long sections are returned a page at a time: a cut page has truncated: true, total_chars and next_offset.`),
|
|
19
|
+
offset: z
|
|
20
|
+
.number()
|
|
21
|
+
.int()
|
|
22
|
+
.min(0)
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Character offset to start each section from (default 0). To read the rest of a truncated section, call again with sections set to that one section and offset set to its next_offset."),
|
|
11
25
|
};
|
|
12
26
|
/**
|
|
13
27
|
* Build an SmPCResult from the shared drug-data engine (eMC). Result-shape
|
|
14
28
|
* compatible with the previous implementation. Cached for 24h.
|
|
15
29
|
*/
|
|
16
|
-
export async function buildSmpcResult(drug, sections) {
|
|
17
|
-
const cacheKey = `smpc:${drug.toLowerCase()}:${(sections ?? []).join(",").toLowerCase()}`;
|
|
30
|
+
export async function buildSmpcResult(drug, sections, paging = {}) {
|
|
31
|
+
const cacheKey = `smpc-full:${drug.toLowerCase()}:${(sections ?? []).join(",").toLowerCase()}`;
|
|
18
32
|
const cached = cache.get(cacheKey);
|
|
19
33
|
if (cached)
|
|
20
|
-
return cached;
|
|
21
|
-
const smpc = await getUkSmpc(drug, sections);
|
|
34
|
+
return applyPaging(cached, paging);
|
|
35
|
+
const smpc = await getUkSmpc(drug, sections, { maxChars: Infinity });
|
|
22
36
|
if (!smpc || smpc.sections.length === 0) {
|
|
23
37
|
return { error: `No SmPC found for "${drug}" on eMC` };
|
|
24
38
|
}
|
|
@@ -29,12 +43,22 @@ export async function buildSmpcResult(drug, sections) {
|
|
|
29
43
|
url: smpc.url,
|
|
30
44
|
};
|
|
31
45
|
cache.set(cacheKey, result, TTL.LABEL);
|
|
32
|
-
return result;
|
|
46
|
+
return applyPaging(result, paging);
|
|
47
|
+
}
|
|
48
|
+
/** Page every section of a full (cached) result. */
|
|
49
|
+
function applyPaging(result, paging) {
|
|
50
|
+
return {
|
|
51
|
+
...result,
|
|
52
|
+
sections: pageSections(result.sections, paging.offset ?? 0, paging.maxChars ?? DEFAULT_SECTION_CHARS),
|
|
53
|
+
};
|
|
33
54
|
}
|
|
34
55
|
export function registerSmpcTool(server) {
|
|
35
|
-
server.tool("get_smpc", "Get UK/EU Summary of Product Characteristics (SmPC) for a drug from eMC (medicines.org.uk). Returns structured labelling sections.", schema, { readOnlyHint: true, destructiveHint: false, openWorldHint: true }, async (params) => {
|
|
56
|
+
server.tool("get_smpc", "Get UK/EU Summary of Product Characteristics (SmPC) for a drug from eMC (medicines.org.uk). Returns structured labelling sections, verbatim. Long sections are paged: a cut section has truncated: true, total_chars and next_offset — call again with that section and offset to read on. Check drug_name: the best eMC match may be a different product or formulation from the one you meant.", schema, { readOnlyHint: true, destructiveHint: false, openWorldHint: true }, async (params) => {
|
|
36
57
|
try {
|
|
37
|
-
const result = await buildSmpcResult(params.drug, params.sections
|
|
58
|
+
const result = await buildSmpcResult(params.drug, params.sections, {
|
|
59
|
+
offset: params.offset,
|
|
60
|
+
maxChars: params.max_chars,
|
|
61
|
+
});
|
|
38
62
|
const isError = "error" in result;
|
|
39
63
|
return {
|
|
40
64
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
package/dist/tools/smpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smpc.js","sourceRoot":"","sources":["../../src/tools/smpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"smpc.js","sourceRoot":"","sources":["../../src/tools/smpc.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/uspi.d.ts
CHANGED
|
@@ -5,7 +5,10 @@ import { USPIResult } from "../types.js";
|
|
|
5
5
|
* DailyMed). Result-shape compatible with the previous SPL-based implementation.
|
|
6
6
|
* Cached for 24h. Returns { error } when no label is found.
|
|
7
7
|
*/
|
|
8
|
-
export declare function buildUspiResult(drug: string, sections?: string[]
|
|
8
|
+
export declare function buildUspiResult(drug: string, sections?: string[], paging?: {
|
|
9
|
+
offset?: number;
|
|
10
|
+
maxChars?: number;
|
|
11
|
+
}): Promise<USPIResult | {
|
|
9
12
|
error: string;
|
|
10
13
|
}>;
|
|
11
14
|
export declare function registerUspiTool(server: McpServer): void;
|
package/dist/tools/uspi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uspi.d.ts","sourceRoot":"","sources":["../../src/tools/uspi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"uspi.d.ts","sourceRoot":"","sources":["../../src/tools/uspi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUpE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA4BzC;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,MAAM,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClD,OAAO,CAAC,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBzC;AAUD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0BxD"}
|
package/dist/tools/uspi.js
CHANGED
|
@@ -2,24 +2,38 @@ import { z } from "zod";
|
|
|
2
2
|
import { getUsLabel } from "@pharmatools/drug-data";
|
|
3
3
|
import { cache, TTL } from "../lib/cache.js";
|
|
4
4
|
import { markTruncated } from "../lib/label-mapping.js";
|
|
5
|
+
import { pageSections, DEFAULT_SECTION_CHARS, MIN_SECTION_CHARS, MAX_SECTION_CHARS, } from "../lib/paging.js";
|
|
5
6
|
const schema = {
|
|
6
7
|
drug: z.string().describe("Drug name to look up (e.g., 'metformin', 'atorvastatin')"),
|
|
7
8
|
sections: z
|
|
8
9
|
.array(z.string())
|
|
9
10
|
.optional()
|
|
10
11
|
.describe("Specific sections to retrieve (e.g., ['indications', 'adverse reactions', 'contraindications']). Returns all sections if omitted."),
|
|
12
|
+
max_chars: z
|
|
13
|
+
.number()
|
|
14
|
+
.int()
|
|
15
|
+
.min(MIN_SECTION_CHARS)
|
|
16
|
+
.max(MAX_SECTION_CHARS)
|
|
17
|
+
.optional()
|
|
18
|
+
.describe(`Maximum characters returned per section (default ${DEFAULT_SECTION_CHARS}). Long sections are returned a page at a time: a cut page has truncated: true, total_chars and next_offset.`),
|
|
19
|
+
offset: z
|
|
20
|
+
.number()
|
|
21
|
+
.int()
|
|
22
|
+
.min(0)
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Character offset to start each section from (default 0). To read the rest of a truncated section, call again with sections set to that one section and offset set to its next_offset."),
|
|
11
25
|
};
|
|
12
26
|
/**
|
|
13
27
|
* Build a USPIResult from the shared drug-data engine (openFDA, cited to
|
|
14
28
|
* DailyMed). Result-shape compatible with the previous SPL-based implementation.
|
|
15
29
|
* Cached for 24h. Returns { error } when no label is found.
|
|
16
30
|
*/
|
|
17
|
-
export async function buildUspiResult(drug, sections) {
|
|
18
|
-
const cacheKey = `uspi:${drug.toLowerCase()}:${(sections ?? []).join(",").toLowerCase()}`;
|
|
31
|
+
export async function buildUspiResult(drug, sections, paging = {}) {
|
|
32
|
+
const cacheKey = `uspi-full:${drug.toLowerCase()}:${(sections ?? []).join(",").toLowerCase()}`;
|
|
19
33
|
const cached = cache.get(cacheKey);
|
|
20
34
|
if (cached)
|
|
21
|
-
return cached;
|
|
22
|
-
const label = await getUsLabel(drug, sections);
|
|
35
|
+
return applyPaging(cached, paging);
|
|
36
|
+
const label = await getUsLabel(drug, sections, { maxChars: Infinity });
|
|
23
37
|
if (!label || label.sections.length === 0) {
|
|
24
38
|
return { error: `No FDA labelling found for "${drug}"` };
|
|
25
39
|
}
|
|
@@ -32,12 +46,22 @@ export async function buildUspiResult(drug, sections) {
|
|
|
32
46
|
dailymed_url: label.dailymedUrl,
|
|
33
47
|
};
|
|
34
48
|
cache.set(cacheKey, result, TTL.LABEL);
|
|
35
|
-
return result;
|
|
49
|
+
return applyPaging(result, paging);
|
|
50
|
+
}
|
|
51
|
+
/** Page every section of a full (cached) result. */
|
|
52
|
+
function applyPaging(result, paging) {
|
|
53
|
+
return {
|
|
54
|
+
...result,
|
|
55
|
+
sections: pageSections(result.sections, paging.offset ?? 0, paging.maxChars ?? DEFAULT_SECTION_CHARS),
|
|
56
|
+
};
|
|
36
57
|
}
|
|
37
58
|
export function registerUspiTool(server) {
|
|
38
|
-
server.tool("get_uspi", "Get FDA US Prescribing Information (USPI) for a drug from openFDA (cited to DailyMed). Returns structured labelling sections with LOINC codes.", schema, { readOnlyHint: true, destructiveHint: false, openWorldHint: true }, async (params) => {
|
|
59
|
+
server.tool("get_uspi", "Get FDA US Prescribing Information (USPI) for a drug from openFDA (cited to DailyMed). Returns structured labelling sections with LOINC codes, verbatim. Long sections are paged: a cut section has truncated: true, total_chars and next_offset — call again with that section and offset to read on. Check drug_name: the best openFDA match may be a different product from the one you meant.", schema, { readOnlyHint: true, destructiveHint: false, openWorldHint: true }, async (params) => {
|
|
39
60
|
try {
|
|
40
|
-
const result = await buildUspiResult(params.drug, params.sections
|
|
61
|
+
const result = await buildUspiResult(params.drug, params.sections, {
|
|
62
|
+
offset: params.offset,
|
|
63
|
+
maxChars: params.max_chars,
|
|
64
|
+
});
|
|
41
65
|
const isError = "error" in result;
|
|
42
66
|
return {
|
|
43
67
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
package/dist/tools/uspi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uspi.js","sourceRoot":"","sources":["../../src/tools/uspi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"uspi.js","sourceRoot":"","sources":["../../src/tools/uspi.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -68,12 +68,18 @@ export interface LabelSection {
|
|
|
68
68
|
title: string;
|
|
69
69
|
content: string;
|
|
70
70
|
/**
|
|
71
|
-
* True when
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
71
|
+
* True when more of this section follows this page (content then ends with
|
|
72
|
+
* an ellipsis). The text returned is verbatim but incomplete: absence of a
|
|
73
|
+
* phrase from a truncated section proves nothing. Fetch the next page with
|
|
74
|
+
* `offset: next_offset` on get_smpc / get_uspi.
|
|
75
75
|
*/
|
|
76
76
|
truncated?: boolean;
|
|
77
|
+
/** Length of the full section text (present when the section is paged). */
|
|
78
|
+
total_chars?: number;
|
|
79
|
+
/** Where this page starts in the full section (present when > 0). */
|
|
80
|
+
offset?: number;
|
|
81
|
+
/** Pass as `offset` to fetch the next page (present when truncated). */
|
|
82
|
+
next_offset?: number;
|
|
77
83
|
}
|
|
78
84
|
export interface USPIResult {
|
|
79
85
|
drug_name: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,aAAa,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,qDAAqD;IACrD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,YAAY,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,YAAY,GAAG,IAAI,CAAC;IAChC,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAID,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,mBAAoB,SAAQ,oBAAoB;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,gBAAgB,EAAE,YAAY,EAAE,CAAC;IACjC,kBAAkB,EAAE,YAAY,EAAE,CAAC;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;CACb"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pharmatools/pubcrawl",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "MCP server for PubMed & Europe PMC literature search, US/UK drug labelling, and clinical trials — built by PharmaTools.AI",
|
|
5
5
|
"mcpName": "io.github.nickjlamb/pubcrawl",
|
|
6
6
|
"author": "PharmaTools.AI",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
43
|
-
"@pharmatools/drug-data": "^0.
|
|
43
|
+
"@pharmatools/drug-data": "^0.3.0",
|
|
44
44
|
"cheerio": "^1.2.0",
|
|
45
45
|
"dotenv": "^16.0.0",
|
|
46
46
|
"fast-xml-parser": "^5.11.2",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/nickjlamb/pubcrawl",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.7.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@pharmatools/pubcrawl",
|
|
14
|
-
"version": "2.
|
|
14
|
+
"version": "2.7.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|