@diffbot/typescript 0.1.0 → 0.2.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/README.md +142 -8
- package/dist/index.cjs +141 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +111 -6
- package/dist/index.d.ts +111 -6
- package/dist/index.js +141 -45
- package/dist/index.js.map +1 -1
- package/dist/node/index.cjs +93 -0
- package/dist/node/index.cjs.map +1 -0
- package/dist/node/index.d.cts +27 -0
- package/dist/node/index.d.ts +27 -0
- package/dist/node/index.js +63 -0
- package/dist/node/index.js.map +1 -0
- package/package.json +10 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
-
var VERSION = "0.
|
|
2
|
+
var VERSION = "0.2.0";
|
|
3
3
|
var DEFAULT_TIMEOUT = 3e4;
|
|
4
4
|
var EXTRACT_BASE = "https://api.diffbot.com/v3";
|
|
5
5
|
var CRAWL_BASE = "https://api.diffbot.com/v3/crawl";
|
|
@@ -140,6 +140,8 @@ var DiffbotClient = class {
|
|
|
140
140
|
crawlerUrl;
|
|
141
141
|
webSearchUrl;
|
|
142
142
|
nlpUrl;
|
|
143
|
+
dqlUrl;
|
|
144
|
+
ontologyUrl;
|
|
143
145
|
http;
|
|
144
146
|
constructor(options) {
|
|
145
147
|
if (!options.token) {
|
|
@@ -151,6 +153,8 @@ var DiffbotClient = class {
|
|
|
151
153
|
this.crawlerUrl = options.crawlerUrl ?? CRAWL_BASE;
|
|
152
154
|
this.webSearchUrl = options.webSearchUrl ?? WEB_SEARCH_BASE;
|
|
153
155
|
this.nlpUrl = options.nlpUrl ?? NLP_BASE;
|
|
156
|
+
this.dqlUrl = options.dqlUrl ?? KG_DQL_ENDPOINT;
|
|
157
|
+
this.ontologyUrl = options.ontologyUrl ?? KG_ONTOLOGY_ENDPOINT;
|
|
154
158
|
this.http = new HttpClient(
|
|
155
159
|
options.fetch ?? fetch,
|
|
156
160
|
options.timeout ?? DEFAULT_TIMEOUT,
|
|
@@ -166,34 +170,20 @@ var DiffbotClient = class {
|
|
|
166
170
|
};
|
|
167
171
|
|
|
168
172
|
// src/auth.ts
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return "";
|
|
178
|
-
}
|
|
179
|
-
const text = readFileSync(path, "utf8");
|
|
180
|
-
for (const line of text.split("\n")) {
|
|
181
|
-
const trimmed = line.trim();
|
|
182
|
-
if (trimmed.startsWith(`${TOKEN_ENV_VAR}=`)) {
|
|
183
|
-
return trimmed.slice(TOKEN_ENV_VAR.length + 1).trim();
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return "";
|
|
173
|
+
function envToken(env) {
|
|
174
|
+
const fromEnv = env?.[TOKEN_ENV_VAR];
|
|
175
|
+
if (typeof fromEnv === "string" && fromEnv.trim()) {
|
|
176
|
+
return fromEnv.trim();
|
|
177
|
+
}
|
|
178
|
+
const proc = globalThis.process;
|
|
179
|
+
const fromProcess = proc?.env?.[TOKEN_ENV_VAR];
|
|
180
|
+
return fromProcess?.trim() ?? "";
|
|
187
181
|
}
|
|
188
|
-
function
|
|
182
|
+
function resolveTokenFromEnv(token, env) {
|
|
189
183
|
if (token?.trim()) {
|
|
190
184
|
return token.trim();
|
|
191
185
|
}
|
|
192
|
-
|
|
193
|
-
if (envToken) {
|
|
194
|
-
return envToken;
|
|
195
|
-
}
|
|
196
|
-
return readCredentialsFile();
|
|
186
|
+
return envToken(env);
|
|
197
187
|
}
|
|
198
188
|
|
|
199
189
|
// src/extract.ts
|
|
@@ -422,12 +412,7 @@ async function crawlDeleteJob(client, jobName) {
|
|
|
422
412
|
raiseForStatus(response, body);
|
|
423
413
|
}
|
|
424
414
|
|
|
425
|
-
// src/kg.ts
|
|
426
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
427
|
-
import { dirname } from "path";
|
|
428
|
-
|
|
429
415
|
// src/ontology.ts
|
|
430
|
-
import { readFile } from "fs/promises";
|
|
431
416
|
var Ontology = class _Ontology {
|
|
432
417
|
data;
|
|
433
418
|
constructor(data) {
|
|
@@ -437,10 +422,6 @@ var Ontology = class _Ontology {
|
|
|
437
422
|
const text = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
|
|
438
423
|
return new _Ontology(JSON.parse(text));
|
|
439
424
|
}
|
|
440
|
-
static async fromPath(path) {
|
|
441
|
-
const text = await readFile(path, "utf8");
|
|
442
|
-
return _Ontology.fromJson(text);
|
|
443
|
-
}
|
|
444
425
|
types() {
|
|
445
426
|
const types = this.data.types;
|
|
446
427
|
return Object.keys(types ?? {}).sort();
|
|
@@ -553,7 +534,7 @@ function buildDqlParams(client, query, options) {
|
|
|
553
534
|
}
|
|
554
535
|
async function dql(client, query, options = {}) {
|
|
555
536
|
const params = buildDqlParams(client, query, options);
|
|
556
|
-
const response = await client.http.get(
|
|
537
|
+
const response = await client.http.get(client.dqlUrl, { params });
|
|
557
538
|
const body = await readBodyText(response);
|
|
558
539
|
raiseForStatus(response, body);
|
|
559
540
|
if (options.raw) {
|
|
@@ -577,18 +558,14 @@ async function dqlParallel(client, queries, workers = 8) {
|
|
|
577
558
|
await Promise.all(Array.from({ length: limit }, () => worker()));
|
|
578
559
|
return results;
|
|
579
560
|
}
|
|
580
|
-
async function
|
|
581
|
-
const response = await client.http.get(
|
|
561
|
+
async function dqlFetchOntologyText(client) {
|
|
562
|
+
const response = await client.http.get(client.ontologyUrl);
|
|
582
563
|
const body = await readBodyText(response);
|
|
583
564
|
raiseForStatus(response, body);
|
|
584
|
-
|
|
585
|
-
await writeFile(dest, body);
|
|
565
|
+
return body;
|
|
586
566
|
}
|
|
587
567
|
async function dqlFetchOntology(client) {
|
|
588
|
-
|
|
589
|
-
const body = await readBodyText(response);
|
|
590
|
-
raiseForStatus(response, body);
|
|
591
|
-
return Ontology.fromJson(body);
|
|
568
|
+
return Ontology.fromJson(await dqlFetchOntologyText(client));
|
|
592
569
|
}
|
|
593
570
|
|
|
594
571
|
// src/nlp.ts
|
|
@@ -603,6 +580,123 @@ async function entities(client, text, lang = "auto") {
|
|
|
603
580
|
return Array.isArray(data) ? data[0] ?? {} : data;
|
|
604
581
|
}
|
|
605
582
|
|
|
583
|
+
// src/ontology-store.ts
|
|
584
|
+
var OntologyStore = class {
|
|
585
|
+
client;
|
|
586
|
+
ttlSeconds;
|
|
587
|
+
inFlight = null;
|
|
588
|
+
constructor(client, options = {}) {
|
|
589
|
+
this.client = client;
|
|
590
|
+
this.ttlSeconds = options.ttlSeconds ?? 86400;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Resolve the ontology, from cache when possible. Concurrent calls share
|
|
594
|
+
* one in-flight fetch rather than issuing duplicate requests; a rejected
|
|
595
|
+
* fetch clears the in-flight memo so the next call retries instead of
|
|
596
|
+
* replaying the same failure forever.
|
|
597
|
+
*/
|
|
598
|
+
load(options = {}) {
|
|
599
|
+
if (options.refresh) {
|
|
600
|
+
this.inFlight = null;
|
|
601
|
+
}
|
|
602
|
+
if (!this.inFlight) {
|
|
603
|
+
this.inFlight = this.resolve(options.refresh ?? false).catch((error) => {
|
|
604
|
+
this.inFlight = null;
|
|
605
|
+
throw error;
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
return this.inFlight;
|
|
609
|
+
}
|
|
610
|
+
async resolve(refresh) {
|
|
611
|
+
if (!refresh) {
|
|
612
|
+
const cached = await this.read();
|
|
613
|
+
if (cached !== void 0) {
|
|
614
|
+
try {
|
|
615
|
+
return Ontology.fromJson(cached);
|
|
616
|
+
} catch {
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
const text = await dqlFetchOntologyText(this.client);
|
|
621
|
+
await this.write(text);
|
|
622
|
+
return Ontology.fromJson(text);
|
|
623
|
+
}
|
|
624
|
+
/** Read the cached ontology text, or `undefined` on a miss. Memory-only by default. */
|
|
625
|
+
read() {
|
|
626
|
+
return Promise.resolve(void 0);
|
|
627
|
+
}
|
|
628
|
+
/** Persist ontology text after a fetch. No-op by default. */
|
|
629
|
+
write(_text) {
|
|
630
|
+
return Promise.resolve();
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
var KVOntologyStore = class extends OntologyStore {
|
|
634
|
+
kv;
|
|
635
|
+
key;
|
|
636
|
+
refreshedAtKey;
|
|
637
|
+
lockKey;
|
|
638
|
+
staleAfterSeconds;
|
|
639
|
+
lockTtlSeconds;
|
|
640
|
+
waitUntil;
|
|
641
|
+
constructor(client, kv, options = {}) {
|
|
642
|
+
super(client, options);
|
|
643
|
+
this.kv = kv;
|
|
644
|
+
this.key = options.key ?? "diffbot:ontology:v1";
|
|
645
|
+
this.refreshedAtKey = `${this.key}:refreshed_at`;
|
|
646
|
+
this.lockKey = `${this.key}:lock`;
|
|
647
|
+
this.staleAfterSeconds = options.staleAfterSeconds ?? 0;
|
|
648
|
+
this.lockTtlSeconds = options.lockTtlSeconds ?? 60;
|
|
649
|
+
this.waitUntil = options.waitUntil;
|
|
650
|
+
}
|
|
651
|
+
load(options = {}) {
|
|
652
|
+
if (!options.refresh && this.staleAfterSeconds > 0) {
|
|
653
|
+
return this.loadWithStaleWhileRevalidate();
|
|
654
|
+
}
|
|
655
|
+
return super.load(options);
|
|
656
|
+
}
|
|
657
|
+
async loadWithStaleWhileRevalidate() {
|
|
658
|
+
const [cached, refreshedAt] = await Promise.all([
|
|
659
|
+
this.kv.get(this.key),
|
|
660
|
+
this.kv.get(this.refreshedAtKey)
|
|
661
|
+
]);
|
|
662
|
+
if (cached === null) {
|
|
663
|
+
return super.load();
|
|
664
|
+
}
|
|
665
|
+
const age = refreshedAt ? (Date.now() - Number(refreshedAt)) / 1e3 : Infinity;
|
|
666
|
+
const isStale = age > this.staleAfterSeconds;
|
|
667
|
+
const ontology = Ontology.fromJson(cached);
|
|
668
|
+
if (isStale) {
|
|
669
|
+
const refresh = super.load({ refresh: true }).catch(() => {
|
|
670
|
+
});
|
|
671
|
+
if (this.waitUntil) {
|
|
672
|
+
this.waitUntil(refresh);
|
|
673
|
+
} else {
|
|
674
|
+
await refresh;
|
|
675
|
+
return super.load();
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return ontology;
|
|
679
|
+
}
|
|
680
|
+
async read() {
|
|
681
|
+
const cached = await this.kv.get(this.key);
|
|
682
|
+
return cached ?? void 0;
|
|
683
|
+
}
|
|
684
|
+
async write(text) {
|
|
685
|
+
if (await this.kv.get(this.lockKey)) {
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
await this.kv.put(this.lockKey, "1", { expirationTtl: this.lockTtlSeconds });
|
|
689
|
+
try {
|
|
690
|
+
await this.kv.put(this.key, text, { expirationTtl: this.ttlSeconds });
|
|
691
|
+
await this.kv.put(this.refreshedAtKey, String(Date.now()), {
|
|
692
|
+
expirationTtl: this.ttlSeconds
|
|
693
|
+
});
|
|
694
|
+
} finally {
|
|
695
|
+
await this.kv.delete(this.lockKey);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
|
|
606
700
|
// src/web-search.ts
|
|
607
701
|
async function webSearch(client, text, options = {}) {
|
|
608
702
|
const headers = { Authorization: `Bearer ${client.token}` };
|
|
@@ -621,7 +715,9 @@ export {
|
|
|
621
715
|
DiffbotClient,
|
|
622
716
|
DiffbotError,
|
|
623
717
|
ExtractionError,
|
|
718
|
+
KVOntologyStore,
|
|
624
719
|
Ontology,
|
|
720
|
+
OntologyStore,
|
|
625
721
|
RateLimitError,
|
|
626
722
|
VERSION,
|
|
627
723
|
ValidationError,
|
|
@@ -632,11 +728,11 @@ export {
|
|
|
632
728
|
crawlListJobs,
|
|
633
729
|
dql,
|
|
634
730
|
dqlFetchOntology,
|
|
731
|
+
dqlFetchOntologyText,
|
|
635
732
|
dqlParallel,
|
|
636
|
-
dqlRefreshOntology,
|
|
637
733
|
entities,
|
|
638
734
|
extract,
|
|
639
|
-
|
|
735
|
+
resolveTokenFromEnv,
|
|
640
736
|
webSearch
|
|
641
737
|
};
|
|
642
738
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/http.ts","../src/client.ts","../src/auth.ts","../src/extract.ts","../src/ask.ts","../src/crawl.ts","../src/kg.ts","../src/ontology.ts","../src/nlp.ts","../src/web-search.ts"],"sourcesContent":["export const VERSION = \"0.1.0\";\n\nexport const DEFAULT_TIMEOUT = 30_000;\n\nexport const EXTRACT_BASE = \"https://api.diffbot.com/v3\";\nexport const CRAWL_BASE = \"https://api.diffbot.com/v3/crawl\";\nexport const DIFFBOT_LLM_BASE = \"https://llm.diffbot.com/rag/v1/chat/completions\";\nexport const WEB_SEARCH_BASE = \"https://llm.diffbot.com/api/v1/web_search\";\nexport const NLP_BASE = \"https://nl.diffbot.com/v1/\";\nexport const KG_DQL_ENDPOINT = \"https://kg.diffbot.com/kg/v3/dql\";\nexport const KG_ONTOLOGY_ENDPOINT = \"https://kg.diffbot.com/kg/ontology\";\n\nexport const TOKEN_ENV_VAR = \"DIFFBOT_API_TOKEN\";\n","/** Exception hierarchy for the Diffbot SDK. */\n\nexport class DiffbotError extends Error {\n override name = \"DiffbotError\";\n}\n\nexport class ValidationError extends DiffbotError {\n override name = \"ValidationError\";\n}\n\nexport class APIError extends DiffbotError {\n statusCode: number;\n body: string;\n apiMessage: string | undefined;\n requestId: string | undefined;\n\n constructor(statusCode: number, body: string) {\n let apiMessage: string | undefined;\n let requestId: string | undefined;\n try {\n const data = JSON.parse(body) as { message?: string; requestId?: string };\n apiMessage = data.message;\n requestId = data.requestId;\n } catch {\n /* ignore parse errors */\n }\n const display = apiMessage ?? (body.length > 200 ? `${body.slice(0, 200)}...` : body);\n super(`Diffbot API error ${statusCode}: ${display}`);\n this.name = \"APIError\";\n this.statusCode = statusCode;\n this.body = body;\n this.apiMessage = apiMessage;\n this.requestId = requestId;\n }\n\n}\n\nexport class AuthError extends APIError {\n override name = \"AuthError\";\n}\n\nexport class RateLimitError extends APIError {\n retryAfter: string | undefined;\n override name = \"RateLimitError\";\n\n constructor(statusCode: number, body: string, retryAfter?: string | null) {\n super(statusCode, body);\n this.retryAfter = retryAfter ?? undefined;\n }\n}\n\nexport class ExtractionError extends DiffbotError {\n errorCode: number;\n error: string;\n override name = \"ExtractionError\";\n\n constructor(errorCode: number, error: string) {\n super(`Diffbot extraction error ${errorCode}: ${error}`);\n this.errorCode = errorCode;\n this.error = error;\n }\n}\n","import { APIError, AuthError, RateLimitError } from \"./errors.js\";\n\nexport type FetchFn = typeof fetch;\n\nexport interface HttpRequestOptions {\n params?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string>;\n json?: unknown;\n redirect?: \"follow\" | \"error\" | \"manual\";\n}\n\nexport class HttpClient {\n private closed = false;\n\n constructor(\n private readonly fetchFn: FetchFn,\n private readonly timeoutMs: number,\n readonly userAgent: string,\n ) {}\n\n async get(url: string, options: HttpRequestOptions = {}): Promise<Response> {\n return this.request(url, { ...options, method: \"GET\" });\n }\n\n async post(url: string, options: HttpRequestOptions = {}): Promise<Response> {\n return this.request(url, { ...options, method: \"POST\" });\n }\n\n async request(url: string, options: HttpRequestOptions & { method?: string } = {}): Promise<Response> {\n if (this.closed) {\n throw new Error(\"HTTP client is closed\");\n }\n\n const parsed = new URL(url);\n if (options.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined) {\n parsed.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers = new Headers(options.headers);\n headers.set(\"User-Agent\", this.userAgent);\n if (options.json !== undefined) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n const init: RequestInit = {\n method: options.method ?? \"GET\",\n headers,\n redirect: options.redirect,\n signal: AbortSignal.timeout(this.timeoutMs),\n };\n if (options.json !== undefined) {\n init.body = JSON.stringify(options.json);\n }\n\n return this.fetchFn(parsed.toString(), init);\n }\n\n async close(): Promise<void> {\n this.closed = true;\n }\n\n get isClosed(): boolean {\n return this.closed;\n }\n}\n\nexport function raiseForStatus(response: Response, bodyText?: string): void {\n if (response.ok) {\n return;\n }\n const status = response.status;\n const body = bodyText ?? \"\";\n if (status === 401 || status === 403) {\n throw new AuthError(status, body);\n }\n if (status === 429) {\n throw new RateLimitError(status, body, response.headers.get(\"retry-after\"));\n }\n throw new APIError(status, body);\n}\n\nexport async function readBodyText(response: Response): Promise<string> {\n return response.text();\n}\n","import {\n CRAWL_BASE,\n DEFAULT_TIMEOUT,\n DIFFBOT_LLM_BASE,\n EXTRACT_BASE,\n NLP_BASE,\n VERSION,\n WEB_SEARCH_BASE,\n} from \"./constants.js\";\nimport { ValidationError } from \"./errors.js\";\nimport { HttpClient, type FetchFn } from \"./http.js\";\n\nexport interface DiffbotClientOptions {\n token: string;\n timeout?: number;\n analyzeUrl?: string;\n llmUrl?: string;\n crawlerUrl?: string;\n webSearchUrl?: string;\n nlpUrl?: string;\n fetch?: FetchFn;\n}\n\nexport class DiffbotClient {\n readonly token: string;\n readonly analyzeUrl: string;\n readonly llmUrl: string;\n readonly crawlerUrl: string;\n readonly webSearchUrl: string;\n readonly nlpUrl: string;\n readonly http: HttpClient;\n\n constructor(options: DiffbotClientOptions) {\n if (!options.token) {\n throw new ValidationError(\"token is required\");\n }\n this.token = options.token;\n this.analyzeUrl = options.analyzeUrl ?? EXTRACT_BASE;\n this.llmUrl = options.llmUrl ?? DIFFBOT_LLM_BASE;\n this.crawlerUrl = options.crawlerUrl ?? CRAWL_BASE;\n this.webSearchUrl = options.webSearchUrl ?? WEB_SEARCH_BASE;\n this.nlpUrl = options.nlpUrl ?? NLP_BASE;\n this.http = new HttpClient(\n options.fetch ?? fetch,\n options.timeout ?? DEFAULT_TIMEOUT,\n `diffbot-typescript/${VERSION}`,\n );\n }\n\n async close(): Promise<void> {\n await this.http.close();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { TOKEN_ENV_VAR } from \"./constants.js\";\n\n/** Mutable for tests; defaults to ~/.diffbot/credentials. */\nexport const authConfig = {\n credentialsPath: join(homedir(), \".diffbot\", \"credentials\"),\n};\n\nfunction readCredentialsFile(path = authConfig.credentialsPath): string {\n if (!existsSync(path)) {\n return \"\";\n }\n const text = readFileSync(path, \"utf8\");\n for (const line of text.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(`${TOKEN_ENV_VAR}=`)) {\n return trimmed.slice(TOKEN_ENV_VAR.length + 1).trim();\n }\n }\n return \"\";\n}\n\n/** Resolve a Diffbot API token from explicit arg, env var, or credentials file. */\nexport function resolveToken(token?: string | null): string {\n if (token?.trim()) {\n return token.trim();\n }\n\n const envToken = process.env[TOKEN_ENV_VAR]?.trim();\n if (envToken) {\n return envToken;\n }\n\n return readCredentialsFile();\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { ExtractionError } from \"./errors.js\";\nimport { raiseForStatus, readBodyText } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nfunction buildParams(client: DiffbotClient, url: string, fmt: string) {\n const params: Record<string, string | number> = {\n token: client.token,\n url,\n timeout: 30_000,\n };\n if (fmt === \"markdown\") {\n params.mode = \"llm\";\n }\n return params;\n}\n\nfunction parseResponse(data: JsonObject): JsonObject {\n if (\"errorCode\" in data) {\n throw new ExtractionError(\n Number(data.errorCode),\n String(data.error ?? \"\"),\n );\n }\n return data;\n}\n\nfunction normalizeUrl(url: string): string {\n return url.startsWith(\"http\") ? url : `https://${url}`;\n}\n\nexport async function extract(\n client: DiffbotClient,\n url: string,\n api = \"analyze\",\n fmt = \"markdown\",\n): Promise<JsonObject> {\n const normalized = normalizeUrl(url);\n const response = await client.http.get(`${client.analyzeUrl}/${api}`, {\n params: buildParams(client, normalized, fmt),\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return parseResponse(JSON.parse(body) as JsonObject);\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\n\nexport interface ChatMessage {\n role: string;\n content: string;\n}\n\nfunction parseChunk(line: string): string | undefined {\n try {\n const chunk = JSON.parse(line.replace(/^data: /, \"\")) as {\n choices?: Array<{ delta?: { content?: string } }>;\n };\n const content = chunk.choices?.[0]?.delta?.content;\n return content ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction* linesFromText(text: string): Generator<string> {\n for (const line of text.split(\"\\n\")) {\n if (line) yield line;\n }\n}\n\nasync function* linesFromStream(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split(\"\\n\");\n buffer = parts.pop() ?? \"\";\n for (const line of parts) {\n if (line) yield line;\n }\n }\n if (buffer) yield buffer;\n}\n\nexport async function* ask(\n client: DiffbotClient,\n messages: ChatMessage[],\n): AsyncGenerator<string> {\n const headers = { Authorization: `Bearer ${client.token}` };\n const payload = { model: \"diffbot-small-xl\", messages, stream: true };\n\n const response = await client.http.post(client.llmUrl, { headers, json: payload });\n if (!response.ok) {\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return;\n }\n\n if (response.body) {\n for await (const line of linesFromStream(response.body)) {\n const content = parseChunk(line);\n if (content) yield content;\n }\n return;\n }\n\n const text = await response.text();\n for (const line of linesFromText(text)) {\n const content = parseChunk(line);\n if (content) yield content;\n }\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { APIError } from \"./errors.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nexport enum CrawlEventType {\n JobCreated = \"job_created\",\n UrlProcessed = \"url_processed\",\n}\n\nexport interface CrawlEvent {\n eventType: CrawlEventType;\n timestamp: string;\n details: JsonObject;\n}\n\nexport interface CrawlOptions {\n hops?: number;\n jobName?: string;\n maxToCrawl?: number;\n maxToProcess?: number;\n restrictDomain?: boolean;\n apiUrl?: string;\n crawlDelay?: number;\n urlCrawlPattern?: string;\n urlProcessPattern?: string;\n obeyRobots?: boolean;\n useProxies?: boolean;\n customHeaders?: string;\n watch?: boolean;\n pollInterval?: number;\n}\n\nfunction buildCrawlParams(\n client: DiffbotClient,\n jobName: string,\n site: string,\n options: Required<Pick<CrawlOptions, \"maxToCrawl\" | \"maxToProcess\" | \"hops\" | \"restrictDomain\" | \"apiUrl\" | \"crawlDelay\" | \"obeyRobots\" | \"useProxies\">> &\n Pick<CrawlOptions, \"urlCrawlPattern\" | \"urlProcessPattern\" | \"customHeaders\">,\n) {\n const params: Record<string, string | number> = {\n token: client.token,\n name: jobName,\n seeds: site,\n maxToCrawl: options.maxToCrawl,\n maxToProcess: options.maxToProcess,\n maxHops: options.hops,\n restrictDomain: options.restrictDomain ? 1 : 0,\n };\n if (options.apiUrl) params.apiUrl = options.apiUrl;\n if (options.crawlDelay > 0) params.crawlDelay = options.crawlDelay;\n if (options.urlCrawlPattern) params.urlCrawlPattern = options.urlCrawlPattern;\n if (options.urlProcessPattern) params.urlProcessPattern = options.urlProcessPattern;\n if (options.obeyRobots) params.obeyRobots = 1;\n if (options.useProxies) params.useProxies = 1;\n if (options.customHeaders) params.customHeaders = options.customHeaders;\n return params;\n}\n\nfunction parseUrlCsv(text: string, seenUrls: Set<string>): CrawlEvent[] {\n const events: CrawlEvent[] = [];\n const lines = text.trim().split(\"\\n\");\n if (lines.length < 2) return events;\n\n const headers = lines[0]!.split(\",\").map((h) => h.trim());\n const urlIdx = headers.indexOf(\"Url\");\n const timeIdx = headers.indexOf(\"Crawled Time\");\n const statusIdx = headers.indexOf(\"Crawl Status\");\n\n for (const line of lines.slice(1)) {\n const cols = line.split(\",\");\n const url = cols[urlIdx]?.replace(/^\"|\"$/g, \"\").trim() ?? \"\";\n if (url && !seenUrls.has(url)) {\n seenUrls.add(url);\n events.push({\n eventType: CrawlEventType.UrlProcessed,\n timestamp: cols[timeIdx]?.trim() ?? new Date().toISOString(),\n details: {\n url,\n status: cols[statusIdx]?.trim() ?? \"unknown\",\n },\n });\n }\n }\n return events;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function* crawl(\n client: DiffbotClient,\n site: string,\n options: CrawlOptions = {},\n): AsyncGenerator<CrawlEvent> {\n let normalizedSite = site.startsWith(\"http\") ? site : `https://${site}`;\n const jobName = options.jobName ?? `crawl-${Math.floor(Date.now() / 1000)}`;\n\n const params = buildCrawlParams(client, jobName, normalizedSite, {\n hops: options.hops ?? 2,\n maxToCrawl: options.maxToCrawl ?? 100,\n maxToProcess: options.maxToProcess ?? 100,\n restrictDomain: options.restrictDomain ?? true,\n apiUrl: options.apiUrl ?? \"\",\n crawlDelay: options.crawlDelay ?? -1,\n urlCrawlPattern: options.urlCrawlPattern,\n urlProcessPattern: options.urlProcessPattern,\n obeyRobots: options.obeyRobots ?? false,\n useProxies: options.useProxies ?? false,\n customHeaders: options.customHeaders,\n });\n\n const response = await client.http.get(client.crawlerUrl, { params });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n\n yield {\n eventType: CrawlEventType.JobCreated,\n timestamp: new Date().toISOString(),\n details: { job_name: jobName },\n };\n\n if (!options.watch) {\n return;\n }\n\n const seenUrls = new Set<string>();\n const pollInterval = options.pollInterval ?? 2000;\n\n while (true) {\n const statusResponse = await client.http.get(client.crawlerUrl, {\n params: { token: client.token, name: jobName },\n });\n const statusBody = await readBodyText(statusResponse);\n raiseForStatus(statusResponse, statusBody);\n const jobs = (JSON.parse(statusBody) as JsonObject).jobs as JsonObject[] | undefined;\n if (!jobs?.length) break;\n\n const jobStatus = (jobs[0]!.jobStatus ?? {}) as JsonObject;\n const statusCode = Number(jobStatus.status ?? 0);\n\n const urlsResponse = await client.http.get(`${client.crawlerUrl}/data`, {\n params: { token: client.token, name: jobName, type: \"urls\" },\n redirect: \"follow\",\n });\n const urlsBody = await readBodyText(urlsResponse);\n raiseForStatus(urlsResponse, urlsBody);\n if (urlsBody) {\n for (const event of parseUrlCsv(urlsBody, seenUrls)) {\n yield event;\n }\n }\n\n if (statusCode !== 0 && statusCode !== 7) {\n const message = String(jobStatus.message ?? \"\");\n if (/fail|error/i.test(message)) {\n throw new APIError(500, `Crawler job failed: ${message}`);\n }\n break;\n }\n\n await sleep(pollInterval);\n }\n}\n\nexport async function crawlListJobs(client: DiffbotClient): Promise<JsonObject[]> {\n const response = await client.http.get(client.crawlerUrl, {\n params: { token: client.token },\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return ((JSON.parse(body) as JsonObject).jobs as JsonObject[] | undefined) ?? [];\n}\n\nexport async function crawlGetJob(client: DiffbotClient, jobName: string): Promise<JsonObject> {\n const response = await client.http.get(client.crawlerUrl, {\n params: { token: client.token, name: jobName },\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n const jobs = (JSON.parse(body) as JsonObject).jobs as JsonObject[] | undefined;\n return jobs?.[0] ?? {};\n}\n\nexport async function crawlDeleteJob(client: DiffbotClient, jobName: string): Promise<void> {\n const response = await client.http.get(client.crawlerUrl, {\n params: { token: client.token, name: jobName, delete: 1 },\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { KG_DQL_ENDPOINT, KG_ONTOLOGY_ENDPOINT } from \"./constants.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\nimport { Ontology } from \"./ontology.js\";\n\nexport interface DqlOptions {\n size?: number;\n from?: number;\n format?: string;\n filter?: string;\n exportspec?: string;\n extra?: Record<string, string>;\n raw?: boolean;\n}\n\nfunction buildDqlParams(\n client: DiffbotClient,\n query: string,\n options: DqlOptions,\n): Record<string, string | number> {\n const params: Record<string, string | number> = {\n token: client.token,\n query,\n size: options.size ?? 10,\n };\n if (options.from) params.from = options.from;\n if (options.format && options.format !== \"json\") params.format = options.format;\n if (options.filter !== undefined) params.filter = options.filter;\n if (options.exportspec !== undefined) params.exportspec = options.exportspec;\n if (options.extra) Object.assign(params, options.extra);\n return params;\n}\n\nexport async function dql(\n client: DiffbotClient,\n query: string,\n options: DqlOptions = {},\n): Promise<JsonObject | Uint8Array> {\n const params = buildDqlParams(client, query, options);\n const response = await client.http.get(KG_DQL_ENDPOINT, { params });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n if (options.raw) {\n return new TextEncoder().encode(body);\n }\n return JSON.parse(body) as JsonObject;\n}\n\nexport async function dqlParallel(\n client: DiffbotClient,\n queries: Array<DqlOptions & { query: string }>,\n workers = 8,\n): Promise<Array<JsonObject | Uint8Array>> {\n if (!queries.length) return [];\n\n const limit = Math.min(workers, queries.length);\n const results: Array<JsonObject | Uint8Array> = new Array(queries.length);\n let index = 0;\n\n async function worker(): Promise<void> {\n while (true) {\n const current = index++;\n if (current >= queries.length) return;\n const { query, ...opts } = queries[current]!;\n results[current] = await dql(client, query, opts);\n }\n }\n\n await Promise.all(Array.from({ length: limit }, () => worker()));\n return results;\n}\n\nexport async function dqlRefreshOntology(client: DiffbotClient, dest: string): Promise<void> {\n const response = await client.http.get(KG_ONTOLOGY_ENDPOINT);\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, body);\n}\n\nexport async function dqlFetchOntology(client: DiffbotClient): Promise<Ontology> {\n const response = await client.http.get(KG_ONTOLOGY_ENDPOINT);\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return Ontology.fromJson(body);\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { JsonObject } from \"./json.js\";\n\ntype FieldMeta = JsonObject;\ntype FieldEntry = [string, FieldMeta];\n\nexport class Ontology {\n readonly data: JsonObject;\n\n constructor(data: JsonObject) {\n this.data = data;\n }\n\n static fromJson(raw: string | Uint8Array): Ontology {\n const text = typeof raw === \"string\" ? raw : new TextDecoder().decode(raw);\n return new Ontology(JSON.parse(text) as JsonObject);\n }\n\n static async fromPath(path: string): Promise<Ontology> {\n const text = await readFile(path, \"utf8\");\n return Ontology.fromJson(text);\n }\n\n types(): string[] {\n const types = this.data.types as Record<string, unknown> | undefined;\n return Object.keys(types ?? {}).sort();\n }\n\n composites(): string[] {\n const composites = this.data.composites as Record<string, unknown> | undefined;\n return Object.keys(composites ?? {}).sort();\n }\n\n enums(): string[] {\n const enums = this.data.enums as Record<string, unknown> | undefined;\n return Object.keys(enums ?? {}).sort();\n }\n\n taxonomies(): string[] {\n const taxonomies = this.data.taxonomies as Record<string, unknown> | undefined;\n return Object.keys(taxonomies ?? {}).sort();\n }\n\n private static fieldsOf(container: Record<string, JsonObject>, typeName: string): Record<string, FieldMeta> {\n const entry = container[typeName];\n if (!entry) throw new Error(`Unknown name: ${typeName}`);\n return (entry.fields as Record<string, FieldMeta> | undefined) ?? {};\n }\n\n fieldsFor(typeName: string): Record<string, FieldMeta> {\n const types = (this.data.types ?? {}) as Record<string, JsonObject>;\n const composites = (this.data.composites ?? {}) as Record<string, JsonObject>;\n if (typeName in types) return Ontology.fieldsOf(types, typeName);\n if (typeName in composites) return Ontology.fieldsOf(composites, typeName);\n throw new Error(`${typeName} is not a known entity type or composite`);\n }\n\n static filterFields(\n fields: Record<string, FieldMeta>,\n search?: string | null,\n includeDeprecated = false,\n ): FieldEntry[] {\n const pattern = search ? new RegExp(search, \"i\") : null;\n const out: FieldEntry[] = [];\n for (const [name, meta] of Object.entries(fields)) {\n if (!includeDeprecated && meta.isDeprecated) continue;\n if (pattern && !pattern.test(name)) continue;\n out.push([name, meta]);\n }\n return out;\n }\n\n taxonomyValues(name: string, search?: string | null): string[] {\n const taxonomies = (this.data.taxonomies ?? {}) as Record<string, JsonObject>;\n const tax = taxonomies[name];\n if (!tax) throw new Error(`Unknown taxonomy: ${name}`);\n\n const pattern = search ? new RegExp(search, \"i\") : null;\n const out: string[] = [];\n\n const walk = (node: JsonObject): void => {\n const n = node.name;\n if (typeof n === \"string\" && (!pattern || pattern.test(n))) {\n out.push(n);\n }\n for (const child of (node.children as JsonObject[] | undefined) ?? []) {\n walk(child);\n }\n };\n\n for (const cat of (tax.categories as JsonObject[] | undefined) ?? []) {\n walk(cat);\n }\n return out;\n }\n\n enumValues(name: string): string[] {\n const enums = (this.data.enums ?? {}) as Record<string, JsonObject>;\n const enumEntry = enums[name];\n if (!enumEntry) throw new Error(`Unknown enum: ${name}`);\n return [...((enumEntry.values as string[] | undefined) ?? [])];\n }\n\n findNamed(search: string): string[] {\n const pattern = new RegExp(search, \"i\");\n const found = new Set<string>();\n\n const walk = (node: unknown): void => {\n if (Array.isArray(node)) {\n for (const v of node) walk(v);\n } else if (node && typeof node === \"object\") {\n const obj = node as JsonObject;\n const n = obj.name;\n if (typeof n === \"string\" && pattern.test(n)) found.add(n);\n for (const v of Object.values(obj)) walk(v);\n }\n };\n\n walk(this.data);\n return [...found].sort();\n }\n\n static formatField(name: string, meta: FieldMeta): string {\n let typeName = String(meta.type ?? \"?\");\n if (typeName === \"LinkedEntity\") {\n const le = meta.leType as string[] | undefined;\n if (le?.length) typeName = `LinkedEntity (${le[0]})`;\n }\n const flags: string[] = [];\n if (meta.isList) flags.push(\"isList\");\n if (meta.isComposite) flags.push(\"isComposite\");\n if (meta.isEnum) flags.push(\"isEnum\");\n if (meta.isDeprecated) flags.push(\"DEPRECATED\");\n const suffix = flags.map((f) => ` [${f}]`).join(\"\");\n return `${name}: [${typeName}]${suffix}`;\n }\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nconst NLP_FIELDS = \"entities,sentiment\";\n\nexport async function entities(\n client: DiffbotClient,\n text: string,\n lang = \"auto\",\n): Promise<JsonObject> {\n const params = { token: client.token, fields: NLP_FIELDS };\n const payload = [{ lang, format: \"plain text\", content: text }];\n const response = await client.http.post(client.nlpUrl, { params, json: payload });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n const data = JSON.parse(body) as JsonObject | JsonObject[];\n return Array.isArray(data) ? (data[0] ?? {}) : data;\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nexport async function webSearch(\n client: DiffbotClient,\n text: string,\n options: { numResults?: number; maxTokens?: number } = {},\n): Promise<JsonObject> {\n const headers = { Authorization: `Bearer ${client.token}` };\n const params: Record<string, string | number> = { text };\n if (options.numResults !== undefined) params.size = options.numResults;\n if (options.maxTokens !== undefined) params.maxTokens = options.maxTokens;\n\n const response = await client.http.get(client.webSearchUrl, { headers, params });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return JSON.parse(body) as JsonObject;\n}\n"],"mappings":"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","names":["CrawlEventType"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/http.ts","../src/client.ts","../src/auth.ts","../src/extract.ts","../src/ask.ts","../src/crawl.ts","../src/ontology.ts","../src/kg.ts","../src/nlp.ts","../src/ontology-store.ts","../src/web-search.ts"],"sourcesContent":["export const VERSION = \"0.2.0\";\n\nexport const DEFAULT_TIMEOUT = 30_000;\n\nexport const EXTRACT_BASE = \"https://api.diffbot.com/v3\";\nexport const CRAWL_BASE = \"https://api.diffbot.com/v3/crawl\";\nexport const DIFFBOT_LLM_BASE = \"https://llm.diffbot.com/rag/v1/chat/completions\";\nexport const WEB_SEARCH_BASE = \"https://llm.diffbot.com/api/v1/web_search\";\nexport const NLP_BASE = \"https://nl.diffbot.com/v1/\";\nexport const KG_DQL_ENDPOINT = \"https://kg.diffbot.com/kg/v3/dql\";\nexport const KG_ONTOLOGY_ENDPOINT = \"https://kg.diffbot.com/kg/ontology\";\n\nexport const TOKEN_ENV_VAR = \"DIFFBOT_API_TOKEN\";\n","/** Exception hierarchy for the Diffbot SDK. */\n\nexport class DiffbotError extends Error {\n override name = \"DiffbotError\";\n}\n\nexport class ValidationError extends DiffbotError {\n override name = \"ValidationError\";\n}\n\nexport class APIError extends DiffbotError {\n statusCode: number;\n body: string;\n apiMessage: string | undefined;\n requestId: string | undefined;\n\n constructor(statusCode: number, body: string) {\n let apiMessage: string | undefined;\n let requestId: string | undefined;\n try {\n const data = JSON.parse(body) as { message?: string; requestId?: string };\n apiMessage = data.message;\n requestId = data.requestId;\n } catch {\n /* ignore parse errors */\n }\n const display = apiMessage ?? (body.length > 200 ? `${body.slice(0, 200)}...` : body);\n super(`Diffbot API error ${statusCode}: ${display}`);\n this.name = \"APIError\";\n this.statusCode = statusCode;\n this.body = body;\n this.apiMessage = apiMessage;\n this.requestId = requestId;\n }\n\n}\n\nexport class AuthError extends APIError {\n override name = \"AuthError\";\n}\n\nexport class RateLimitError extends APIError {\n retryAfter: string | undefined;\n override name = \"RateLimitError\";\n\n constructor(statusCode: number, body: string, retryAfter?: string | null) {\n super(statusCode, body);\n this.retryAfter = retryAfter ?? undefined;\n }\n}\n\nexport class ExtractionError extends DiffbotError {\n errorCode: number;\n error: string;\n override name = \"ExtractionError\";\n\n constructor(errorCode: number, error: string) {\n super(`Diffbot extraction error ${errorCode}: ${error}`);\n this.errorCode = errorCode;\n this.error = error;\n }\n}\n","import { APIError, AuthError, RateLimitError } from \"./errors.js\";\n\nexport type FetchFn = typeof fetch;\n\nexport interface HttpRequestOptions {\n params?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string>;\n json?: unknown;\n redirect?: \"follow\" | \"error\" | \"manual\";\n}\n\nexport class HttpClient {\n private closed = false;\n\n constructor(\n private readonly fetchFn: FetchFn,\n private readonly timeoutMs: number,\n readonly userAgent: string,\n ) {}\n\n async get(url: string, options: HttpRequestOptions = {}): Promise<Response> {\n return this.request(url, { ...options, method: \"GET\" });\n }\n\n async post(url: string, options: HttpRequestOptions = {}): Promise<Response> {\n return this.request(url, { ...options, method: \"POST\" });\n }\n\n async request(url: string, options: HttpRequestOptions & { method?: string } = {}): Promise<Response> {\n if (this.closed) {\n throw new Error(\"HTTP client is closed\");\n }\n\n const parsed = new URL(url);\n if (options.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined) {\n parsed.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers = new Headers(options.headers);\n headers.set(\"User-Agent\", this.userAgent);\n if (options.json !== undefined) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n const init: RequestInit = {\n method: options.method ?? \"GET\",\n headers,\n redirect: options.redirect,\n signal: AbortSignal.timeout(this.timeoutMs),\n };\n if (options.json !== undefined) {\n init.body = JSON.stringify(options.json);\n }\n\n return this.fetchFn(parsed.toString(), init);\n }\n\n async close(): Promise<void> {\n this.closed = true;\n }\n\n get isClosed(): boolean {\n return this.closed;\n }\n}\n\nexport function raiseForStatus(response: Response, bodyText?: string): void {\n if (response.ok) {\n return;\n }\n const status = response.status;\n const body = bodyText ?? \"\";\n if (status === 401 || status === 403) {\n throw new AuthError(status, body);\n }\n if (status === 429) {\n throw new RateLimitError(status, body, response.headers.get(\"retry-after\"));\n }\n throw new APIError(status, body);\n}\n\nexport async function readBodyText(response: Response): Promise<string> {\n return response.text();\n}\n","import {\n CRAWL_BASE,\n DEFAULT_TIMEOUT,\n DIFFBOT_LLM_BASE,\n EXTRACT_BASE,\n KG_DQL_ENDPOINT,\n KG_ONTOLOGY_ENDPOINT,\n NLP_BASE,\n VERSION,\n WEB_SEARCH_BASE,\n} from \"./constants.js\";\nimport { ValidationError } from \"./errors.js\";\nimport { HttpClient, type FetchFn } from \"./http.js\";\n\nexport interface DiffbotClientOptions {\n token: string;\n timeout?: number;\n analyzeUrl?: string;\n llmUrl?: string;\n crawlerUrl?: string;\n webSearchUrl?: string;\n nlpUrl?: string;\n dqlUrl?: string;\n ontologyUrl?: string;\n fetch?: FetchFn;\n}\n\nexport class DiffbotClient {\n readonly token: string;\n readonly analyzeUrl: string;\n readonly llmUrl: string;\n readonly crawlerUrl: string;\n readonly webSearchUrl: string;\n readonly nlpUrl: string;\n readonly dqlUrl: string;\n readonly ontologyUrl: string;\n readonly http: HttpClient;\n\n constructor(options: DiffbotClientOptions) {\n if (!options.token) {\n throw new ValidationError(\"token is required\");\n }\n this.token = options.token;\n this.analyzeUrl = options.analyzeUrl ?? EXTRACT_BASE;\n this.llmUrl = options.llmUrl ?? DIFFBOT_LLM_BASE;\n this.crawlerUrl = options.crawlerUrl ?? CRAWL_BASE;\n this.webSearchUrl = options.webSearchUrl ?? WEB_SEARCH_BASE;\n this.nlpUrl = options.nlpUrl ?? NLP_BASE;\n this.dqlUrl = options.dqlUrl ?? KG_DQL_ENDPOINT;\n this.ontologyUrl = options.ontologyUrl ?? KG_ONTOLOGY_ENDPOINT;\n this.http = new HttpClient(\n options.fetch ?? fetch,\n options.timeout ?? DEFAULT_TIMEOUT,\n `diffbot-typescript/${VERSION}`,\n );\n }\n\n async close(): Promise<void> {\n await this.http.close();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n","import { TOKEN_ENV_VAR } from \"./constants.js\";\n\n/*\n * `object`, not `Record<string, unknown>`: a typed Workers `Env` is normally\n * an `interface`, and interfaces don't get TypeScript's implicit index\n * signature, so a `Record<string, unknown>` parameter would reject exactly\n * the argument this function exists to accept. `object` has no members, so\n * any object type is assignable to it; the bracket access below is cast\n * internally instead.\n */\nexport type TokenSource = object;\n\nfunction envToken(env: TokenSource | undefined): string {\n const fromEnv = (env as Record<string, unknown> | undefined)?.[TOKEN_ENV_VAR];\n if (typeof fromEnv === \"string\" && fromEnv.trim()) {\n return fromEnv.trim();\n }\n\n /*\n * Guarded rather than a static `process.env` read: `process` does not exist\n * in Workers/browsers, and touching it unconditionally would reintroduce a\n * runtime-specific dependency into an otherwise platform-neutral module.\n */\n const proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n const fromProcess = proc?.env?.[TOKEN_ENV_VAR];\n return fromProcess?.trim() ?? \"\";\n}\n\n/**\n * Resolve a Diffbot API token from an explicit arg, then a Workers-style\n * `env` object, then `process.env`. Does not touch the filesystem — for a\n * credentials-file fallback, use `resolveToken` from `@diffbot/typescript/node`.\n */\nexport function resolveTokenFromEnv(token?: string | null, env?: TokenSource): string {\n if (token?.trim()) {\n return token.trim();\n }\n return envToken(env);\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { ExtractionError } from \"./errors.js\";\nimport { raiseForStatus, readBodyText } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nfunction buildParams(client: DiffbotClient, url: string, fmt: string) {\n const params: Record<string, string | number> = {\n token: client.token,\n url,\n timeout: 30_000,\n };\n if (fmt === \"markdown\") {\n params.mode = \"llm\";\n }\n return params;\n}\n\nfunction parseResponse(data: JsonObject): JsonObject {\n if (\"errorCode\" in data) {\n throw new ExtractionError(\n Number(data.errorCode),\n String(data.error ?? \"\"),\n );\n }\n return data;\n}\n\nfunction normalizeUrl(url: string): string {\n return url.startsWith(\"http\") ? url : `https://${url}`;\n}\n\nexport async function extract(\n client: DiffbotClient,\n url: string,\n api = \"analyze\",\n fmt = \"markdown\",\n): Promise<JsonObject> {\n const normalized = normalizeUrl(url);\n const response = await client.http.get(`${client.analyzeUrl}/${api}`, {\n params: buildParams(client, normalized, fmt),\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return parseResponse(JSON.parse(body) as JsonObject);\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\n\nexport interface ChatMessage {\n role: string;\n content: string;\n}\n\nfunction parseChunk(line: string): string | undefined {\n try {\n const chunk = JSON.parse(line.replace(/^data: /, \"\")) as {\n choices?: Array<{ delta?: { content?: string } }>;\n };\n const content = chunk.choices?.[0]?.delta?.content;\n return content ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction* linesFromText(text: string): Generator<string> {\n for (const line of text.split(\"\\n\")) {\n if (line) yield line;\n }\n}\n\nasync function* linesFromStream(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split(\"\\n\");\n buffer = parts.pop() ?? \"\";\n for (const line of parts) {\n if (line) yield line;\n }\n }\n if (buffer) yield buffer;\n}\n\nexport async function* ask(\n client: DiffbotClient,\n messages: ChatMessage[],\n): AsyncGenerator<string> {\n const headers = { Authorization: `Bearer ${client.token}` };\n const payload = { model: \"diffbot-small-xl\", messages, stream: true };\n\n const response = await client.http.post(client.llmUrl, { headers, json: payload });\n if (!response.ok) {\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return;\n }\n\n if (response.body) {\n for await (const line of linesFromStream(response.body)) {\n const content = parseChunk(line);\n if (content) yield content;\n }\n return;\n }\n\n const text = await response.text();\n for (const line of linesFromText(text)) {\n const content = parseChunk(line);\n if (content) yield content;\n }\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { APIError } from \"./errors.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nexport enum CrawlEventType {\n JobCreated = \"job_created\",\n UrlProcessed = \"url_processed\",\n}\n\nexport interface CrawlEvent {\n eventType: CrawlEventType;\n timestamp: string;\n details: JsonObject;\n}\n\nexport interface CrawlOptions {\n hops?: number;\n jobName?: string;\n maxToCrawl?: number;\n maxToProcess?: number;\n restrictDomain?: boolean;\n apiUrl?: string;\n crawlDelay?: number;\n urlCrawlPattern?: string;\n urlProcessPattern?: string;\n obeyRobots?: boolean;\n useProxies?: boolean;\n customHeaders?: string;\n watch?: boolean;\n pollInterval?: number;\n}\n\nfunction buildCrawlParams(\n client: DiffbotClient,\n jobName: string,\n site: string,\n options: Required<Pick<CrawlOptions, \"maxToCrawl\" | \"maxToProcess\" | \"hops\" | \"restrictDomain\" | \"apiUrl\" | \"crawlDelay\" | \"obeyRobots\" | \"useProxies\">> &\n Pick<CrawlOptions, \"urlCrawlPattern\" | \"urlProcessPattern\" | \"customHeaders\">,\n) {\n const params: Record<string, string | number> = {\n token: client.token,\n name: jobName,\n seeds: site,\n maxToCrawl: options.maxToCrawl,\n maxToProcess: options.maxToProcess,\n maxHops: options.hops,\n restrictDomain: options.restrictDomain ? 1 : 0,\n };\n if (options.apiUrl) params.apiUrl = options.apiUrl;\n if (options.crawlDelay > 0) params.crawlDelay = options.crawlDelay;\n if (options.urlCrawlPattern) params.urlCrawlPattern = options.urlCrawlPattern;\n if (options.urlProcessPattern) params.urlProcessPattern = options.urlProcessPattern;\n if (options.obeyRobots) params.obeyRobots = 1;\n if (options.useProxies) params.useProxies = 1;\n if (options.customHeaders) params.customHeaders = options.customHeaders;\n return params;\n}\n\nfunction parseUrlCsv(text: string, seenUrls: Set<string>): CrawlEvent[] {\n const events: CrawlEvent[] = [];\n const lines = text.trim().split(\"\\n\");\n if (lines.length < 2) return events;\n\n const headers = lines[0]!.split(\",\").map((h) => h.trim());\n const urlIdx = headers.indexOf(\"Url\");\n const timeIdx = headers.indexOf(\"Crawled Time\");\n const statusIdx = headers.indexOf(\"Crawl Status\");\n\n for (const line of lines.slice(1)) {\n const cols = line.split(\",\");\n const url = cols[urlIdx]?.replace(/^\"|\"$/g, \"\").trim() ?? \"\";\n if (url && !seenUrls.has(url)) {\n seenUrls.add(url);\n events.push({\n eventType: CrawlEventType.UrlProcessed,\n timestamp: cols[timeIdx]?.trim() ?? new Date().toISOString(),\n details: {\n url,\n status: cols[statusIdx]?.trim() ?? \"unknown\",\n },\n });\n }\n }\n return events;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function* crawl(\n client: DiffbotClient,\n site: string,\n options: CrawlOptions = {},\n): AsyncGenerator<CrawlEvent> {\n let normalizedSite = site.startsWith(\"http\") ? site : `https://${site}`;\n const jobName = options.jobName ?? `crawl-${Math.floor(Date.now() / 1000)}`;\n\n const params = buildCrawlParams(client, jobName, normalizedSite, {\n hops: options.hops ?? 2,\n maxToCrawl: options.maxToCrawl ?? 100,\n maxToProcess: options.maxToProcess ?? 100,\n restrictDomain: options.restrictDomain ?? true,\n apiUrl: options.apiUrl ?? \"\",\n crawlDelay: options.crawlDelay ?? -1,\n urlCrawlPattern: options.urlCrawlPattern,\n urlProcessPattern: options.urlProcessPattern,\n obeyRobots: options.obeyRobots ?? false,\n useProxies: options.useProxies ?? false,\n customHeaders: options.customHeaders,\n });\n\n const response = await client.http.get(client.crawlerUrl, { params });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n\n yield {\n eventType: CrawlEventType.JobCreated,\n timestamp: new Date().toISOString(),\n details: { job_name: jobName },\n };\n\n if (!options.watch) {\n return;\n }\n\n const seenUrls = new Set<string>();\n const pollInterval = options.pollInterval ?? 2000;\n\n while (true) {\n const statusResponse = await client.http.get(client.crawlerUrl, {\n params: { token: client.token, name: jobName },\n });\n const statusBody = await readBodyText(statusResponse);\n raiseForStatus(statusResponse, statusBody);\n const jobs = (JSON.parse(statusBody) as JsonObject).jobs as JsonObject[] | undefined;\n if (!jobs?.length) break;\n\n const jobStatus = (jobs[0]!.jobStatus ?? {}) as JsonObject;\n const statusCode = Number(jobStatus.status ?? 0);\n\n const urlsResponse = await client.http.get(`${client.crawlerUrl}/data`, {\n params: { token: client.token, name: jobName, type: \"urls\" },\n redirect: \"follow\",\n });\n const urlsBody = await readBodyText(urlsResponse);\n raiseForStatus(urlsResponse, urlsBody);\n if (urlsBody) {\n for (const event of parseUrlCsv(urlsBody, seenUrls)) {\n yield event;\n }\n }\n\n if (statusCode !== 0 && statusCode !== 7) {\n const message = String(jobStatus.message ?? \"\");\n if (/fail|error/i.test(message)) {\n throw new APIError(500, `Crawler job failed: ${message}`);\n }\n break;\n }\n\n await sleep(pollInterval);\n }\n}\n\nexport async function crawlListJobs(client: DiffbotClient): Promise<JsonObject[]> {\n const response = await client.http.get(client.crawlerUrl, {\n params: { token: client.token },\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return ((JSON.parse(body) as JsonObject).jobs as JsonObject[] | undefined) ?? [];\n}\n\nexport async function crawlGetJob(client: DiffbotClient, jobName: string): Promise<JsonObject> {\n const response = await client.http.get(client.crawlerUrl, {\n params: { token: client.token, name: jobName },\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n const jobs = (JSON.parse(body) as JsonObject).jobs as JsonObject[] | undefined;\n return jobs?.[0] ?? {};\n}\n\nexport async function crawlDeleteJob(client: DiffbotClient, jobName: string): Promise<void> {\n const response = await client.http.get(client.crawlerUrl, {\n params: { token: client.token, name: jobName, delete: 1 },\n });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n}\n","import type { JsonObject } from \"./json.js\";\n\ntype FieldMeta = JsonObject;\ntype FieldEntry = [string, FieldMeta];\n\nexport class Ontology {\n readonly data: JsonObject;\n\n constructor(data: JsonObject) {\n this.data = data;\n }\n\n static fromJson(raw: string | Uint8Array): Ontology {\n const text = typeof raw === \"string\" ? raw : new TextDecoder().decode(raw);\n return new Ontology(JSON.parse(text) as JsonObject);\n }\n\n types(): string[] {\n const types = this.data.types as Record<string, unknown> | undefined;\n return Object.keys(types ?? {}).sort();\n }\n\n composites(): string[] {\n const composites = this.data.composites as Record<string, unknown> | undefined;\n return Object.keys(composites ?? {}).sort();\n }\n\n enums(): string[] {\n const enums = this.data.enums as Record<string, unknown> | undefined;\n return Object.keys(enums ?? {}).sort();\n }\n\n taxonomies(): string[] {\n const taxonomies = this.data.taxonomies as Record<string, unknown> | undefined;\n return Object.keys(taxonomies ?? {}).sort();\n }\n\n private static fieldsOf(container: Record<string, JsonObject>, typeName: string): Record<string, FieldMeta> {\n const entry = container[typeName];\n if (!entry) throw new Error(`Unknown name: ${typeName}`);\n return (entry.fields as Record<string, FieldMeta> | undefined) ?? {};\n }\n\n fieldsFor(typeName: string): Record<string, FieldMeta> {\n const types = (this.data.types ?? {}) as Record<string, JsonObject>;\n const composites = (this.data.composites ?? {}) as Record<string, JsonObject>;\n if (typeName in types) return Ontology.fieldsOf(types, typeName);\n if (typeName in composites) return Ontology.fieldsOf(composites, typeName);\n throw new Error(`${typeName} is not a known entity type or composite`);\n }\n\n static filterFields(\n fields: Record<string, FieldMeta>,\n search?: string | null,\n includeDeprecated = false,\n ): FieldEntry[] {\n const pattern = search ? new RegExp(search, \"i\") : null;\n const out: FieldEntry[] = [];\n for (const [name, meta] of Object.entries(fields)) {\n if (!includeDeprecated && meta.isDeprecated) continue;\n if (pattern && !pattern.test(name)) continue;\n out.push([name, meta]);\n }\n return out;\n }\n\n taxonomyValues(name: string, search?: string | null): string[] {\n const taxonomies = (this.data.taxonomies ?? {}) as Record<string, JsonObject>;\n const tax = taxonomies[name];\n if (!tax) throw new Error(`Unknown taxonomy: ${name}`);\n\n const pattern = search ? new RegExp(search, \"i\") : null;\n const out: string[] = [];\n\n const walk = (node: JsonObject): void => {\n const n = node.name;\n if (typeof n === \"string\" && (!pattern || pattern.test(n))) {\n out.push(n);\n }\n for (const child of (node.children as JsonObject[] | undefined) ?? []) {\n walk(child);\n }\n };\n\n for (const cat of (tax.categories as JsonObject[] | undefined) ?? []) {\n walk(cat);\n }\n return out;\n }\n\n enumValues(name: string): string[] {\n const enums = (this.data.enums ?? {}) as Record<string, JsonObject>;\n const enumEntry = enums[name];\n if (!enumEntry) throw new Error(`Unknown enum: ${name}`);\n return [...((enumEntry.values as string[] | undefined) ?? [])];\n }\n\n findNamed(search: string): string[] {\n const pattern = new RegExp(search, \"i\");\n const found = new Set<string>();\n\n const walk = (node: unknown): void => {\n if (Array.isArray(node)) {\n for (const v of node) walk(v);\n } else if (node && typeof node === \"object\") {\n const obj = node as JsonObject;\n const n = obj.name;\n if (typeof n === \"string\" && pattern.test(n)) found.add(n);\n for (const v of Object.values(obj)) walk(v);\n }\n };\n\n walk(this.data);\n return [...found].sort();\n }\n\n static formatField(name: string, meta: FieldMeta): string {\n let typeName = String(meta.type ?? \"?\");\n if (typeName === \"LinkedEntity\") {\n const le = meta.leType as string[] | undefined;\n if (le?.length) typeName = `LinkedEntity (${le[0]})`;\n }\n const flags: string[] = [];\n if (meta.isList) flags.push(\"isList\");\n if (meta.isComposite) flags.push(\"isComposite\");\n if (meta.isEnum) flags.push(\"isEnum\");\n if (meta.isDeprecated) flags.push(\"DEPRECATED\");\n const suffix = flags.map((f) => ` [${f}]`).join(\"\");\n return `${name}: [${typeName}]${suffix}`;\n }\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\nimport { Ontology } from \"./ontology.js\";\n\nexport interface DqlOptions {\n size?: number;\n from?: number;\n format?: string;\n filter?: string;\n exportspec?: string;\n extra?: Record<string, string>;\n raw?: boolean;\n}\n\nfunction buildDqlParams(\n client: DiffbotClient,\n query: string,\n options: DqlOptions,\n): Record<string, string | number> {\n const params: Record<string, string | number> = {\n token: client.token,\n query,\n size: options.size ?? 10,\n };\n if (options.from) params.from = options.from;\n if (options.format && options.format !== \"json\") params.format = options.format;\n if (options.filter !== undefined) params.filter = options.filter;\n if (options.exportspec !== undefined) params.exportspec = options.exportspec;\n if (options.extra) Object.assign(params, options.extra);\n return params;\n}\n\nexport async function dql(\n client: DiffbotClient,\n query: string,\n options: DqlOptions = {},\n): Promise<JsonObject | Uint8Array> {\n const params = buildDqlParams(client, query, options);\n const response = await client.http.get(client.dqlUrl, { params });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n if (options.raw) {\n return new TextEncoder().encode(body);\n }\n return JSON.parse(body) as JsonObject;\n}\n\nexport async function dqlParallel(\n client: DiffbotClient,\n queries: Array<DqlOptions & { query: string }>,\n workers = 8,\n): Promise<Array<JsonObject | Uint8Array>> {\n if (!queries.length) return [];\n\n const limit = Math.min(workers, queries.length);\n const results: Array<JsonObject | Uint8Array> = new Array(queries.length);\n let index = 0;\n\n async function worker(): Promise<void> {\n while (true) {\n const current = index++;\n if (current >= queries.length) return;\n const { query, ...opts } = queries[current]!;\n results[current] = await dql(client, query, opts);\n }\n }\n\n await Promise.all(Array.from({ length: limit }, () => worker()));\n return results;\n}\n\n/** Fetch the raw ontology JSON text. For a parsed, cached `Ontology`, see `OntologyStore`. */\nexport async function dqlFetchOntologyText(client: DiffbotClient): Promise<string> {\n const response = await client.http.get(client.ontologyUrl);\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return body;\n}\n\nexport async function dqlFetchOntology(client: DiffbotClient): Promise<Ontology> {\n return Ontology.fromJson(await dqlFetchOntologyText(client));\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nconst NLP_FIELDS = \"entities,sentiment\";\n\nexport async function entities(\n client: DiffbotClient,\n text: string,\n lang = \"auto\",\n): Promise<JsonObject> {\n const params = { token: client.token, fields: NLP_FIELDS };\n const payload = [{ lang, format: \"plain text\", content: text }];\n const response = await client.http.post(client.nlpUrl, { params, json: payload });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n const data = JSON.parse(body) as JsonObject | JsonObject[];\n return Array.isArray(data) ? (data[0] ?? {}) : data;\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { dqlFetchOntologyText } from \"./kg.js\";\nimport { Ontology } from \"./ontology.js\";\n\nexport interface OntologyStoreOptions {\n /**\n * How long a cached entry should be kept, in seconds. Default 86_400 (24h).\n * The base `OntologyStore` doesn't expire its in-memory cache on its own —\n * an explicit `refresh: true` is the only way to bust it — so this only\n * takes effect in subclasses backed by a store with real expiration, like\n * `KVOntologyStore` (where it becomes the KV entry's `expirationTtl`).\n */\n ttlSeconds?: number;\n}\n\n/**\n * Fetches and caches the Diffbot KG ontology for a client. The base class\n * caches only in memory, for the lifetime of the instance; subclasses\n * override `read`/`write` to back the cache with a durable store (a\n * filesystem, a KV namespace, ...).\n */\nexport class OntologyStore {\n readonly client: DiffbotClient;\n protected readonly ttlSeconds: number;\n private inFlight: Promise<Ontology> | null = null;\n\n constructor(client: DiffbotClient, options: OntologyStoreOptions = {}) {\n this.client = client;\n this.ttlSeconds = options.ttlSeconds ?? 86_400;\n }\n\n /**\n * Resolve the ontology, from cache when possible. Concurrent calls share\n * one in-flight fetch rather than issuing duplicate requests; a rejected\n * fetch clears the in-flight memo so the next call retries instead of\n * replaying the same failure forever.\n */\n load(options: { refresh?: boolean } = {}): Promise<Ontology> {\n if (options.refresh) {\n this.inFlight = null;\n }\n if (!this.inFlight) {\n this.inFlight = this.resolve(options.refresh ?? false).catch((error: unknown) => {\n this.inFlight = null;\n throw error;\n });\n }\n return this.inFlight;\n }\n\n private async resolve(refresh: boolean): Promise<Ontology> {\n if (!refresh) {\n const cached = await this.read();\n if (cached !== undefined) {\n try {\n return Ontology.fromJson(cached);\n } catch {\n /* Corrupt cache entry: fall through to a live fetch below. */\n }\n }\n }\n const text = await dqlFetchOntologyText(this.client);\n await this.write(text);\n return Ontology.fromJson(text);\n }\n\n /** Read the cached ontology text, or `undefined` on a miss. Memory-only by default. */\n protected read(): Promise<string | undefined> {\n return Promise.resolve(undefined);\n }\n\n /** Persist ontology text after a fetch. No-op by default. */\n protected write(_text: string): Promise<void> {\n return Promise.resolve();\n }\n}\n\n/**\n * Structurally typed rather than importing `@cloudflare/workers-types`, so\n * the SDK takes no Cloudflare dependency — a `KVNamespace` binding satisfies\n * this directly.\n */\nexport interface KVLike {\n get(key: string): Promise<string | null>;\n put(key: string, value: string, options?: { expirationTtl?: number }): Promise<void>;\n delete(key: string): Promise<void>;\n}\n\nexport interface KVOntologyStoreOptions extends OntologyStoreOptions {\n /** Default `\"diffbot:ontology:v1\"`. Bump the suffix to force cache invalidation on a schema change. */\n key?: string;\n /**\n * After this many seconds, a cached entry is served immediately while a\n * refresh runs behind it (stale-while-revalidate) instead of being trusted\n * outright. 0 (default) disables SWR — a cached entry is trusted for its\n * full `ttlSeconds`. Should be less than `ttlSeconds`, or the KV entry\n * expires before it is ever considered stale.\n */\n staleAfterSeconds?: number;\n /**\n * TTL on the refresh lock that prevents concurrent refetches (cron, SWR,\n * manual). Default 60s — Cloudflare KV rejects `expirationTtl` below 60.\n */\n lockTtlSeconds?: number;\n /**\n * `ExecutionContext.waitUntil`. Without it, a background stale-while-revalidate\n * refresh is killed as soon as the response is returned, so SWR degrades to a\n * blocking refresh-on-expiry.\n */\n waitUntil?: (promise: Promise<unknown>) => void;\n}\n\n/**\n * KV-backed ontology cache for Cloudflare Workers. Ports the stampede\n * protection and stale-while-revalidate behavior of a production Worker's\n * hand-rolled ontology cache: a short-lived lock key prevents concurrent\n * refreshes from cron, SWR, and a manual refresh all refetching at once, and\n * a `refreshed_at` companion key lets a stale entry be served immediately\n * while a refresh runs in the background.\n */\nexport class KVOntologyStore extends OntologyStore {\n private readonly kv: KVLike;\n private readonly key: string;\n private readonly refreshedAtKey: string;\n private readonly lockKey: string;\n private readonly staleAfterSeconds: number;\n private readonly lockTtlSeconds: number;\n private readonly waitUntil: ((promise: Promise<unknown>) => void) | undefined;\n\n constructor(client: DiffbotClient, kv: KVLike, options: KVOntologyStoreOptions = {}) {\n super(client, options);\n this.kv = kv;\n this.key = options.key ?? \"diffbot:ontology:v1\";\n this.refreshedAtKey = `${this.key}:refreshed_at`;\n this.lockKey = `${this.key}:lock`;\n this.staleAfterSeconds = options.staleAfterSeconds ?? 0;\n this.lockTtlSeconds = options.lockTtlSeconds ?? 60;\n this.waitUntil = options.waitUntil;\n }\n\n override load(options: { refresh?: boolean } = {}): Promise<Ontology> {\n if (!options.refresh && this.staleAfterSeconds > 0) {\n return this.loadWithStaleWhileRevalidate();\n }\n return super.load(options);\n }\n\n private async loadWithStaleWhileRevalidate(): Promise<Ontology> {\n const [cached, refreshedAt] = await Promise.all([\n this.kv.get(this.key),\n this.kv.get(this.refreshedAtKey),\n ]);\n if (cached === null) {\n return super.load();\n }\n\n const age = refreshedAt ? (Date.now() - Number(refreshedAt)) / 1000 : Infinity;\n const isStale = age > this.staleAfterSeconds;\n const ontology = Ontology.fromJson(cached);\n\n if (isStale) {\n const refresh = super.load({ refresh: true }).catch(() => {\n /* Stale value already served; a failed background refresh just retries next time. */\n });\n if (this.waitUntil) {\n this.waitUntil(refresh);\n } else {\n await refresh;\n return super.load();\n }\n }\n\n return ontology;\n }\n\n protected override async read(): Promise<string | undefined> {\n const cached = await this.kv.get(this.key);\n return cached ?? undefined;\n }\n\n protected override async write(text: string): Promise<void> {\n /* Lock prevents concurrent refreshes from all refetching the same large payload. */\n if (await this.kv.get(this.lockKey)) {\n return;\n }\n await this.kv.put(this.lockKey, \"1\", { expirationTtl: this.lockTtlSeconds });\n try {\n await this.kv.put(this.key, text, { expirationTtl: this.ttlSeconds });\n await this.kv.put(this.refreshedAtKey, String(Date.now()), {\n expirationTtl: this.ttlSeconds,\n });\n } finally {\n await this.kv.delete(this.lockKey);\n }\n }\n}\n","import type { DiffbotClient } from \"./client.js\";\nimport { readBodyText, raiseForStatus } from \"./http.js\";\nimport type { JsonObject } from \"./json.js\";\n\nexport async function webSearch(\n client: DiffbotClient,\n text: string,\n options: { numResults?: number; maxTokens?: number } = {},\n): Promise<JsonObject> {\n const headers = { Authorization: `Bearer ${client.token}` };\n const params: Record<string, string | number> = { text };\n if (options.numResults !== undefined) params.size = options.numResults;\n if (options.maxTokens !== undefined) params.maxTokens = options.maxTokens;\n\n const response = await client.http.get(client.webSearchUrl, { headers, params });\n const body = await readBodyText(response);\n raiseForStatus(response, body);\n return JSON.parse(body) as JsonObject;\n}\n"],"mappings":"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","names":["CrawlEventType"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/node/index.ts
|
|
21
|
+
var node_exports = {};
|
|
22
|
+
__export(node_exports, {
|
|
23
|
+
FileOntologyStore: () => FileOntologyStore,
|
|
24
|
+
authConfig: () => authConfig,
|
|
25
|
+
defaultCredentialsPath: () => defaultCredentialsPath,
|
|
26
|
+
resolveToken: () => resolveToken
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(node_exports);
|
|
29
|
+
|
|
30
|
+
// src/node/auth.ts
|
|
31
|
+
var import_node_fs = require("fs");
|
|
32
|
+
var import_node_os = require("os");
|
|
33
|
+
var import_node_path = require("path");
|
|
34
|
+
var import_typescript = require("@diffbot/typescript");
|
|
35
|
+
var TOKEN_ENV_VAR = "DIFFBOT_API_TOKEN";
|
|
36
|
+
function defaultCredentialsPath() {
|
|
37
|
+
return (0, import_node_path.join)((0, import_node_os.homedir)(), ".diffbot", "credentials");
|
|
38
|
+
}
|
|
39
|
+
var authConfig = {};
|
|
40
|
+
function readCredentialsFile(path) {
|
|
41
|
+
if (!(0, import_node_fs.existsSync)(path)) {
|
|
42
|
+
return "";
|
|
43
|
+
}
|
|
44
|
+
const text = (0, import_node_fs.readFileSync)(path, "utf8");
|
|
45
|
+
for (const line of text.split("\n")) {
|
|
46
|
+
const trimmed = line.trim();
|
|
47
|
+
if (trimmed.startsWith(`${TOKEN_ENV_VAR}=`)) {
|
|
48
|
+
return trimmed.slice(TOKEN_ENV_VAR.length + 1).trim();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
53
|
+
function resolveToken(token, env) {
|
|
54
|
+
const fromEnv = (0, import_typescript.resolveTokenFromEnv)(token, env);
|
|
55
|
+
if (fromEnv) {
|
|
56
|
+
return fromEnv;
|
|
57
|
+
}
|
|
58
|
+
return readCredentialsFile(authConfig.credentialsPath ?? defaultCredentialsPath());
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/node/ontology-store.ts
|
|
62
|
+
var import_promises = require("fs/promises");
|
|
63
|
+
var import_node_path2 = require("path");
|
|
64
|
+
var import_typescript2 = require("@diffbot/typescript");
|
|
65
|
+
var FileOntologyStore = class extends import_typescript2.OntologyStore {
|
|
66
|
+
path;
|
|
67
|
+
constructor(client, path, options) {
|
|
68
|
+
super(client, options);
|
|
69
|
+
this.path = path;
|
|
70
|
+
}
|
|
71
|
+
async read() {
|
|
72
|
+
try {
|
|
73
|
+
return await (0, import_promises.readFile)(this.path, "utf8");
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error.code === "ENOENT") {
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async write(text) {
|
|
82
|
+
await (0, import_promises.mkdir)((0, import_node_path2.dirname)(this.path), { recursive: true });
|
|
83
|
+
await (0, import_promises.writeFile)(this.path, text);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
87
|
+
0 && (module.exports = {
|
|
88
|
+
FileOntologyStore,
|
|
89
|
+
authConfig,
|
|
90
|
+
defaultCredentialsPath,
|
|
91
|
+
resolveToken
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/node/index.ts","../../src/node/auth.ts","../../src/node/ontology-store.ts"],"sourcesContent":["export { authConfig, defaultCredentialsPath, resolveToken } from \"./auth.js\";\nexport { FileOntologyStore } from \"./ontology-store.js\";\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { resolveTokenFromEnv, type TokenSource } from \"@diffbot/typescript\";\n\nconst TOKEN_ENV_VAR = \"DIFFBOT_API_TOKEN\";\n\nexport function defaultCredentialsPath(): string {\n return join(homedir(), \".diffbot\", \"credentials\");\n}\n\n/** Mutable for tests; defaults to `~/.diffbot/credentials`. */\nexport const authConfig: { credentialsPath?: string } = {};\n\nfunction readCredentialsFile(path: string): string {\n if (!existsSync(path)) {\n return \"\";\n }\n const text = readFileSync(path, \"utf8\");\n for (const line of text.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(`${TOKEN_ENV_VAR}=`)) {\n return trimmed.slice(TOKEN_ENV_VAR.length + 1).trim();\n }\n }\n return \"\";\n}\n\n/**\n * Resolve a Diffbot API token from an explicit arg, an `env` object, then\n * `process.env`, then `~/.diffbot/credentials`. Superset of the core\n * `resolveTokenFromEnv` — same first three steps, plus the file fallback.\n */\nexport function resolveToken(token?: string | null, env?: TokenSource): string {\n const fromEnv = resolveTokenFromEnv(token, env);\n if (fromEnv) {\n return fromEnv;\n }\n return readCredentialsFile(authConfig.credentialsPath ?? defaultCredentialsPath());\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { OntologyStore, type OntologyStoreOptions } from \"@diffbot/typescript\";\nimport type { DiffbotClient } from \"@diffbot/typescript\";\n\n/**\n * Filesystem-backed ontology cache. Replaces the old `dqlRefreshOntology` +\n * `Ontology.fromPath` pair with a single read-through cache, consistent with\n * `KVOntologyStore` in core.\n */\nexport class FileOntologyStore extends OntologyStore {\n private readonly path: string;\n\n constructor(client: DiffbotClient, path: string, options?: OntologyStoreOptions) {\n super(client, options);\n this.path = path;\n }\n\n protected override async read(): Promise<string | undefined> {\n try {\n return await readFile(this.path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n }\n\n protected override async write(text: string): Promise<void> {\n await mkdir(dirname(this.path), { recursive: true });\n await writeFile(this.path, text);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,qBAAyC;AACzC,qBAAwB;AACxB,uBAAqB;AACrB,wBAAsD;AAEtD,IAAM,gBAAgB;AAEf,SAAS,yBAAiC;AAC/C,aAAO,2BAAK,wBAAQ,GAAG,YAAY,aAAa;AAClD;AAGO,IAAM,aAA2C,CAAC;AAEzD,SAAS,oBAAoB,MAAsB;AACjD,MAAI,KAAC,2BAAW,IAAI,GAAG;AACrB,WAAO;AAAA,EACT;AACA,QAAM,WAAO,6BAAa,MAAM,MAAM;AACtC,aAAW,QAAQ,KAAK,MAAM,IAAI,GAAG;AACnC,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,QAAQ,WAAW,GAAG,aAAa,GAAG,GAAG;AAC3C,aAAO,QAAQ,MAAM,cAAc,SAAS,CAAC,EAAE,KAAK;AAAA,IACtD;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,aAAa,OAAuB,KAA2B;AAC7E,QAAM,cAAU,uCAAoB,OAAO,GAAG;AAC9C,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AACA,SAAO,oBAAoB,WAAW,mBAAmB,uBAAuB,CAAC;AACnF;;;ACvCA,sBAA2C;AAC3C,IAAAA,oBAAwB;AACxB,IAAAC,qBAAyD;AAQlD,IAAM,oBAAN,cAAgC,iCAAc;AAAA,EAClC;AAAA,EAEjB,YAAY,QAAuB,MAAc,SAAgC;AAC/E,UAAM,QAAQ,OAAO;AACrB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAyB,OAAoC;AAC3D,QAAI;AACF,aAAO,UAAM,0BAAS,KAAK,MAAM,MAAM;AAAA,IACzC,SAAS,OAAO;AACd,UAAK,MAAgC,SAAS,UAAU;AACtD,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAyB,MAAM,MAA6B;AAC1D,cAAM,2BAAM,2BAAQ,KAAK,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,cAAM,2BAAU,KAAK,MAAM,IAAI;AAAA,EACjC;AACF;","names":["import_node_path","import_typescript"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { TokenSource, OntologyStore, DiffbotClient, OntologyStoreOptions } from '@diffbot/typescript';
|
|
2
|
+
|
|
3
|
+
declare function defaultCredentialsPath(): string;
|
|
4
|
+
/** Mutable for tests; defaults to `~/.diffbot/credentials`. */
|
|
5
|
+
declare const authConfig: {
|
|
6
|
+
credentialsPath?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a Diffbot API token from an explicit arg, an `env` object, then
|
|
10
|
+
* `process.env`, then `~/.diffbot/credentials`. Superset of the core
|
|
11
|
+
* `resolveTokenFromEnv` — same first three steps, plus the file fallback.
|
|
12
|
+
*/
|
|
13
|
+
declare function resolveToken(token?: string | null, env?: TokenSource): string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Filesystem-backed ontology cache. Replaces the old `dqlRefreshOntology` +
|
|
17
|
+
* `Ontology.fromPath` pair with a single read-through cache, consistent with
|
|
18
|
+
* `KVOntologyStore` in core.
|
|
19
|
+
*/
|
|
20
|
+
declare class FileOntologyStore extends OntologyStore {
|
|
21
|
+
private readonly path;
|
|
22
|
+
constructor(client: DiffbotClient, path: string, options?: OntologyStoreOptions);
|
|
23
|
+
protected read(): Promise<string | undefined>;
|
|
24
|
+
protected write(text: string): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { FileOntologyStore, authConfig, defaultCredentialsPath, resolveToken };
|