import { readdir, stat } from "node:fs/promises"; import { join, dirname } from "node:path"; import { createRequire } from "node:module"; async function find(path: string, name: string): Promise { for (const file of await readdir(path, { withFileTypes: true })) { if (file.isDirectory()) { const found = await find(join(file.parentPath, file.name), name); if (found) return found; } else if (file.isFile()) { if (file.name === name) return join(file.parentPath, file.name); } } return null; } async function isFile(path: string): Promise { try { const st = await stat(path); return st.isFile(); } catch { return false; } } async function getPackageJsonDir(path: string): Promise { if (await isFile(join(path, "package.json"))) return path; const next = dirname(path); if (next === path) return null; return getPackageJsonDir(next); } export async function findNative( module: string, native: string ): Promise { const path = await getPackageJsonDir( createRequire(import.meta.url).resolve(module) ); if (!path) throw new Error(`Cannot find module directory for ${module}`); const file = await find(path, native); if (!file) throw new Error( `Cannot find native ${native} of package ${module} in ${path}` ); return file; } export async function tryFindNative( module: string, native: string ): Promise { try { return await findNative(module, native); } catch (e) { console.warn(e); return null; } } export async function findNatives(): Promise { return { sqlite: await tryFindNative("better-sqlite3", "better_sqlite3.node"), }; }