mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-26 17:12:27 +03:00
⭐5 — Provider x-search de primeira classe (SuperGrok/xAI x_search) em POST /v1/search e MCP omniroute_x_search. Fallback de credenciais xai-oauth→xao→xai; distinto de web search e do X Developer MCP. Reconciliado com o release tip (que já incluía #10981 "skip catalog-default SearXNG" deste mesmo lote): merge trouxe 5 conflitos reais de contagem gerada (llm.txt/README.md/AGENTS.md/PROVIDER_REFERENCE.md/SVGs/46 mirrors i18n, todos verificados como bump puro 347→348, sem perda de conteúdo do HEAD) + 1 conflito real de mergeable=CONFLICTING. Durante a validação, os 3 testes novos de SearXNG expuseram um bug real de interação com #10981: `isUnconfiguredLoopbackSearchProvider()` checava o baseUrl ESTÁTICO do catálogo em vez do baseUrl efetivo (após override de `provider_options.baseUrl` ou `providerSpecificData.baseUrl` da conexão), então QUALQUER request a searxng-search — mesmo com override customizado — era rejeitado como se fosse o default não-configurado. Corrigido em `open-sse/handlers/search.ts` (resolve o baseUrl efetivo via `resolveSearchBaseUrl()` antes do skip-check, tanto para o provider primário quanto o alternate). Um teste do próprio #10988 que assumia o comportamento pré-#10981 (default localhost:8888 sempre atendido) foi atualizado para refletir o comportamento já mesclado e intencional (503 quando não configurado). Validação completa: typecheck limpo, 70/70 testes unit (search-route/search-registry/x-search-provider/searxng-loopback-default), 24/24 vitest MCP, 14/14 integration (search-providers-catalog), lint limpo nos arquivos tocados, docs-counts-sync OK (2 drifts soft pré-existentes, não relacionados), gates estáticos (file-size/complexity/cognitive/dead-code/changelog) todos OK.
55 lines
2.6 KiB
TypeScript
55 lines
2.6 KiB
TypeScript
// Guards the native `require` shape that webpack silently rewrites when the
|
|
// module specifier (or the require itself) is not statically analyzable.
|
|
//
|
|
// This failure cannot be caught by running the code: under `tsx`/`node --test` the
|
|
// injected loader behaves normally, so the existing driverFactory tests pass in BOTH
|
|
// the broken and fixed shapes. The damage only appears in a packaged Next server build.
|
|
// The sql.js fallback is covered separately through package assembly and installed-
|
|
// artifact boot/write/read outcomes; do not pin another resolver implementation here.
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
|
|
function readSource(relativePath: string): string {
|
|
return fs.readFileSync(path.join(repoRoot, relativePath), "utf8");
|
|
}
|
|
|
|
/**
|
|
* Strips comments before shape-matching. Both files document the rewritten forms they
|
|
* must avoid, so a scan of the raw text matches its own warning and fails on the FIXED
|
|
* source — a guard that can only ever be satisfied by deleting the explanation.
|
|
*/
|
|
function stripComments(source: string): string {
|
|
return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^[ \t]*\/\/.*$/gm, "");
|
|
}
|
|
|
|
test("sync driver cascade requires each SQLite module by literal specifier", () => {
|
|
const driverFactory = stripComments(readSource("src/lib/db/adapters/driverFactory.ts"));
|
|
|
|
// Positive anchor: proves the read hit the real, non-empty module (#8619).
|
|
assert.match(driverFactory, /^export function createSyncDriverFactory\(/m);
|
|
|
|
// The production loader must be the literal-specifier wrapper, never `_require`
|
|
// itself — passing `_require` through the `load` parameter is exactly what makes
|
|
// webpack substitute its missing-module stub.
|
|
assert.match(
|
|
driverFactory,
|
|
/const openSyncDriver = createSyncDriverFactory\((?:requireSqliteDriver|\w+)(?:,\s*createBetterSqliteProbe\(\{\}\))?\)/
|
|
);
|
|
assert.match(driverFactory, /^export function tryOpenSync\($/m);
|
|
assert.doesNotMatch(driverFactory, /createSyncDriverFactory\(\s*_require\s*\)/);
|
|
|
|
// Every driver the cascade can ask for needs a direct `_require("<literal>")` so
|
|
// webpack emits a real external for it.
|
|
for (const moduleName of ["bun:sqlite", "better-sqlite3", "node:sqlite"]) {
|
|
assert.ok(
|
|
driverFactory.includes(`_require("${moduleName}")`),
|
|
`driverFactory must call _require("${moduleName}") with a literal specifier so webpack emits an external for it`
|
|
);
|
|
}
|
|
});
|