feat(search): add Xquik as an X search provider
Xquik needs a GET request with x-api-key auth and a tweets envelope normalizer, neither of which the generic search fallback provides. Adds a dedicated request builder and normalizer, cursor pagination passthrough, result-based credit usage reporting, and a validateUrl probe so key validation hits the no-charge credits endpoint.
This commit is contained in:
@@ -347,6 +347,33 @@ function buildSearxngRequest(config, params) {
|
||||
};
|
||||
}
|
||||
|
||||
function buildXquikRequest(config, params) {
|
||||
const apiKey = params.token;
|
||||
if (!apiKey) throw new Error("Xquik requires an API key");
|
||||
|
||||
const queryType = getProviderSetting(params, "queryType");
|
||||
if (queryType && !["Latest", "Top"].includes(queryType)) {
|
||||
throw new Error("Xquik queryType must be Latest or Top");
|
||||
}
|
||||
|
||||
const qp = new URLSearchParams({
|
||||
q: params.query,
|
||||
limit: String(params.maxResults),
|
||||
});
|
||||
const cursor = getProviderSetting(params, "cursor");
|
||||
if (cursor) qp.set("cursor", cursor);
|
||||
if (queryType) qp.set("queryType", queryType);
|
||||
if (params.language) qp.set("language", params.language);
|
||||
|
||||
return {
|
||||
url: `${resolveBaseUrl(config, params)}?${qp}`,
|
||||
init: {
|
||||
method: "GET",
|
||||
headers: { Accept: "application/json", "x-api-key": apiKey },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ── Dispatcher ──────────────────────────────────────────────────────────
|
||||
|
||||
const BUILDERS = {
|
||||
@@ -360,6 +387,7 @@ const BUILDERS = {
|
||||
"searchapi": buildSearchApiRequest,
|
||||
"youcom": buildYouComRequest,
|
||||
"searxng": buildSearxngRequest,
|
||||
"xquik": buildXquikRequest,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user