Files
pinkudex/app/actions/actressLookup.ts
2026-05-26 22:46:00 +02:00

55 lines
1.8 KiB
TypeScript

"use server";
import { rawDb } from "@/lib/db/client";
import { reverseName } from "@/lib/jav/nameUtils";
export interface ActressLookupResult {
name: string;
match: { id: number; name: string; slug: string } | null;
}
/**
* For each input name, find an existing actress matching by:
* - canonical name (exact, case-insensitive)
* - any entry in alt_names (comma-separated)
* - the reversed-word-order form (e.g. "Atomi Shuri" matches "Shuri Atomi")
* Returns one row per input preserving order.
*/
export async function lookupActressesByNames(names: string[]): Promise<ActressLookupResult[]> {
const trimmed = names.map((n) => n.trim()).filter(Boolean);
if (trimmed.length === 0) return [];
const rows = rawDb.prepare(`SELECT id, name, slug, alt_names AS altNames FROM actresses`).all() as Array<{
id: number;
name: string;
slug: string;
altNames: string | null;
}>;
type Indexed = { id: number; name: string; slug: string; keys: Set<string> };
const indexed: Indexed[] = rows.map((r) => {
const keys = new Set<string>();
keys.add(r.name.toLowerCase());
const rev = reverseName(r.name);
if (rev) keys.add(rev.toLowerCase());
if (r.altNames) {
for (const part of r.altNames.split(/[,、,]/)) {
const t = part.trim().toLowerCase();
if (t) keys.add(t);
}
}
return { id: r.id, name: r.name, slug: r.slug, keys };
});
const findMatch = (q: string) => {
const lq = q.toLowerCase();
const lqRev = reverseName(q)?.toLowerCase() ?? null;
for (const r of indexed) {
if (r.keys.has(lq) || (lqRev && r.keys.has(lqRev))) {
return { id: r.id, name: r.name, slug: r.slug };
}
}
return null;
};
return trimmed.map((name) => ({ name, match: findMatch(name) }));
}