@debriefer/sources 1.0.1
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 +59 -0
- package/dist/__tests__/archives/chronicling-america.test.d.ts +8 -0
- package/dist/__tests__/archives/chronicling-america.test.d.ts.map +1 -0
- package/dist/__tests__/archives/chronicling-america.test.js +151 -0
- package/dist/__tests__/archives/chronicling-america.test.js.map +1 -0
- package/dist/__tests__/archives/europeana.test.d.ts +8 -0
- package/dist/__tests__/archives/europeana.test.d.ts.map +1 -0
- package/dist/__tests__/archives/europeana.test.js +200 -0
- package/dist/__tests__/archives/europeana.test.js.map +1 -0
- package/dist/__tests__/archives/internet-archive.test.d.ts +8 -0
- package/dist/__tests__/archives/internet-archive.test.d.ts.map +1 -0
- package/dist/__tests__/archives/internet-archive.test.js +189 -0
- package/dist/__tests__/archives/internet-archive.test.js.map +1 -0
- package/dist/__tests__/archives/trove.test.d.ts +8 -0
- package/dist/__tests__/archives/trove.test.d.ts.map +1 -0
- package/dist/__tests__/archives/trove.test.js +202 -0
- package/dist/__tests__/archives/trove.test.js.map +1 -0
- package/dist/__tests__/books/google-books.test.d.ts +8 -0
- package/dist/__tests__/books/google-books.test.d.ts.map +1 -0
- package/dist/__tests__/books/google-books.test.js +221 -0
- package/dist/__tests__/books/google-books.test.js.map +1 -0
- package/dist/__tests__/books/open-library.test.d.ts +8 -0
- package/dist/__tests__/books/open-library.test.d.ts.map +1 -0
- package/dist/__tests__/books/open-library.test.js +159 -0
- package/dist/__tests__/books/open-library.test.js.map +1 -0
- package/dist/__tests__/news/guardian.test.d.ts +9 -0
- package/dist/__tests__/news/guardian.test.d.ts.map +1 -0
- package/dist/__tests__/news/guardian.test.js +224 -0
- package/dist/__tests__/news/guardian.test.js.map +1 -0
- package/dist/__tests__/news/nytimes.test.d.ts +9 -0
- package/dist/__tests__/news/nytimes.test.d.ts.map +1 -0
- package/dist/__tests__/news/nytimes.test.js +271 -0
- package/dist/__tests__/news/nytimes.test.js.map +1 -0
- package/dist/__tests__/news/site-search-source.test.d.ts +9 -0
- package/dist/__tests__/news/site-search-source.test.d.ts.map +1 -0
- package/dist/__tests__/news/site-search-source.test.js +342 -0
- package/dist/__tests__/news/site-search-source.test.js.map +1 -0
- package/dist/__tests__/obituary/find-a-grave.test.d.ts +8 -0
- package/dist/__tests__/obituary/find-a-grave.test.d.ts.map +1 -0
- package/dist/__tests__/obituary/find-a-grave.test.js +238 -0
- package/dist/__tests__/obituary/find-a-grave.test.js.map +1 -0
- package/dist/__tests__/shared/duckduckgo-search.test.d.ts +9 -0
- package/dist/__tests__/shared/duckduckgo-search.test.d.ts.map +1 -0
- package/dist/__tests__/shared/duckduckgo-search.test.js +218 -0
- package/dist/__tests__/shared/duckduckgo-search.test.js.map +1 -0
- package/dist/__tests__/shared/fetch-page.test.d.ts +9 -0
- package/dist/__tests__/shared/fetch-page.test.d.ts.map +1 -0
- package/dist/__tests__/shared/fetch-page.test.js +281 -0
- package/dist/__tests__/shared/fetch-page.test.js.map +1 -0
- package/dist/__tests__/shared/html-utils.test.d.ts +2 -0
- package/dist/__tests__/shared/html-utils.test.d.ts.map +1 -0
- package/dist/__tests__/shared/html-utils.test.js +169 -0
- package/dist/__tests__/shared/html-utils.test.js.map +1 -0
- package/dist/__tests__/shared/readability-extract.test.d.ts +2 -0
- package/dist/__tests__/shared/readability-extract.test.d.ts.map +1 -0
- package/dist/__tests__/shared/readability-extract.test.js +107 -0
- package/dist/__tests__/shared/readability-extract.test.js.map +1 -0
- package/dist/__tests__/shared/sanitize-text.test.d.ts +2 -0
- package/dist/__tests__/shared/sanitize-text.test.d.ts.map +1 -0
- package/dist/__tests__/shared/sanitize-text.test.js +77 -0
- package/dist/__tests__/shared/sanitize-text.test.js.map +1 -0
- package/dist/__tests__/shared/search-utils.test.d.ts +2 -0
- package/dist/__tests__/shared/search-utils.test.d.ts.map +1 -0
- package/dist/__tests__/shared/search-utils.test.js +26 -0
- package/dist/__tests__/shared/search-utils.test.js.map +1 -0
- package/dist/__tests__/structured/wikidata.test.d.ts +9 -0
- package/dist/__tests__/structured/wikidata.test.d.ts.map +1 -0
- package/dist/__tests__/structured/wikidata.test.js +509 -0
- package/dist/__tests__/structured/wikidata.test.js.map +1 -0
- package/dist/__tests__/structured/wikipedia.test.d.ts +9 -0
- package/dist/__tests__/structured/wikipedia.test.d.ts.map +1 -0
- package/dist/__tests__/structured/wikipedia.test.js +643 -0
- package/dist/__tests__/structured/wikipedia.test.js.map +1 -0
- package/dist/__tests__/web-search/base.test.d.ts +9 -0
- package/dist/__tests__/web-search/base.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/base.test.js +622 -0
- package/dist/__tests__/web-search/base.test.js.map +1 -0
- package/dist/__tests__/web-search/bing.test.d.ts +10 -0
- package/dist/__tests__/web-search/bing.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/bing.test.js +277 -0
- package/dist/__tests__/web-search/bing.test.js.map +1 -0
- package/dist/__tests__/web-search/brave.test.d.ts +10 -0
- package/dist/__tests__/web-search/brave.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/brave.test.js +264 -0
- package/dist/__tests__/web-search/brave.test.js.map +1 -0
- package/dist/__tests__/web-search/duckduckgo.test.d.ts +10 -0
- package/dist/__tests__/web-search/duckduckgo.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/duckduckgo.test.js +107 -0
- package/dist/__tests__/web-search/duckduckgo.test.js.map +1 -0
- package/dist/__tests__/web-search/google.test.d.ts +9 -0
- package/dist/__tests__/web-search/google.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/google.test.js +189 -0
- package/dist/__tests__/web-search/google.test.js.map +1 -0
- package/dist/archives/chronicling-america.d.ts +33 -0
- package/dist/archives/chronicling-america.d.ts.map +1 -0
- package/dist/archives/chronicling-america.js +85 -0
- package/dist/archives/chronicling-america.js.map +1 -0
- package/dist/archives/europeana.d.ts +37 -0
- package/dist/archives/europeana.d.ts.map +1 -0
- package/dist/archives/europeana.js +92 -0
- package/dist/archives/europeana.js.map +1 -0
- package/dist/archives/internet-archive.d.ts +32 -0
- package/dist/archives/internet-archive.d.ts.map +1 -0
- package/dist/archives/internet-archive.js +90 -0
- package/dist/archives/internet-archive.js.map +1 -0
- package/dist/archives/trove.d.ts +37 -0
- package/dist/archives/trove.d.ts.map +1 -0
- package/dist/archives/trove.js +97 -0
- package/dist/archives/trove.js.map +1 -0
- package/dist/books/google-books.d.ts +48 -0
- package/dist/books/google-books.d.ts.map +1 -0
- package/dist/books/google-books.js +111 -0
- package/dist/books/google-books.js.map +1 -0
- package/dist/books/open-library.d.ts +44 -0
- package/dist/books/open-library.d.ts.map +1 -0
- package/dist/books/open-library.js +103 -0
- package/dist/books/open-library.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/news/guardian.d.ts +51 -0
- package/dist/news/guardian.d.ts.map +1 -0
- package/dist/news/guardian.js +131 -0
- package/dist/news/guardian.js.map +1 -0
- package/dist/news/nytimes.d.ts +27 -0
- package/dist/news/nytimes.d.ts.map +1 -0
- package/dist/news/nytimes.js +104 -0
- package/dist/news/nytimes.js.map +1 -0
- package/dist/news/site-search-source.d.ts +89 -0
- package/dist/news/site-search-source.d.ts.map +1 -0
- package/dist/news/site-search-source.js +182 -0
- package/dist/news/site-search-source.js.map +1 -0
- package/dist/news/sources.d.ts +52 -0
- package/dist/news/sources.d.ts.map +1 -0
- package/dist/news/sources.js +276 -0
- package/dist/news/sources.js.map +1 -0
- package/dist/obituary/find-a-grave.d.ts +43 -0
- package/dist/obituary/find-a-grave.d.ts.map +1 -0
- package/dist/obituary/find-a-grave.js +173 -0
- package/dist/obituary/find-a-grave.js.map +1 -0
- package/dist/shared/duckduckgo-search.d.ts +86 -0
- package/dist/shared/duckduckgo-search.d.ts.map +1 -0
- package/dist/shared/duckduckgo-search.js +218 -0
- package/dist/shared/duckduckgo-search.js.map +1 -0
- package/dist/shared/fetch-page.d.ts +50 -0
- package/dist/shared/fetch-page.d.ts.map +1 -0
- package/dist/shared/fetch-page.js +212 -0
- package/dist/shared/fetch-page.js.map +1 -0
- package/dist/shared/html-utils.d.ts +99 -0
- package/dist/shared/html-utils.d.ts.map +1 -0
- package/dist/shared/html-utils.js +246 -0
- package/dist/shared/html-utils.js.map +1 -0
- package/dist/shared/readability-extract.d.ts +33 -0
- package/dist/shared/readability-extract.d.ts.map +1 -0
- package/dist/shared/readability-extract.js +45 -0
- package/dist/shared/readability-extract.js.map +1 -0
- package/dist/shared/sanitize-text.d.ts +24 -0
- package/dist/shared/sanitize-text.d.ts.map +1 -0
- package/dist/shared/sanitize-text.js +49 -0
- package/dist/shared/sanitize-text.js.map +1 -0
- package/dist/shared/search-utils.d.ts +18 -0
- package/dist/shared/search-utils.d.ts.map +1 -0
- package/dist/shared/search-utils.js +20 -0
- package/dist/shared/search-utils.js.map +1 -0
- package/dist/structured/wikidata.d.ts +128 -0
- package/dist/structured/wikidata.d.ts.map +1 -0
- package/dist/structured/wikidata.js +361 -0
- package/dist/structured/wikidata.js.map +1 -0
- package/dist/structured/wikipedia.d.ts +184 -0
- package/dist/structured/wikipedia.d.ts.map +1 -0
- package/dist/structured/wikipedia.js +275 -0
- package/dist/structured/wikipedia.js.map +1 -0
- package/dist/web-search/base.d.ts +128 -0
- package/dist/web-search/base.d.ts.map +1 -0
- package/dist/web-search/base.js +251 -0
- package/dist/web-search/base.js.map +1 -0
- package/dist/web-search/bing.d.ts +21 -0
- package/dist/web-search/bing.d.ts.map +1 -0
- package/dist/web-search/bing.js +53 -0
- package/dist/web-search/bing.js.map +1 -0
- package/dist/web-search/brave.d.ts +21 -0
- package/dist/web-search/brave.d.ts.map +1 -0
- package/dist/web-search/brave.js +56 -0
- package/dist/web-search/brave.js.map +1 -0
- package/dist/web-search/duckduckgo.d.ts +15 -0
- package/dist/web-search/duckduckgo.d.ts.map +1 -0
- package/dist/web-search/duckduckgo.js +21 -0
- package/dist/web-search/duckduckgo.js.map +1 -0
- package/dist/web-search/google.d.ts +24 -0
- package/dist/web-search/google.d.ts.map +1 -0
- package/dist/web-search/google.js +48 -0
- package/dist/web-search/google.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"europeana.js","sourceRoot":"","sources":["../../src/archives/europeana.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internet Archive source.
|
|
3
|
+
*
|
|
4
|
+
* Queries the Internet Archive advanced search API for books, documents,
|
|
5
|
+
* and media about a research subject. No authentication required.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
|
|
8
|
+
export type InternetArchiveOptions = BaseSourceOptions;
|
|
9
|
+
/**
|
|
10
|
+
* Research source backed by the Internet Archive advanced search API.
|
|
11
|
+
*
|
|
12
|
+
* Searches for books, documents, and media about a subject.
|
|
13
|
+
* Free, no API key required.
|
|
14
|
+
*/
|
|
15
|
+
export declare class InternetArchiveSource extends BaseResearchSource<ResearchSubject> {
|
|
16
|
+
readonly name = "Internet Archive";
|
|
17
|
+
readonly type = "internet-archive";
|
|
18
|
+
readonly reliabilityTier = ReliabilityTier.ARCHIVE_MIRROR;
|
|
19
|
+
readonly domain = "archive.org";
|
|
20
|
+
readonly isFree = true;
|
|
21
|
+
readonly estimatedCostPerQuery = 0;
|
|
22
|
+
constructor(options?: InternetArchiveOptions);
|
|
23
|
+
protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create an Internet Archive source instance.
|
|
27
|
+
*
|
|
28
|
+
* @param options - Source options (rateLimitMs, etc.)
|
|
29
|
+
* @returns A configured InternetArchiveSource
|
|
30
|
+
*/
|
|
31
|
+
export declare function internetArchive(options?: InternetArchiveOptions): InternetArchiveSource;
|
|
32
|
+
//# sourceMappingURL=internet-archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internet-archive.d.ts","sourceRoot":"","sources":["../../src/archives/internet-archive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAcxB,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAA;AAqBtD;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IAC5E,QAAQ,CAAC,IAAI,sBAAqB;IAClC,QAAQ,CAAC,IAAI,sBAAqB;IAClC,QAAQ,CAAC,eAAe,kCAAiC;IACzD,QAAQ,CAAC,MAAM,iBAAgB;IAC/B,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;gBAEtB,OAAO,GAAE,sBAA2B;cAIhC,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAgD9B;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,qBAAqB,CAEvF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internet Archive source.
|
|
3
|
+
*
|
|
4
|
+
* Queries the Internet Archive advanced search API for books, documents,
|
|
5
|
+
* and media about a research subject. No authentication required.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
|
|
8
|
+
import { sanitizeSourceText } from "../shared/sanitize-text.js";
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Constants
|
|
11
|
+
// ============================================================================
|
|
12
|
+
const IA_API_URL = "https://archive.org/advancedsearch.php";
|
|
13
|
+
const IA_DETAILS_BASE = "https://archive.org/details/";
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// InternetArchiveSource
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Research source backed by the Internet Archive advanced search API.
|
|
19
|
+
*
|
|
20
|
+
* Searches for books, documents, and media about a subject.
|
|
21
|
+
* Free, no API key required.
|
|
22
|
+
*/
|
|
23
|
+
export class InternetArchiveSource extends BaseResearchSource {
|
|
24
|
+
name = "Internet Archive";
|
|
25
|
+
type = "internet-archive";
|
|
26
|
+
reliabilityTier = ReliabilityTier.ARCHIVE_MIRROR;
|
|
27
|
+
domain = "archive.org";
|
|
28
|
+
isFree = true;
|
|
29
|
+
estimatedCostPerQuery = 0;
|
|
30
|
+
constructor(options = {}) {
|
|
31
|
+
super({ rateLimitMs: 1000, ...options });
|
|
32
|
+
}
|
|
33
|
+
async fetchResult(subject, signal) {
|
|
34
|
+
const url = new URL(IA_API_URL);
|
|
35
|
+
url.searchParams.set("q", `"${subject.name}" AND (biography OR memoir)`);
|
|
36
|
+
url.searchParams.append("fl[]", "identifier");
|
|
37
|
+
url.searchParams.append("fl[]", "title");
|
|
38
|
+
url.searchParams.append("fl[]", "description");
|
|
39
|
+
url.searchParams.append("fl[]", "creator");
|
|
40
|
+
url.searchParams.append("sort[]", "downloads desc");
|
|
41
|
+
url.searchParams.set("rows", "5");
|
|
42
|
+
url.searchParams.set("output", "json");
|
|
43
|
+
const response = await fetch(url.toString(), { signal });
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`Internet Archive API error: HTTP ${response.status} ${response.statusText}`);
|
|
46
|
+
}
|
|
47
|
+
const data = (await response.json());
|
|
48
|
+
if (!data.response?.docs?.length)
|
|
49
|
+
return null;
|
|
50
|
+
// Combine title + description from all docs
|
|
51
|
+
const parts = [];
|
|
52
|
+
for (const doc of data.response.docs) {
|
|
53
|
+
if (doc.title)
|
|
54
|
+
parts.push(doc.title);
|
|
55
|
+
if (doc.description)
|
|
56
|
+
parts.push(doc.description);
|
|
57
|
+
}
|
|
58
|
+
const text = parts.join("\n\n");
|
|
59
|
+
if (!text.trim())
|
|
60
|
+
return null;
|
|
61
|
+
const sanitized = sanitizeSourceText(text);
|
|
62
|
+
if (!sanitized)
|
|
63
|
+
return null;
|
|
64
|
+
const firstDoc = data.response.docs[0];
|
|
65
|
+
const resultUrl = firstDoc?.identifier ? `${IA_DETAILS_BASE}${firstDoc.identifier}` : undefined;
|
|
66
|
+
return {
|
|
67
|
+
text: sanitized,
|
|
68
|
+
confidence: -1,
|
|
69
|
+
costUsd: 0,
|
|
70
|
+
url: resultUrl,
|
|
71
|
+
publication: "Internet Archive",
|
|
72
|
+
metadata: {
|
|
73
|
+
title: firstDoc?.title ?? "",
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// ============================================================================
|
|
79
|
+
// Factory
|
|
80
|
+
// ============================================================================
|
|
81
|
+
/**
|
|
82
|
+
* Create an Internet Archive source instance.
|
|
83
|
+
*
|
|
84
|
+
* @param options - Source options (rateLimitMs, etc.)
|
|
85
|
+
* @returns A configured InternetArchiveSource
|
|
86
|
+
*/
|
|
87
|
+
export function internetArchive(options) {
|
|
88
|
+
return new InternetArchiveSource(options);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=internet-archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internet-archive.js","sourceRoot":"","sources":["../../src/archives/internet-archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trove (National Library of Australia) source.
|
|
3
|
+
*
|
|
4
|
+
* Queries the Trove API v3 for newspaper articles about a research subject.
|
|
5
|
+
* Requires a free API key from the National Library of Australia.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
|
|
8
|
+
export interface TroveOptions extends BaseSourceOptions {
|
|
9
|
+
/** Trove API key. Defaults to process.env.TROVE_API_KEY. */
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Research source backed by the Trove API (National Library of Australia).
|
|
14
|
+
*
|
|
15
|
+
* Searches digitized Australian newspapers for biographical content
|
|
16
|
+
* about a subject. Requires a free API key.
|
|
17
|
+
*/
|
|
18
|
+
export declare class TroveSource extends BaseResearchSource<ResearchSubject> {
|
|
19
|
+
readonly name = "Trove";
|
|
20
|
+
readonly type = "trove";
|
|
21
|
+
readonly reliabilityTier = ReliabilityTier.ARCHIVAL;
|
|
22
|
+
readonly domain = "api.trove.nla.gov.au";
|
|
23
|
+
readonly isFree = true;
|
|
24
|
+
readonly estimatedCostPerQuery = 0;
|
|
25
|
+
private apiKey;
|
|
26
|
+
constructor(options?: TroveOptions);
|
|
27
|
+
isAvailable(): boolean;
|
|
28
|
+
protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create a Trove source instance.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Trove-specific options (apiKey, rateLimitMs, etc.)
|
|
34
|
+
* @returns A configured TroveSource
|
|
35
|
+
*/
|
|
36
|
+
export declare function trove(options?: TroveOptions): TroveSource;
|
|
37
|
+
//# sourceMappingURL=trove.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trove.d.ts","sourceRoot":"","sources":["../../src/archives/trove.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAaxB,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AA0BD;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IAClE,QAAQ,CAAC,IAAI,WAAU;IACvB,QAAQ,CAAC,IAAI,WAAU;IACvB,QAAQ,CAAC,eAAe,4BAA2B;IACnD,QAAQ,CAAC,MAAM,0BAAyB;IACxC,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;IAElC,OAAO,CAAC,MAAM,CAAoB;gBAEtB,OAAO,GAAE,YAAiB;IAK7B,WAAW,IAAI,OAAO;cAIf,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAmD9B;AAMD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAEzD"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trove (National Library of Australia) source.
|
|
3
|
+
*
|
|
4
|
+
* Queries the Trove API v3 for newspaper articles about a research subject.
|
|
5
|
+
* Requires a free API key from the National Library of Australia.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
|
|
8
|
+
import { sanitizeSourceText } from "../shared/sanitize-text.js";
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Constants
|
|
11
|
+
// ============================================================================
|
|
12
|
+
const TROVE_API_URL = "https://api.trove.nla.gov.au/v3/result";
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// TroveSource
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Research source backed by the Trove API (National Library of Australia).
|
|
18
|
+
*
|
|
19
|
+
* Searches digitized Australian newspapers for biographical content
|
|
20
|
+
* about a subject. Requires a free API key.
|
|
21
|
+
*/
|
|
22
|
+
export class TroveSource extends BaseResearchSource {
|
|
23
|
+
name = "Trove";
|
|
24
|
+
type = "trove";
|
|
25
|
+
reliabilityTier = ReliabilityTier.ARCHIVAL;
|
|
26
|
+
domain = "api.trove.nla.gov.au";
|
|
27
|
+
isFree = true;
|
|
28
|
+
estimatedCostPerQuery = 0;
|
|
29
|
+
apiKey;
|
|
30
|
+
constructor(options = {}) {
|
|
31
|
+
super({ rateLimitMs: 1000, ...options });
|
|
32
|
+
this.apiKey = options.apiKey ?? process.env.TROVE_API_KEY;
|
|
33
|
+
}
|
|
34
|
+
isAvailable() {
|
|
35
|
+
return Boolean(this.apiKey);
|
|
36
|
+
}
|
|
37
|
+
async fetchResult(subject, signal) {
|
|
38
|
+
if (!this.apiKey)
|
|
39
|
+
return null;
|
|
40
|
+
const url = new URL(TROVE_API_URL);
|
|
41
|
+
url.searchParams.set("key", this.apiKey);
|
|
42
|
+
url.searchParams.set("q", `"${subject.name}" biography`);
|
|
43
|
+
url.searchParams.set("category", "newspaper");
|
|
44
|
+
url.searchParams.set("encoding", "json");
|
|
45
|
+
url.searchParams.set("n", "5");
|
|
46
|
+
const response = await fetch(url.toString(), { signal });
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw new Error(`Trove API error: HTTP ${response.status} ${response.statusText}`);
|
|
49
|
+
}
|
|
50
|
+
const data = (await response.json());
|
|
51
|
+
const articles = data.category?.[0]?.records?.article;
|
|
52
|
+
if (!articles?.length)
|
|
53
|
+
return null;
|
|
54
|
+
// Combine heading + cleaned snippet from all articles
|
|
55
|
+
const parts = [];
|
|
56
|
+
for (const article of articles) {
|
|
57
|
+
if (article.heading)
|
|
58
|
+
parts.push(article.heading);
|
|
59
|
+
if (article.snippet) {
|
|
60
|
+
// Strip HTML tags from snippets
|
|
61
|
+
const cleaned = article.snippet.replace(/<[^>]+>/g, "");
|
|
62
|
+
if (cleaned.trim())
|
|
63
|
+
parts.push(cleaned);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const text = parts.join("\n\n");
|
|
67
|
+
if (!text.trim())
|
|
68
|
+
return null;
|
|
69
|
+
const sanitized = sanitizeSourceText(text);
|
|
70
|
+
if (!sanitized)
|
|
71
|
+
return null;
|
|
72
|
+
const firstWithUrl = articles.find((a) => a.troveUrl);
|
|
73
|
+
return {
|
|
74
|
+
text: sanitized,
|
|
75
|
+
confidence: -1,
|
|
76
|
+
costUsd: 0,
|
|
77
|
+
url: firstWithUrl?.troveUrl,
|
|
78
|
+
publication: "Trove (National Library of Australia)",
|
|
79
|
+
metadata: {
|
|
80
|
+
title: articles[0]?.heading ?? "",
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// Factory
|
|
87
|
+
// ============================================================================
|
|
88
|
+
/**
|
|
89
|
+
* Create a Trove source instance.
|
|
90
|
+
*
|
|
91
|
+
* @param options - Trove-specific options (apiKey, rateLimitMs, etc.)
|
|
92
|
+
* @returns A configured TroveSource
|
|
93
|
+
*/
|
|
94
|
+
export function trove(options) {
|
|
95
|
+
return new TroveSource(options);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=trove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trove.js","sourceRoot":"","sources":["../../src/archives/trove.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Books API source.
|
|
3
|
+
*
|
|
4
|
+
* Searches Google Books for volumes matching the research subject,
|
|
5
|
+
* extracts text snippets and descriptions, and returns the best
|
|
6
|
+
* match as a finding.
|
|
7
|
+
*
|
|
8
|
+
* Requires a Google Books API key (https://developers.google.com/books).
|
|
9
|
+
*/
|
|
10
|
+
import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
|
|
11
|
+
export interface GoogleBooksOptions extends BaseSourceOptions {
|
|
12
|
+
/** Google Books API key. Defaults to process.env.GOOGLE_BOOKS_API_KEY. */
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Research source backed by the Google Books API.
|
|
17
|
+
*
|
|
18
|
+
* Searches for volumes about a subject, picks the first item with
|
|
19
|
+
* enough combined text (snippet + description), and returns the
|
|
20
|
+
* sanitized result.
|
|
21
|
+
*/
|
|
22
|
+
export declare class GoogleBooksSource extends BaseResearchSource<ResearchSubject> {
|
|
23
|
+
readonly name = "Google Books";
|
|
24
|
+
readonly type = "google-books";
|
|
25
|
+
readonly reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
|
|
26
|
+
readonly domain = "www.googleapis.com";
|
|
27
|
+
readonly isFree = true;
|
|
28
|
+
readonly estimatedCostPerQuery = 0;
|
|
29
|
+
private apiKey;
|
|
30
|
+
constructor(options?: GoogleBooksOptions);
|
|
31
|
+
isAvailable(): boolean;
|
|
32
|
+
protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Extract and combine text from a Google Books volume.
|
|
35
|
+
*
|
|
36
|
+
* Combines the text snippet (with HTML tags stripped and entities decoded)
|
|
37
|
+
* and the description into a single string.
|
|
38
|
+
*/
|
|
39
|
+
private extractText;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a Google Books API source instance.
|
|
43
|
+
*
|
|
44
|
+
* @param options - Google Books-specific options (apiKey, rateLimitMs, etc.)
|
|
45
|
+
* @returns A configured GoogleBooksSource
|
|
46
|
+
*/
|
|
47
|
+
export declare function googleBooks(options?: GoogleBooksOptions): GoogleBooksSource;
|
|
48
|
+
//# sourceMappingURL=google-books.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-books.d.ts","sourceRoot":"","sources":["../../src/books/google-books.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAcxB,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AA0BD;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IACxE,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,eAAe,yCAAwC;IAChE,QAAQ,CAAC,MAAM,wBAAuB;IACtC,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;IAElC,OAAO,CAAC,MAAM,CAAoB;gBAEtB,OAAO,GAAE,kBAAuB;IAKnC,WAAW,IAAI,OAAO;cAIf,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA6C7B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;CAepB;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CAE3E"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Books API source.
|
|
3
|
+
*
|
|
4
|
+
* Searches Google Books for volumes matching the research subject,
|
|
5
|
+
* extracts text snippets and descriptions, and returns the best
|
|
6
|
+
* match as a finding.
|
|
7
|
+
*
|
|
8
|
+
* Requires a Google Books API key (https://developers.google.com/books).
|
|
9
|
+
*/
|
|
10
|
+
import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
|
|
11
|
+
import { decodeHtmlEntities } from "../shared/html-utils.js";
|
|
12
|
+
import { sanitizeSourceText } from "../shared/sanitize-text.js";
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
const GOOGLE_BOOKS_API_URL = "https://www.googleapis.com/books/v1/volumes";
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// GoogleBooksSource
|
|
19
|
+
// ============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Research source backed by the Google Books API.
|
|
22
|
+
*
|
|
23
|
+
* Searches for volumes about a subject, picks the first item with
|
|
24
|
+
* enough combined text (snippet + description), and returns the
|
|
25
|
+
* sanitized result.
|
|
26
|
+
*/
|
|
27
|
+
export class GoogleBooksSource extends BaseResearchSource {
|
|
28
|
+
name = "Google Books";
|
|
29
|
+
type = "google-books";
|
|
30
|
+
reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
|
|
31
|
+
domain = "www.googleapis.com";
|
|
32
|
+
isFree = true;
|
|
33
|
+
estimatedCostPerQuery = 0;
|
|
34
|
+
apiKey;
|
|
35
|
+
constructor(options = {}) {
|
|
36
|
+
super({ rateLimitMs: 1000, ...options });
|
|
37
|
+
this.apiKey = options.apiKey ?? process.env.GOOGLE_BOOKS_API_KEY;
|
|
38
|
+
}
|
|
39
|
+
isAvailable() {
|
|
40
|
+
return Boolean(this.apiKey);
|
|
41
|
+
}
|
|
42
|
+
async fetchResult(subject, signal) {
|
|
43
|
+
if (!this.apiKey)
|
|
44
|
+
return null;
|
|
45
|
+
const query = `"${subject.name}" biography`;
|
|
46
|
+
const url = new URL(GOOGLE_BOOKS_API_URL);
|
|
47
|
+
url.searchParams.set("q", query);
|
|
48
|
+
url.searchParams.set("key", this.apiKey);
|
|
49
|
+
url.searchParams.set("maxResults", "5");
|
|
50
|
+
const response = await fetch(url.toString(), { signal });
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`Google Books API error: HTTP ${response.status} ${response.statusText}`);
|
|
53
|
+
}
|
|
54
|
+
const data = (await response.json());
|
|
55
|
+
if (!data.items?.length)
|
|
56
|
+
return null;
|
|
57
|
+
// Pick first item with enough combined text
|
|
58
|
+
for (const item of data.items) {
|
|
59
|
+
const combined = this.extractText(item);
|
|
60
|
+
if (combined.length >= 100) {
|
|
61
|
+
const sanitized = sanitizeSourceText(combined);
|
|
62
|
+
if (sanitized.length < 50)
|
|
63
|
+
continue;
|
|
64
|
+
return {
|
|
65
|
+
text: sanitized,
|
|
66
|
+
confidence: -1,
|
|
67
|
+
costUsd: 0,
|
|
68
|
+
url: item.volumeInfo.infoLink,
|
|
69
|
+
publication: "Google Books",
|
|
70
|
+
metadata: {
|
|
71
|
+
title: item.volumeInfo.title,
|
|
72
|
+
authors: item.volumeInfo.authors,
|
|
73
|
+
publishedDate: item.volumeInfo.publishedDate,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Extract and combine text from a Google Books volume.
|
|
82
|
+
*
|
|
83
|
+
* Combines the text snippet (with HTML tags stripped and entities decoded)
|
|
84
|
+
* and the description into a single string.
|
|
85
|
+
*/
|
|
86
|
+
extractText(item) {
|
|
87
|
+
const parts = [];
|
|
88
|
+
if (item.searchInfo?.textSnippet) {
|
|
89
|
+
// Strip <b> and other HTML tags, then decode entities
|
|
90
|
+
const stripped = item.searchInfo.textSnippet.replace(/<[^>]+>/g, "");
|
|
91
|
+
parts.push(decodeHtmlEntities(stripped));
|
|
92
|
+
}
|
|
93
|
+
if (item.volumeInfo.description) {
|
|
94
|
+
parts.push(item.volumeInfo.description);
|
|
95
|
+
}
|
|
96
|
+
return parts.join(" ").trim();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// Factory
|
|
101
|
+
// ============================================================================
|
|
102
|
+
/**
|
|
103
|
+
* Create a Google Books API source instance.
|
|
104
|
+
*
|
|
105
|
+
* @param options - Google Books-specific options (apiKey, rateLimitMs, etc.)
|
|
106
|
+
* @returns A configured GoogleBooksSource
|
|
107
|
+
*/
|
|
108
|
+
export function googleBooks(options) {
|
|
109
|
+
return new GoogleBooksSource(options);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=google-books.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-books.js","sourceRoot":"","sources":["../../src/books/google-books.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Library search source.
|
|
3
|
+
*
|
|
4
|
+
* Queries the Open Library Search API for books matching the research
|
|
5
|
+
* subject. Returns book metadata (title, authors, publication year)
|
|
6
|
+
* as a finding. No API key required.
|
|
7
|
+
*
|
|
8
|
+
* https://openlibrary.org/dev/docs/api/search
|
|
9
|
+
*/
|
|
10
|
+
import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
|
|
11
|
+
export type OpenLibraryOptions = BaseSourceOptions;
|
|
12
|
+
/**
|
|
13
|
+
* Research source backed by the Open Library Search API.
|
|
14
|
+
*
|
|
15
|
+
* Searches for books about a subject, picks the first result with
|
|
16
|
+
* a title, and returns a combined attribution string (including any
|
|
17
|
+
* available authors and publication year) as the finding text.
|
|
18
|
+
*/
|
|
19
|
+
export declare class OpenLibrarySource extends BaseResearchSource<ResearchSubject> {
|
|
20
|
+
readonly name = "Open Library";
|
|
21
|
+
readonly type = "open-library";
|
|
22
|
+
readonly reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
|
|
23
|
+
readonly domain = "openlibrary.org";
|
|
24
|
+
readonly isFree = true;
|
|
25
|
+
readonly estimatedCostPerQuery = 0;
|
|
26
|
+
constructor(options?: OpenLibraryOptions);
|
|
27
|
+
isAvailable(): boolean;
|
|
28
|
+
protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Build attribution text from an Open Library document.
|
|
31
|
+
*
|
|
32
|
+
* Combines title, author names, and publication year into a
|
|
33
|
+
* human-readable string.
|
|
34
|
+
*/
|
|
35
|
+
private buildText;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create an Open Library source instance.
|
|
39
|
+
*
|
|
40
|
+
* @param options - Open Library-specific options (rateLimitMs, etc.)
|
|
41
|
+
* @returns A configured OpenLibrarySource
|
|
42
|
+
*/
|
|
43
|
+
export declare function openLibrary(options?: OpenLibraryOptions): OpenLibrarySource;
|
|
44
|
+
//# sourceMappingURL=open-library.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-library.d.ts","sourceRoot":"","sources":["../../src/books/open-library.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAYxB,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAA;AAqBlD;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IACxE,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,eAAe,yCAAwC;IAChE,QAAQ,CAAC,MAAM,qBAAoB;IACnC,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;gBAEtB,OAAO,GAAE,kBAAuB;IAInC,WAAW,IAAI,OAAO;cAIf,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAwC7B;;;;;OAKG;IACH,OAAO,CAAC,SAAS;CAiBlB;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CAE3E"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Library search source.
|
|
3
|
+
*
|
|
4
|
+
* Queries the Open Library Search API for books matching the research
|
|
5
|
+
* subject. Returns book metadata (title, authors, publication year)
|
|
6
|
+
* as a finding. No API key required.
|
|
7
|
+
*
|
|
8
|
+
* https://openlibrary.org/dev/docs/api/search
|
|
9
|
+
*/
|
|
10
|
+
import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Constants
|
|
13
|
+
// ============================================================================
|
|
14
|
+
const OPEN_LIBRARY_SEARCH_URL = "https://openlibrary.org/search.json";
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// OpenLibrarySource
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Research source backed by the Open Library Search API.
|
|
20
|
+
*
|
|
21
|
+
* Searches for books about a subject, picks the first result with
|
|
22
|
+
* a title, and returns a combined attribution string (including any
|
|
23
|
+
* available authors and publication year) as the finding text.
|
|
24
|
+
*/
|
|
25
|
+
export class OpenLibrarySource extends BaseResearchSource {
|
|
26
|
+
name = "Open Library";
|
|
27
|
+
type = "open-library";
|
|
28
|
+
reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
|
|
29
|
+
domain = "openlibrary.org";
|
|
30
|
+
isFree = true;
|
|
31
|
+
estimatedCostPerQuery = 0;
|
|
32
|
+
constructor(options = {}) {
|
|
33
|
+
super({ rateLimitMs: 350, ...options });
|
|
34
|
+
}
|
|
35
|
+
isAvailable() {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
async fetchResult(subject, signal) {
|
|
39
|
+
const query = `"${subject.name}" biography`;
|
|
40
|
+
const url = new URL(OPEN_LIBRARY_SEARCH_URL);
|
|
41
|
+
url.searchParams.set("q", query);
|
|
42
|
+
url.searchParams.set("limit", "5");
|
|
43
|
+
const response = await fetch(url.toString(), { signal });
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`Open Library API error: HTTP ${response.status} ${response.statusText}`);
|
|
46
|
+
}
|
|
47
|
+
const data = (await response.json());
|
|
48
|
+
if (!data.docs?.length)
|
|
49
|
+
return null;
|
|
50
|
+
// Pick the first doc with a title
|
|
51
|
+
const doc = data.docs.find((d) => d.title);
|
|
52
|
+
if (!doc)
|
|
53
|
+
return null;
|
|
54
|
+
const text = this.buildText(doc);
|
|
55
|
+
if (!text)
|
|
56
|
+
return null;
|
|
57
|
+
const docUrl = doc.key ? `https://openlibrary.org${doc.key}` : undefined;
|
|
58
|
+
return {
|
|
59
|
+
text,
|
|
60
|
+
confidence: -1,
|
|
61
|
+
costUsd: 0,
|
|
62
|
+
url: docUrl,
|
|
63
|
+
publication: "Open Library",
|
|
64
|
+
metadata: {
|
|
65
|
+
title: doc.title,
|
|
66
|
+
authors: doc.author_name,
|
|
67
|
+
firstPublishYear: doc.first_publish_year,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Build attribution text from an Open Library document.
|
|
73
|
+
*
|
|
74
|
+
* Combines title, author names, and publication year into a
|
|
75
|
+
* human-readable string.
|
|
76
|
+
*/
|
|
77
|
+
buildText(doc) {
|
|
78
|
+
const parts = [];
|
|
79
|
+
if (doc.title) {
|
|
80
|
+
parts.push(doc.title);
|
|
81
|
+
}
|
|
82
|
+
if (doc.author_name?.length) {
|
|
83
|
+
parts.push(`by ${doc.author_name.join(", ")}`);
|
|
84
|
+
}
|
|
85
|
+
if (doc.first_publish_year) {
|
|
86
|
+
parts.push(`(${doc.first_publish_year})`);
|
|
87
|
+
}
|
|
88
|
+
return parts.length > 0 ? parts.join(" ") : null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// ============================================================================
|
|
92
|
+
// Factory
|
|
93
|
+
// ============================================================================
|
|
94
|
+
/**
|
|
95
|
+
* Create an Open Library source instance.
|
|
96
|
+
*
|
|
97
|
+
* @param options - Open Library-specific options (rateLimitMs, etc.)
|
|
98
|
+
* @returns A configured OpenLibrarySource
|
|
99
|
+
*/
|
|
100
|
+
export function openLibrary(options) {
|
|
101
|
+
return new OpenLibrarySource(options);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=open-library.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-library.js","sourceRoot":"","sources":["../../src/books/open-library.ts"],"names":[],"mappings":"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"}
|