You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.7 KiB
61 lines
1.7 KiB
import { LANGUAGE_TOOL_URL } from '@/constants' |
|
import { electronAwareFetch } from '@/lib/electron-aware-fetch' |
|
import logger from '@/lib/logger' |
|
|
|
export type LanguageToolMatch = { |
|
offset: number |
|
length: number |
|
message: string |
|
replacements?: Array<{ value: string }> |
|
rule?: { id?: string; description?: string } |
|
} |
|
|
|
export type LanguageToolCheckResponse = { |
|
matches?: LanguageToolMatch[] |
|
software?: { name?: string; version?: string } |
|
language?: { name?: string; code?: string } |
|
} |
|
|
|
function checkUrl(): string | null { |
|
const base = LANGUAGE_TOOL_URL.trim().replace(/\/$/u, '') |
|
if (!base) return null |
|
return `${base}/v2/check` |
|
} |
|
|
|
export async function languageToolCheck( |
|
text: string, |
|
language: string, |
|
signal?: AbortSignal |
|
): Promise<LanguageToolCheckResponse> { |
|
const url = checkUrl() |
|
if (!url) { |
|
return { matches: [] } |
|
} |
|
const body = new URLSearchParams() |
|
body.set('text', text) |
|
body.set('language', language) |
|
body.set('enabledOnly', 'false') |
|
|
|
const res = await electronAwareFetch(url, { |
|
method: 'POST', |
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
|
body: body.toString(), |
|
signal |
|
}) |
|
if (!res.ok) { |
|
const errText = await res.text().catch(() => '') |
|
logger.warn('[LanguageTool] HTTP error', { status: res.status, errText: errText.slice(0, 200) }) |
|
throw new Error(`LanguageTool: ${res.status}`) |
|
} |
|
const json = (await res.json()) as LanguageToolCheckResponse |
|
logger.info('[AdvancedLab] LanguageTool check', { |
|
language, |
|
textChars: text.length, |
|
matchCount: json.matches?.length ?? 0 |
|
}) |
|
return json |
|
} |
|
|
|
export function isLanguageToolConfigured(): boolean { |
|
return Boolean(checkUrl()) |
|
}
|
|
|