@refkit/provider-brave 0.1.1 → 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/dist/index.d.ts +8 -1
- package/dist/index.js +26 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,13 @@ interface BraveConfig {
|
|
|
5
5
|
/** Brave safesearch: 'strict' (default) or 'off'. */
|
|
6
6
|
safesearch?: 'strict' | 'off';
|
|
7
7
|
}
|
|
8
|
+
interface BraveImageSearchOptions {
|
|
9
|
+
country?: string;
|
|
10
|
+
searchLang?: string;
|
|
11
|
+
count?: number;
|
|
12
|
+
safesearch?: 'strict' | 'off';
|
|
13
|
+
spellcheck?: boolean;
|
|
14
|
+
}
|
|
8
15
|
declare function brave(config: BraveConfig): _refkit_core.ReferenceProvider;
|
|
9
16
|
|
|
10
|
-
export { type BraveConfig, brave };
|
|
17
|
+
export { type BraveConfig, type BraveImageSearchOptions, brave };
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,24 @@ import {
|
|
|
3
3
|
defineProvider,
|
|
4
4
|
referenceId
|
|
5
5
|
} from "@refkit/core";
|
|
6
|
+
function braveSafeSearch(control, fallback) {
|
|
7
|
+
if (control === "off") return "off";
|
|
8
|
+
if (control === "strict" || control === "moderate") return "strict";
|
|
9
|
+
return fallback ?? "strict";
|
|
10
|
+
}
|
|
11
|
+
function setIfString(url, key, value, allowed) {
|
|
12
|
+
if (typeof value !== "string" || !value) return;
|
|
13
|
+
if (allowed && !allowed.includes(value)) return;
|
|
14
|
+
url.searchParams.set(key, value);
|
|
15
|
+
}
|
|
16
|
+
function setIfPositiveInt(url, key, value, max) {
|
|
17
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1) return;
|
|
18
|
+
url.searchParams.set(key, String(max ? Math.min(value, max) : value));
|
|
19
|
+
}
|
|
20
|
+
function setIfBoolean(url, key, value) {
|
|
21
|
+
if (typeof value !== "boolean") return;
|
|
22
|
+
url.searchParams.set(key, String(value));
|
|
23
|
+
}
|
|
6
24
|
function toReference(r) {
|
|
7
25
|
const rights = {
|
|
8
26
|
// open web → no license metadata → evaluateUse returns needs-review (never auto-allowed)
|
|
@@ -31,11 +49,18 @@ function brave(config) {
|
|
|
31
49
|
id: "brave",
|
|
32
50
|
modalities: ["image"],
|
|
33
51
|
queryFeatures: ["keyword"],
|
|
52
|
+
capabilities: { controls: ["safety"] },
|
|
34
53
|
async search(q, ctx) {
|
|
35
54
|
const url = new URL("https://api.search.brave.com/res/v1/images/search");
|
|
36
55
|
url.searchParams.set("q", q.text);
|
|
37
56
|
url.searchParams.set("count", String(Math.min(q.limit ?? 50, 200)));
|
|
38
|
-
url.searchParams.set("safesearch", config.safesearch
|
|
57
|
+
url.searchParams.set("safesearch", braveSafeSearch(q.controls?.safety, config.safesearch));
|
|
58
|
+
const opts = q.providerOptions;
|
|
59
|
+
setIfString(url, "country", opts?.country);
|
|
60
|
+
setIfString(url, "search_lang", opts?.searchLang);
|
|
61
|
+
setIfPositiveInt(url, "count", opts?.count, 200);
|
|
62
|
+
setIfString(url, "safesearch", opts?.safesearch, ["strict", "off"]);
|
|
63
|
+
setIfBoolean(url, "spellcheck", opts?.spellcheck);
|
|
39
64
|
const res = await ctx.fetch(url.toString(), {
|
|
40
65
|
headers: { "X-Subscription-Token": config.token, Accept: "application/json" },
|
|
41
66
|
signal: ctx.signal
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n defineProvider, referenceId,\n type Reference, type RightsRecord, type NormalizedQuery, type ProviderContext,\n} from '@refkit/core'\n\nexport interface BraveConfig {\n token: string\n /** Brave safesearch: 'strict' (default) or 'off'. */\n safesearch?: 'strict' | 'off'\n}\n\ninterface BraveImageResult {\n title: string\n url: string // the source webpage (canonical link)\n source: string // domain\n thumbnail: { src: string } // Brave-proxied thumbnail (safe to display)\n properties: { url: string; placeholder?: string } // origin/CDN full image (do NOT rehost)\n}\ninterface BraveResponse { results: BraveImageResult[] }\n\nfunction toReference(r: BraveImageResult): Reference {\n const rights: RightsRecord = {\n // open web → no license metadata → evaluateUse returns needs-review (never auto-allowed)\n license: 'unknown',\n // only the Brave-proxied thumbnail is safe to show; never rehost properties.url (origin image)\n rehostPolicy: 'thumbnail-only',\n raw: { sourceTerms: '', sourceUrl: r.url },\n }\n return {\n id: referenceId('brave', r.properties.url), // origin image URL is the most stable identifier\n modality: 'image',\n title: r.title,\n source: { providerId: 'brave', sourceUrl: r.url },\n canonicalUrl: r.url, // the source webpage, not the raw image bytes\n rights,\n verifiedAt: new Date().toISOString(),\n thumbnail: { url: r.thumbnail.src },\n relevance: 0,\n raw: r,\n }\n}\n\nexport function brave(config: BraveConfig) {\n return defineProvider({\n id: 'brave',\n modalities: ['image'],\n queryFeatures: ['keyword'],\n async search(q: NormalizedQuery, ctx: ProviderContext): Promise<Reference[]> {\n const url = new URL('https://api.search.brave.com/res/v1/images/search')\n url.searchParams.set('q', q.text)\n url.searchParams.set('count', String(Math.min(q.limit ?? 50, 200)))\n url.searchParams.set('safesearch', config.safesearch
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n defineProvider, referenceId,\n type Reference, type RightsRecord, type NormalizedQuery, type ProviderContext, type SearchSafety,\n} from '@refkit/core'\n\nexport interface BraveConfig {\n token: string\n /** Brave safesearch: 'strict' (default) or 'off'. */\n safesearch?: 'strict' | 'off'\n}\n\nexport interface BraveImageSearchOptions {\n country?: string\n searchLang?: string\n count?: number\n safesearch?: 'strict' | 'off'\n spellcheck?: boolean\n}\n\ninterface BraveImageResult {\n title: string\n url: string // the source webpage (canonical link)\n source: string // domain\n thumbnail: { src: string } // Brave-proxied thumbnail (safe to display)\n properties: { url: string; placeholder?: string } // origin/CDN full image (do NOT rehost)\n}\ninterface BraveResponse { results: BraveImageResult[] }\n\nfunction braveSafeSearch(control: SearchSafety | undefined, fallback: BraveConfig['safesearch']): 'strict' | 'off' {\n if (control === 'off') return 'off'\n if (control === 'strict' || control === 'moderate') return 'strict'\n return fallback ?? 'strict'\n}\n\nfunction setIfString(url: URL, key: string, value: unknown, allowed?: readonly string[]) {\n if (typeof value !== 'string' || !value) return\n if (allowed && !allowed.includes(value)) return\n url.searchParams.set(key, value)\n}\n\nfunction setIfPositiveInt(url: URL, key: string, value: unknown, max?: number) {\n if (typeof value !== 'number' || !Number.isInteger(value) || value < 1) return\n url.searchParams.set(key, String(max ? Math.min(value, max) : value))\n}\n\nfunction setIfBoolean(url: URL, key: string, value: unknown) {\n if (typeof value !== 'boolean') return\n url.searchParams.set(key, String(value))\n}\n\nfunction toReference(r: BraveImageResult): Reference {\n const rights: RightsRecord = {\n // open web → no license metadata → evaluateUse returns needs-review (never auto-allowed)\n license: 'unknown',\n // only the Brave-proxied thumbnail is safe to show; never rehost properties.url (origin image)\n rehostPolicy: 'thumbnail-only',\n raw: { sourceTerms: '', sourceUrl: r.url },\n }\n return {\n id: referenceId('brave', r.properties.url), // origin image URL is the most stable identifier\n modality: 'image',\n title: r.title,\n source: { providerId: 'brave', sourceUrl: r.url },\n canonicalUrl: r.url, // the source webpage, not the raw image bytes\n rights,\n verifiedAt: new Date().toISOString(),\n thumbnail: { url: r.thumbnail.src },\n relevance: 0,\n raw: r,\n }\n}\n\nexport function brave(config: BraveConfig) {\n return defineProvider({\n id: 'brave',\n modalities: ['image'],\n queryFeatures: ['keyword'],\n capabilities: { controls: ['safety'] },\n async search(q: NormalizedQuery, ctx: ProviderContext): Promise<Reference[]> {\n const url = new URL('https://api.search.brave.com/res/v1/images/search')\n url.searchParams.set('q', q.text)\n url.searchParams.set('count', String(Math.min(q.limit ?? 50, 200)))\n url.searchParams.set('safesearch', braveSafeSearch(q.controls?.safety, config.safesearch))\n const opts = q.providerOptions as BraveImageSearchOptions | undefined\n setIfString(url, 'country', opts?.country)\n setIfString(url, 'search_lang', opts?.searchLang)\n setIfPositiveInt(url, 'count', opts?.count, 200)\n setIfString(url, 'safesearch', opts?.safesearch, ['strict', 'off'])\n setIfBoolean(url, 'spellcheck', opts?.spellcheck)\n const res = await ctx.fetch(url.toString(), {\n headers: { 'X-Subscription-Token': config.token, Accept: 'application/json' },\n signal: ctx.signal,\n })\n if (!res.ok) throw new Error(`brave search failed: ${res.status}`)\n const json = (await res.json()) as BraveResponse\n return json.results.map(toReference)\n },\n })\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAAgB;AAAA,OAEX;AAyBP,SAAS,gBAAgB,SAAmC,UAAuD;AACjH,MAAI,YAAY,MAAO,QAAO;AAC9B,MAAI,YAAY,YAAY,YAAY,WAAY,QAAO;AAC3D,SAAO,YAAY;AACrB;AAEA,SAAS,YAAY,KAAU,KAAa,OAAgB,SAA6B;AACvF,MAAI,OAAO,UAAU,YAAY,CAAC,MAAO;AACzC,MAAI,WAAW,CAAC,QAAQ,SAAS,KAAK,EAAG;AACzC,MAAI,aAAa,IAAI,KAAK,KAAK;AACjC;AAEA,SAAS,iBAAiB,KAAU,KAAa,OAAgB,KAAc;AAC7E,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,EAAG;AACxE,MAAI,aAAa,IAAI,KAAK,OAAO,MAAM,KAAK,IAAI,OAAO,GAAG,IAAI,KAAK,CAAC;AACtE;AAEA,SAAS,aAAa,KAAU,KAAa,OAAgB;AAC3D,MAAI,OAAO,UAAU,UAAW;AAChC,MAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AACzC;AAEA,SAAS,YAAY,GAAgC;AACnD,QAAM,SAAuB;AAAA;AAAA,IAE3B,SAAS;AAAA;AAAA,IAET,cAAc;AAAA,IACd,KAAK,EAAE,aAAa,IAAI,WAAW,EAAE,IAAI;AAAA,EAC3C;AACA,SAAO;AAAA,IACL,IAAI,YAAY,SAAS,EAAE,WAAW,GAAG;AAAA;AAAA,IACzC,UAAU;AAAA,IACV,OAAO,EAAE;AAAA,IACT,QAAQ,EAAE,YAAY,SAAS,WAAW,EAAE,IAAI;AAAA,IAChD,cAAc,EAAE;AAAA;AAAA,IAChB;AAAA,IACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,WAAW,EAAE,KAAK,EAAE,UAAU,IAAI;AAAA,IAClC,WAAW;AAAA,IACX,KAAK;AAAA,EACP;AACF;AAEO,SAAS,MAAM,QAAqB;AACzC,SAAO,eAAe;AAAA,IACpB,IAAI;AAAA,IACJ,YAAY,CAAC,OAAO;AAAA,IACpB,eAAe,CAAC,SAAS;AAAA,IACzB,cAAc,EAAE,UAAU,CAAC,QAAQ,EAAE;AAAA,IACrC,MAAM,OAAO,GAAoB,KAA4C;AAC3E,YAAM,MAAM,IAAI,IAAI,mDAAmD;AACvE,UAAI,aAAa,IAAI,KAAK,EAAE,IAAI;AAChC,UAAI,aAAa,IAAI,SAAS,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC;AAClE,UAAI,aAAa,IAAI,cAAc,gBAAgB,EAAE,UAAU,QAAQ,OAAO,UAAU,CAAC;AACzF,YAAM,OAAO,EAAE;AACf,kBAAY,KAAK,WAAW,MAAM,OAAO;AACzC,kBAAY,KAAK,eAAe,MAAM,UAAU;AAChD,uBAAiB,KAAK,SAAS,MAAM,OAAO,GAAG;AAC/C,kBAAY,KAAK,cAAc,MAAM,YAAY,CAAC,UAAU,KAAK,CAAC;AAClE,mBAAa,KAAK,cAAc,MAAM,UAAU;AAChD,YAAM,MAAM,MAAM,IAAI,MAAM,IAAI,SAAS,GAAG;AAAA,QAC1C,SAAS,EAAE,wBAAwB,OAAO,OAAO,QAAQ,mBAAmB;AAAA,QAC5E,QAAQ,IAAI;AAAA,MACd,CAAC;AACD,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,wBAAwB,IAAI,MAAM,EAAE;AACjE,YAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,aAAO,KAAK,QAAQ,IAAI,WAAW;AAAA,IACrC;AAAA,EACF,CAAC;AACH;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refkit/provider-brave",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Brave Search web-discovery provider satellite for refkit — open-web image breadth, license:unknown (use-gated to needs-review).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@refkit/core": "0.
|
|
27
|
+
"@refkit/core": "0.4.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@refkit/provider-openverse": "0.
|
|
30
|
+
"@refkit/provider-openverse": "0.2.0"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|