pull/643/head^2
Travis Fischer 2024-05-26 15:41:18 -05:00
rodzic b57e798531
commit 2ea18abab2
5 zmienionych plików z 84 dodań i 4 usunięć

Wyświetl plik

@ -27,6 +27,7 @@
- perigon
- predict leads
- proxycurl
- searxng
- serpapi
- serper
- twitter
@ -43,7 +44,7 @@
- walter
- services
- exa - need to update to correct format
- searxng
- wolfram alpha
- wikipedia
- midjourney
- firecrawl

Wyświetl plik

@ -7,6 +7,7 @@ export * from './perigon-client.js'
export * from './predict-leads-client.js'
export * from './proxycurl-client.js'
export * from './scraper-client.js'
export * from './searxng-client.js'
export * from './serpapi-client.js'
export * from './serper-client.js'
export * from './twitter-client.js'

Wyświetl plik

@ -0,0 +1,77 @@
import defaultKy, { type KyInstance } from 'ky'
import { assert, getEnv, omit, pick, pruneUndefined } from '../utils.js'
export namespace searxng {
export interface SearchOptions {
query: string
categories?: string[]
engines?: string[]
language?: string
pageno?: number
}
export interface SearchResult {
title: string
url: string
img_src?: string
thumbnail_src?: string
thumbnail?: string
content?: string
author?: string
iframe_src?: string
}
export interface SearchResponse {
results: SearchResult[]
suggestions: string[]
}
}
/**
* @see https://docs.searxng.org
*/
export class SearxngClient {
readonly ky: KyInstance
readonly apiKey: string
readonly apiBaseUrl: string
constructor({
apiKey = getEnv('SEARXNG_API_KEY'),
apiBaseUrl = getEnv('SEARXNG_API_BASE_URL'),
ky = defaultKy
}: {
apiKey?: string
apiBaseUrl?: string
ky?: KyInstance
} = {}) {
assert(
apiKey,
'SearxngClient missing required "apiKey" (defaults to "SEARXNG_API_KEY")'
)
assert(
apiBaseUrl,
'SearxngClient missing required "apiBaseUrl" (defaults to "SEARXNG_API_BASE_URL")'
)
this.apiKey = apiKey
this.apiBaseUrl = apiBaseUrl
this.ky = ky.extend({ prefixUrl: apiBaseUrl })
}
async search(opts: searxng.SearchOptions): Promise<searxng.SearchResponse> {
const res = await this.ky
.get('search', {
searchParams: pruneUndefined({
...omit(opts, 'categories', 'engines'),
categories: opts.categories?.join(','),
engines: opts.categories?.join(','),
format: 'json'
})
})
.json<searxng.SearchResponse>()
return pick(res, 'results', 'suggestions')
}
}

Wyświetl plik

@ -12,7 +12,7 @@ export { default as assert } from 'tiny-invariant'
* ```
*/
export const omit = <
T extends Record<any, unknown>,
T extends Record<any, unknown> | object,
K extends keyof T = keyof T
>(
inputObj: T,
@ -33,7 +33,7 @@ export const omit = <
* ```
*/
export const pick = <
T extends Record<any, unknown>,
T extends Record<any, unknown> | object,
K extends keyof T = keyof T
>(
inputObj: T,
@ -47,7 +47,7 @@ export const pick = <
export function pruneUndefined<T extends Record<string, any>>(
obj: T
): NonNullable<T> {
): NonNullable<{ [K in keyof T]: Exclude<T[K], undefined> }> {
return Object.fromEntries(
Object.entries(obj).filter(([, value]) => value !== undefined)
) as NonNullable<T>

Wyświetl plik

@ -16,6 +16,7 @@
// "emitDecoratorMetadata": true,
"strict": true,
"strictNullChecks": true,
"noUncheckedIndexedAccess": true,
"forceConsistentCasingInFileNames": true,