@everdeep/pubmed 0.1.2 → 0.1.3
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 +11 -1
- package/dist/index.cjs +35 -12
- package/dist/index.d.cts +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +35 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,7 +132,17 @@ if (record?.kind === "article") {
|
|
|
132
132
|
}
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
`rawXml` is omitted by default, including on unknown records. Enable it for a client or individual full-record request to retain the exact direct-child XML fragment received from PubMed, without serialization or normalization:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const client = new PubMedClient({ email, tool, includeRawXml: true });
|
|
139
|
+
const record = await client.get("123"); // includes rawXml
|
|
140
|
+
const compact = await client.get("123", { includeRawXml: false }); // omits rawXml
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The per-request option also applies to `getMany`, `search` (including cursor requests), and every page of `searchAll`. Each cursor request uses its own option or the client's default, not the previous page's option. The standalone parser similarly supports `parsePubMedXml(xml, { includeRawXml: true })` and omits XML by default.
|
|
144
|
+
|
|
145
|
+
**Compatibility change:** `rawXml` is now optional (`string | undefined`); consumers that previously relied on its presence must explicitly opt in. This controls returned fields only: XML is still fetched and parsed, and any configured response cache still stores XML bodies. `source` continues to retain parsed source data for fields not represented in the normalized surface. Summary methods are unchanged and do not support this option.
|
|
136
146
|
|
|
137
147
|
## Citation export
|
|
138
148
|
|
package/dist/index.cjs
CHANGED
|
@@ -715,8 +715,19 @@ function parseFragment(fragment) {
|
|
|
715
715
|
}
|
|
716
716
|
|
|
717
717
|
// src/parser.ts
|
|
718
|
-
function parsePubMedXml(xml) {
|
|
719
|
-
|
|
718
|
+
function parsePubMedXml(xml, options = {}) {
|
|
719
|
+
if (typeof options !== "object" || options === null || Array.isArray(options)) {
|
|
720
|
+
throw new ValidationError("parser options must be an object");
|
|
721
|
+
}
|
|
722
|
+
if (options.includeRawXml !== void 0 && typeof options.includeRawXml !== "boolean") {
|
|
723
|
+
throw new ValidationError("includeRawXml must be a boolean");
|
|
724
|
+
}
|
|
725
|
+
const records = extractFragments(xml).map((fragment) => {
|
|
726
|
+
const record = parseFragment(fragment);
|
|
727
|
+
if (options.includeRawXml === true) return record;
|
|
728
|
+
const { rawXml, ...withoutRawXml } = record;
|
|
729
|
+
return withoutRawXml;
|
|
730
|
+
});
|
|
720
731
|
const warnings = records.flatMap((record) => record.kind === "unknown" ? [{ code: "UNKNOWN_RECORD", message: `Unknown PubMed record type: ${record.recordType}`, recordType: record.recordType }] : []);
|
|
721
732
|
return { records, warnings };
|
|
722
733
|
}
|
|
@@ -1674,6 +1685,9 @@ function isAbortSignal(value) {
|
|
|
1674
1685
|
function validateRequestOptions(options, name) {
|
|
1675
1686
|
const candidate = object3(options);
|
|
1676
1687
|
if (candidate === void 0) throw new ValidationError(`${name} must be an object`);
|
|
1688
|
+
if (candidate.includeRawXml !== void 0 && typeof candidate.includeRawXml !== "boolean") {
|
|
1689
|
+
throw new ValidationError("includeRawXml must be a boolean");
|
|
1690
|
+
}
|
|
1677
1691
|
if (candidate.includeLinkOuts !== void 0 && typeof candidate.includeLinkOuts !== "boolean") {
|
|
1678
1692
|
throw new ValidationError("includeLinkOuts must be a boolean");
|
|
1679
1693
|
}
|
|
@@ -1684,6 +1698,9 @@ function validateRequestOptions(options, name) {
|
|
|
1684
1698
|
function validateSummaryRequestOptions(options) {
|
|
1685
1699
|
const candidate = object3(options);
|
|
1686
1700
|
if (candidate === void 0) throw new ValidationError("summary request options must be an object");
|
|
1701
|
+
if (candidate.includeRawXml !== void 0) {
|
|
1702
|
+
throw new ValidationError("includeRawXml is not supported for summary requests");
|
|
1703
|
+
}
|
|
1687
1704
|
if (candidate.includeLinkOuts !== void 0) {
|
|
1688
1705
|
throw new ValidationError("includeLinkOuts is not supported for summary requests");
|
|
1689
1706
|
}
|
|
@@ -1816,7 +1833,7 @@ function validateSearchState(state, expectedIds, offset = 0) {
|
|
|
1816
1833
|
}
|
|
1817
1834
|
}
|
|
1818
1835
|
function parseExpectedFetch(body, expectedPmids) {
|
|
1819
|
-
const parsed = parsePubMedXml(body);
|
|
1836
|
+
const parsed = parsePubMedXml(body, { includeRawXml: true });
|
|
1820
1837
|
const expected = new Set(expectedPmids);
|
|
1821
1838
|
const seen = /* @__PURE__ */ new Set();
|
|
1822
1839
|
for (const record of parsed.records) {
|
|
@@ -1897,11 +1914,16 @@ function withLinks(record, extra) {
|
|
|
1897
1914
|
var PubMedClient = class {
|
|
1898
1915
|
#transport;
|
|
1899
1916
|
#maxBatchSize;
|
|
1917
|
+
#includeRawXml;
|
|
1900
1918
|
#totalDriftPolicy;
|
|
1901
1919
|
#onEvent;
|
|
1902
1920
|
constructor(options) {
|
|
1903
1921
|
if (typeof options !== "object" || options === null) throw new ValidationError("PubMedClient options are required");
|
|
1904
1922
|
validateAdapterShapes(options);
|
|
1923
|
+
if (options.includeRawXml !== void 0 && typeof options.includeRawXml !== "boolean") {
|
|
1924
|
+
throw new ValidationError("includeRawXml must be a boolean");
|
|
1925
|
+
}
|
|
1926
|
+
this.#includeRawXml = options.includeRawXml ?? false;
|
|
1905
1927
|
if (options.totalDriftPolicy !== void 0 && options.totalDriftPolicy !== "error" && options.totalDriftPolicy !== "warn") {
|
|
1906
1928
|
throw new ValidationError('totalDriftPolicy must be "error" or "warn"');
|
|
1907
1929
|
}
|
|
@@ -1968,6 +1990,9 @@ var PubMedClient = class {
|
|
|
1968
1990
|
}
|
|
1969
1991
|
let ordered = input.flatMap((pmid) => byPmid.get(pmid) ?? []);
|
|
1970
1992
|
if (unknown.length > 0) ordered = [...ordered, ...unknown];
|
|
1993
|
+
if (!(options.includeRawXml ?? this.#includeRawXml)) {
|
|
1994
|
+
ordered = ordered.map(({ rawXml, ...record }) => record);
|
|
1995
|
+
}
|
|
1971
1996
|
if (options.includeLinkOuts === true && ordered.length > 0) ordered = await this.#enrich(ordered, options.signal);
|
|
1972
1997
|
if (options.signal?.aborted) throw new AbortedError();
|
|
1973
1998
|
return {
|
|
@@ -2009,7 +2034,7 @@ var PubMedClient = class {
|
|
|
2009
2034
|
validateRequestOptions(options, "search options");
|
|
2010
2035
|
if ("cursor" in options) {
|
|
2011
2036
|
if (typeof options.cursor !== "string" || options.cursor === "") throw new ValidationError("cursor must be a non-empty string");
|
|
2012
|
-
return (await this.#searchCursorPage(options.cursor, options
|
|
2037
|
+
return (await this.#searchCursorPage(options.cursor, options)).batch;
|
|
2013
2038
|
}
|
|
2014
2039
|
validateQueryOptions(options);
|
|
2015
2040
|
return (await this.#searchQueryPage(options)).batch;
|
|
@@ -2025,6 +2050,7 @@ var PubMedClient = class {
|
|
|
2025
2050
|
query: options.query,
|
|
2026
2051
|
pageSize,
|
|
2027
2052
|
...options.sort === void 0 ? {} : { sort: options.sort },
|
|
2053
|
+
...options.includeRawXml === void 0 ? {} : { includeRawXml: options.includeRawXml },
|
|
2028
2054
|
...options.includeLinkOuts === void 0 ? {} : { includeLinkOuts: options.includeLinkOuts },
|
|
2029
2055
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
2030
2056
|
};
|
|
@@ -2041,8 +2067,7 @@ var PubMedClient = class {
|
|
|
2041
2067
|
if (page.batch.nextCursor === null) throw new InvalidResponseError("PubMed search ended before the requested result count");
|
|
2042
2068
|
page = await this.#searchCursorPage(
|
|
2043
2069
|
page.batch.nextCursor,
|
|
2044
|
-
options
|
|
2045
|
-
options.signal,
|
|
2070
|
+
options,
|
|
2046
2071
|
target - processed
|
|
2047
2072
|
);
|
|
2048
2073
|
}
|
|
@@ -2082,10 +2107,7 @@ var PubMedClient = class {
|
|
|
2082
2107
|
expectedPmids: []
|
|
2083
2108
|
};
|
|
2084
2109
|
}
|
|
2085
|
-
const batch = await this.getMany(state.ids,
|
|
2086
|
-
...options.includeLinkOuts === void 0 ? {} : { includeLinkOuts: options.includeLinkOuts },
|
|
2087
|
-
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
2088
|
-
});
|
|
2110
|
+
const batch = await this.getMany(state.ids, options);
|
|
2089
2111
|
const offset = state.ids.length;
|
|
2090
2112
|
return {
|
|
2091
2113
|
batch: {
|
|
@@ -2096,7 +2118,8 @@ var PubMedClient = class {
|
|
|
2096
2118
|
expectedPmids: state.ids
|
|
2097
2119
|
};
|
|
2098
2120
|
}
|
|
2099
|
-
async #searchCursorPage(cursorValue,
|
|
2121
|
+
async #searchCursorPage(cursorValue, options, maxExpected) {
|
|
2122
|
+
const { signal } = options;
|
|
2100
2123
|
const cursor = decodeCursor(cursorValue);
|
|
2101
2124
|
if (cursor.offset >= SEARCH_WINDOW) throw new SearchLimitError();
|
|
2102
2125
|
const remainingWindow = SEARCH_WINDOW - cursor.offset;
|
|
@@ -2135,7 +2158,7 @@ var PubMedClient = class {
|
|
|
2135
2158
|
{ cache: false, ...signal === void 0 ? {} : { signal } }
|
|
2136
2159
|
);
|
|
2137
2160
|
if (diagnostic !== void 0) safeEvent(this.#onEvent, { type: "search-total-drift", ...diagnostic });
|
|
2138
|
-
const batch = await this.getMany(state.ids,
|
|
2161
|
+
const batch = await this.getMany(state.ids, options);
|
|
2139
2162
|
const offset = cursor.offset + state.ids.length;
|
|
2140
2163
|
return {
|
|
2141
2164
|
batch: {
|
package/dist/index.d.cts
CHANGED
|
@@ -169,7 +169,8 @@ interface PubMedWarning {
|
|
|
169
169
|
interface BasePubMedRecord {
|
|
170
170
|
readonly kind: "article" | "book" | "unknown";
|
|
171
171
|
readonly recordType: string;
|
|
172
|
-
|
|
172
|
+
/** Exact source fragment, present only when includeRawXml is enabled. */
|
|
173
|
+
readonly rawXml?: string;
|
|
173
174
|
readonly source: JsonObject;
|
|
174
175
|
readonly identifiers: readonly PubMedIdentifier[];
|
|
175
176
|
readonly links: readonly PubMedLink[];
|
|
@@ -305,6 +306,8 @@ interface SearchBatch extends BatchResult {
|
|
|
305
306
|
readonly diagnostics?: readonly SearchTotalDriftDiagnostic[];
|
|
306
307
|
}
|
|
307
308
|
interface RequestOptions {
|
|
309
|
+
/** Override the client's raw XML inclusion default for this request. */
|
|
310
|
+
readonly includeRawXml?: boolean;
|
|
308
311
|
readonly includeLinkOuts?: boolean;
|
|
309
312
|
readonly signal?: AbortSignal;
|
|
310
313
|
}
|
|
@@ -396,6 +399,8 @@ type PubMedEvent = Readonly<{
|
|
|
396
399
|
recordType?: string;
|
|
397
400
|
}>;
|
|
398
401
|
interface PubMedClientOptions {
|
|
402
|
+
/** Include exact source XML fragments in full records. Default false. */
|
|
403
|
+
readonly includeRawXml?: boolean;
|
|
399
404
|
readonly email: string;
|
|
400
405
|
readonly tool: string;
|
|
401
406
|
readonly apiKey?: string;
|
|
@@ -449,7 +454,11 @@ interface ParsedPubMedXml {
|
|
|
449
454
|
readonly records: readonly PubMedRecord[];
|
|
450
455
|
readonly warnings: readonly PubMedWarning[];
|
|
451
456
|
}
|
|
452
|
-
|
|
453
|
-
|
|
457
|
+
interface ParsePubMedXmlOptions {
|
|
458
|
+
/** Include each direct child's exact source XML fragment. Default false. */
|
|
459
|
+
readonly includeRawXml?: boolean;
|
|
460
|
+
}
|
|
461
|
+
/** Parse an entire PubmedArticleSet, optionally retaining exact source fragments. */
|
|
462
|
+
declare function parsePubMedXml(xml: string, options?: ParsePubMedXmlOptions): ParsedPubMedXml;
|
|
454
463
|
|
|
455
|
-
export { AbortedError, type AbstractSection, type Affiliation, type AuthorIdentifier, type BasePubMedRecord, type BatchResult, type CacheAdapter, type CitationFormat, type CitationSource, type CollectiveAuthor, CursorExpiredError, CursorInvalidError, HttpError, InvalidResponseError, type JournalCitation, type JsonObject, type JsonPrimitive, type JsonValue, type Keyword, MemoryCache, type MemoryCacheOptions, type MeshHeading, NetworkError, PaginationConsistencyError, ParseError, type ParsedPubMedXml, type PartialDate, type PersonalAuthor, type PubMedArticleRecord, type PubMedAuthor, type PubMedBookRecord, PubMedClient, type PubMedClientOptions, type PubMedEndpoint, PubMedError, type PubMedErrorCode, type PubMedEvent, type PubMedIdentifier, type PubMedLink, type PubMedRecord, type PubMedSummary, type PubMedSummaryAuthor, type PubMedSummaryBook, type PubMedSummaryHistoryEntry, type PubMedSummaryIdentifier, type PubMedSummaryJournal, type PubMedWarning, type PublicationDates, type PublicationHistoryEntry, QueueFullError, type RateLimitBucket, type RateLimitCoordinator, RateLimitError, type RequestOptions, ResponseTooLargeError, type SearchAllOptions, type SearchBatch, type SearchCursorOptions, SearchLimitError, type SearchOptions, type SearchQueryOptions, type SearchTotalDriftDiagnostic, type SummaryBatchResult, type SummaryRequestOptions, TimeoutError, type UnknownPubMedRecord, ValidationError, formatCitation, formatCitations, parsePubMedXml };
|
|
464
|
+
export { AbortedError, type AbstractSection, type Affiliation, type AuthorIdentifier, type BasePubMedRecord, type BatchResult, type CacheAdapter, type CitationFormat, type CitationSource, type CollectiveAuthor, CursorExpiredError, CursorInvalidError, HttpError, InvalidResponseError, type JournalCitation, type JsonObject, type JsonPrimitive, type JsonValue, type Keyword, MemoryCache, type MemoryCacheOptions, type MeshHeading, NetworkError, PaginationConsistencyError, ParseError, type ParsePubMedXmlOptions, type ParsedPubMedXml, type PartialDate, type PersonalAuthor, type PubMedArticleRecord, type PubMedAuthor, type PubMedBookRecord, PubMedClient, type PubMedClientOptions, type PubMedEndpoint, PubMedError, type PubMedErrorCode, type PubMedEvent, type PubMedIdentifier, type PubMedLink, type PubMedRecord, type PubMedSummary, type PubMedSummaryAuthor, type PubMedSummaryBook, type PubMedSummaryHistoryEntry, type PubMedSummaryIdentifier, type PubMedSummaryJournal, type PubMedWarning, type PublicationDates, type PublicationHistoryEntry, QueueFullError, type RateLimitBucket, type RateLimitCoordinator, RateLimitError, type RequestOptions, ResponseTooLargeError, type SearchAllOptions, type SearchBatch, type SearchCursorOptions, SearchLimitError, type SearchOptions, type SearchQueryOptions, type SearchTotalDriftDiagnostic, type SummaryBatchResult, type SummaryRequestOptions, TimeoutError, type UnknownPubMedRecord, ValidationError, formatCitation, formatCitations, parsePubMedXml };
|
package/dist/index.d.ts
CHANGED
|
@@ -169,7 +169,8 @@ interface PubMedWarning {
|
|
|
169
169
|
interface BasePubMedRecord {
|
|
170
170
|
readonly kind: "article" | "book" | "unknown";
|
|
171
171
|
readonly recordType: string;
|
|
172
|
-
|
|
172
|
+
/** Exact source fragment, present only when includeRawXml is enabled. */
|
|
173
|
+
readonly rawXml?: string;
|
|
173
174
|
readonly source: JsonObject;
|
|
174
175
|
readonly identifiers: readonly PubMedIdentifier[];
|
|
175
176
|
readonly links: readonly PubMedLink[];
|
|
@@ -305,6 +306,8 @@ interface SearchBatch extends BatchResult {
|
|
|
305
306
|
readonly diagnostics?: readonly SearchTotalDriftDiagnostic[];
|
|
306
307
|
}
|
|
307
308
|
interface RequestOptions {
|
|
309
|
+
/** Override the client's raw XML inclusion default for this request. */
|
|
310
|
+
readonly includeRawXml?: boolean;
|
|
308
311
|
readonly includeLinkOuts?: boolean;
|
|
309
312
|
readonly signal?: AbortSignal;
|
|
310
313
|
}
|
|
@@ -396,6 +399,8 @@ type PubMedEvent = Readonly<{
|
|
|
396
399
|
recordType?: string;
|
|
397
400
|
}>;
|
|
398
401
|
interface PubMedClientOptions {
|
|
402
|
+
/** Include exact source XML fragments in full records. Default false. */
|
|
403
|
+
readonly includeRawXml?: boolean;
|
|
399
404
|
readonly email: string;
|
|
400
405
|
readonly tool: string;
|
|
401
406
|
readonly apiKey?: string;
|
|
@@ -449,7 +454,11 @@ interface ParsedPubMedXml {
|
|
|
449
454
|
readonly records: readonly PubMedRecord[];
|
|
450
455
|
readonly warnings: readonly PubMedWarning[];
|
|
451
456
|
}
|
|
452
|
-
|
|
453
|
-
|
|
457
|
+
interface ParsePubMedXmlOptions {
|
|
458
|
+
/** Include each direct child's exact source XML fragment. Default false. */
|
|
459
|
+
readonly includeRawXml?: boolean;
|
|
460
|
+
}
|
|
461
|
+
/** Parse an entire PubmedArticleSet, optionally retaining exact source fragments. */
|
|
462
|
+
declare function parsePubMedXml(xml: string, options?: ParsePubMedXmlOptions): ParsedPubMedXml;
|
|
454
463
|
|
|
455
|
-
export { AbortedError, type AbstractSection, type Affiliation, type AuthorIdentifier, type BasePubMedRecord, type BatchResult, type CacheAdapter, type CitationFormat, type CitationSource, type CollectiveAuthor, CursorExpiredError, CursorInvalidError, HttpError, InvalidResponseError, type JournalCitation, type JsonObject, type JsonPrimitive, type JsonValue, type Keyword, MemoryCache, type MemoryCacheOptions, type MeshHeading, NetworkError, PaginationConsistencyError, ParseError, type ParsedPubMedXml, type PartialDate, type PersonalAuthor, type PubMedArticleRecord, type PubMedAuthor, type PubMedBookRecord, PubMedClient, type PubMedClientOptions, type PubMedEndpoint, PubMedError, type PubMedErrorCode, type PubMedEvent, type PubMedIdentifier, type PubMedLink, type PubMedRecord, type PubMedSummary, type PubMedSummaryAuthor, type PubMedSummaryBook, type PubMedSummaryHistoryEntry, type PubMedSummaryIdentifier, type PubMedSummaryJournal, type PubMedWarning, type PublicationDates, type PublicationHistoryEntry, QueueFullError, type RateLimitBucket, type RateLimitCoordinator, RateLimitError, type RequestOptions, ResponseTooLargeError, type SearchAllOptions, type SearchBatch, type SearchCursorOptions, SearchLimitError, type SearchOptions, type SearchQueryOptions, type SearchTotalDriftDiagnostic, type SummaryBatchResult, type SummaryRequestOptions, TimeoutError, type UnknownPubMedRecord, ValidationError, formatCitation, formatCitations, parsePubMedXml };
|
|
464
|
+
export { AbortedError, type AbstractSection, type Affiliation, type AuthorIdentifier, type BasePubMedRecord, type BatchResult, type CacheAdapter, type CitationFormat, type CitationSource, type CollectiveAuthor, CursorExpiredError, CursorInvalidError, HttpError, InvalidResponseError, type JournalCitation, type JsonObject, type JsonPrimitive, type JsonValue, type Keyword, MemoryCache, type MemoryCacheOptions, type MeshHeading, NetworkError, PaginationConsistencyError, ParseError, type ParsePubMedXmlOptions, type ParsedPubMedXml, type PartialDate, type PersonalAuthor, type PubMedArticleRecord, type PubMedAuthor, type PubMedBookRecord, PubMedClient, type PubMedClientOptions, type PubMedEndpoint, PubMedError, type PubMedErrorCode, type PubMedEvent, type PubMedIdentifier, type PubMedLink, type PubMedRecord, type PubMedSummary, type PubMedSummaryAuthor, type PubMedSummaryBook, type PubMedSummaryHistoryEntry, type PubMedSummaryIdentifier, type PubMedSummaryJournal, type PubMedWarning, type PublicationDates, type PublicationHistoryEntry, QueueFullError, type RateLimitBucket, type RateLimitCoordinator, RateLimitError, type RequestOptions, ResponseTooLargeError, type SearchAllOptions, type SearchBatch, type SearchCursorOptions, SearchLimitError, type SearchOptions, type SearchQueryOptions, type SearchTotalDriftDiagnostic, type SummaryBatchResult, type SummaryRequestOptions, TimeoutError, type UnknownPubMedRecord, ValidationError, formatCitation, formatCitations, parsePubMedXml };
|
package/dist/index.js
CHANGED
|
@@ -670,8 +670,19 @@ function parseFragment(fragment) {
|
|
|
670
670
|
}
|
|
671
671
|
|
|
672
672
|
// src/parser.ts
|
|
673
|
-
function parsePubMedXml(xml) {
|
|
674
|
-
|
|
673
|
+
function parsePubMedXml(xml, options = {}) {
|
|
674
|
+
if (typeof options !== "object" || options === null || Array.isArray(options)) {
|
|
675
|
+
throw new ValidationError("parser options must be an object");
|
|
676
|
+
}
|
|
677
|
+
if (options.includeRawXml !== void 0 && typeof options.includeRawXml !== "boolean") {
|
|
678
|
+
throw new ValidationError("includeRawXml must be a boolean");
|
|
679
|
+
}
|
|
680
|
+
const records = extractFragments(xml).map((fragment) => {
|
|
681
|
+
const record = parseFragment(fragment);
|
|
682
|
+
if (options.includeRawXml === true) return record;
|
|
683
|
+
const { rawXml, ...withoutRawXml } = record;
|
|
684
|
+
return withoutRawXml;
|
|
685
|
+
});
|
|
675
686
|
const warnings = records.flatMap((record) => record.kind === "unknown" ? [{ code: "UNKNOWN_RECORD", message: `Unknown PubMed record type: ${record.recordType}`, recordType: record.recordType }] : []);
|
|
676
687
|
return { records, warnings };
|
|
677
688
|
}
|
|
@@ -1629,6 +1640,9 @@ function isAbortSignal(value) {
|
|
|
1629
1640
|
function validateRequestOptions(options, name) {
|
|
1630
1641
|
const candidate = object3(options);
|
|
1631
1642
|
if (candidate === void 0) throw new ValidationError(`${name} must be an object`);
|
|
1643
|
+
if (candidate.includeRawXml !== void 0 && typeof candidate.includeRawXml !== "boolean") {
|
|
1644
|
+
throw new ValidationError("includeRawXml must be a boolean");
|
|
1645
|
+
}
|
|
1632
1646
|
if (candidate.includeLinkOuts !== void 0 && typeof candidate.includeLinkOuts !== "boolean") {
|
|
1633
1647
|
throw new ValidationError("includeLinkOuts must be a boolean");
|
|
1634
1648
|
}
|
|
@@ -1639,6 +1653,9 @@ function validateRequestOptions(options, name) {
|
|
|
1639
1653
|
function validateSummaryRequestOptions(options) {
|
|
1640
1654
|
const candidate = object3(options);
|
|
1641
1655
|
if (candidate === void 0) throw new ValidationError("summary request options must be an object");
|
|
1656
|
+
if (candidate.includeRawXml !== void 0) {
|
|
1657
|
+
throw new ValidationError("includeRawXml is not supported for summary requests");
|
|
1658
|
+
}
|
|
1642
1659
|
if (candidate.includeLinkOuts !== void 0) {
|
|
1643
1660
|
throw new ValidationError("includeLinkOuts is not supported for summary requests");
|
|
1644
1661
|
}
|
|
@@ -1771,7 +1788,7 @@ function validateSearchState(state, expectedIds, offset = 0) {
|
|
|
1771
1788
|
}
|
|
1772
1789
|
}
|
|
1773
1790
|
function parseExpectedFetch(body, expectedPmids) {
|
|
1774
|
-
const parsed = parsePubMedXml(body);
|
|
1791
|
+
const parsed = parsePubMedXml(body, { includeRawXml: true });
|
|
1775
1792
|
const expected = new Set(expectedPmids);
|
|
1776
1793
|
const seen = /* @__PURE__ */ new Set();
|
|
1777
1794
|
for (const record of parsed.records) {
|
|
@@ -1852,11 +1869,16 @@ function withLinks(record, extra) {
|
|
|
1852
1869
|
var PubMedClient = class {
|
|
1853
1870
|
#transport;
|
|
1854
1871
|
#maxBatchSize;
|
|
1872
|
+
#includeRawXml;
|
|
1855
1873
|
#totalDriftPolicy;
|
|
1856
1874
|
#onEvent;
|
|
1857
1875
|
constructor(options) {
|
|
1858
1876
|
if (typeof options !== "object" || options === null) throw new ValidationError("PubMedClient options are required");
|
|
1859
1877
|
validateAdapterShapes(options);
|
|
1878
|
+
if (options.includeRawXml !== void 0 && typeof options.includeRawXml !== "boolean") {
|
|
1879
|
+
throw new ValidationError("includeRawXml must be a boolean");
|
|
1880
|
+
}
|
|
1881
|
+
this.#includeRawXml = options.includeRawXml ?? false;
|
|
1860
1882
|
if (options.totalDriftPolicy !== void 0 && options.totalDriftPolicy !== "error" && options.totalDriftPolicy !== "warn") {
|
|
1861
1883
|
throw new ValidationError('totalDriftPolicy must be "error" or "warn"');
|
|
1862
1884
|
}
|
|
@@ -1923,6 +1945,9 @@ var PubMedClient = class {
|
|
|
1923
1945
|
}
|
|
1924
1946
|
let ordered = input.flatMap((pmid) => byPmid.get(pmid) ?? []);
|
|
1925
1947
|
if (unknown.length > 0) ordered = [...ordered, ...unknown];
|
|
1948
|
+
if (!(options.includeRawXml ?? this.#includeRawXml)) {
|
|
1949
|
+
ordered = ordered.map(({ rawXml, ...record }) => record);
|
|
1950
|
+
}
|
|
1926
1951
|
if (options.includeLinkOuts === true && ordered.length > 0) ordered = await this.#enrich(ordered, options.signal);
|
|
1927
1952
|
if (options.signal?.aborted) throw new AbortedError();
|
|
1928
1953
|
return {
|
|
@@ -1964,7 +1989,7 @@ var PubMedClient = class {
|
|
|
1964
1989
|
validateRequestOptions(options, "search options");
|
|
1965
1990
|
if ("cursor" in options) {
|
|
1966
1991
|
if (typeof options.cursor !== "string" || options.cursor === "") throw new ValidationError("cursor must be a non-empty string");
|
|
1967
|
-
return (await this.#searchCursorPage(options.cursor, options
|
|
1992
|
+
return (await this.#searchCursorPage(options.cursor, options)).batch;
|
|
1968
1993
|
}
|
|
1969
1994
|
validateQueryOptions(options);
|
|
1970
1995
|
return (await this.#searchQueryPage(options)).batch;
|
|
@@ -1980,6 +2005,7 @@ var PubMedClient = class {
|
|
|
1980
2005
|
query: options.query,
|
|
1981
2006
|
pageSize,
|
|
1982
2007
|
...options.sort === void 0 ? {} : { sort: options.sort },
|
|
2008
|
+
...options.includeRawXml === void 0 ? {} : { includeRawXml: options.includeRawXml },
|
|
1983
2009
|
...options.includeLinkOuts === void 0 ? {} : { includeLinkOuts: options.includeLinkOuts },
|
|
1984
2010
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
1985
2011
|
};
|
|
@@ -1996,8 +2022,7 @@ var PubMedClient = class {
|
|
|
1996
2022
|
if (page.batch.nextCursor === null) throw new InvalidResponseError("PubMed search ended before the requested result count");
|
|
1997
2023
|
page = await this.#searchCursorPage(
|
|
1998
2024
|
page.batch.nextCursor,
|
|
1999
|
-
options
|
|
2000
|
-
options.signal,
|
|
2025
|
+
options,
|
|
2001
2026
|
target - processed
|
|
2002
2027
|
);
|
|
2003
2028
|
}
|
|
@@ -2037,10 +2062,7 @@ var PubMedClient = class {
|
|
|
2037
2062
|
expectedPmids: []
|
|
2038
2063
|
};
|
|
2039
2064
|
}
|
|
2040
|
-
const batch = await this.getMany(state.ids,
|
|
2041
|
-
...options.includeLinkOuts === void 0 ? {} : { includeLinkOuts: options.includeLinkOuts },
|
|
2042
|
-
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
2043
|
-
});
|
|
2065
|
+
const batch = await this.getMany(state.ids, options);
|
|
2044
2066
|
const offset = state.ids.length;
|
|
2045
2067
|
return {
|
|
2046
2068
|
batch: {
|
|
@@ -2051,7 +2073,8 @@ var PubMedClient = class {
|
|
|
2051
2073
|
expectedPmids: state.ids
|
|
2052
2074
|
};
|
|
2053
2075
|
}
|
|
2054
|
-
async #searchCursorPage(cursorValue,
|
|
2076
|
+
async #searchCursorPage(cursorValue, options, maxExpected) {
|
|
2077
|
+
const { signal } = options;
|
|
2055
2078
|
const cursor = decodeCursor(cursorValue);
|
|
2056
2079
|
if (cursor.offset >= SEARCH_WINDOW) throw new SearchLimitError();
|
|
2057
2080
|
const remainingWindow = SEARCH_WINDOW - cursor.offset;
|
|
@@ -2090,7 +2113,7 @@ var PubMedClient = class {
|
|
|
2090
2113
|
{ cache: false, ...signal === void 0 ? {} : { signal } }
|
|
2091
2114
|
);
|
|
2092
2115
|
if (diagnostic !== void 0) safeEvent(this.#onEvent, { type: "search-total-drift", ...diagnostic });
|
|
2093
|
-
const batch = await this.getMany(state.ids,
|
|
2116
|
+
const batch = await this.getMany(state.ids, options);
|
|
2094
2117
|
const offset = cursor.offset + state.ids.length;
|
|
2095
2118
|
return {
|
|
2096
2119
|
batch: {
|