// resolve rnx's bundled assets (fonts, icons, sounds) // regardless of how the package was installed (source checkout, npm install, bunx). // // uses import.meta.url to derive the package root, then checks both // the source layout (public/) and npm-installed layout (public/). import { existsSync, readFileSync } from 'fs' import { dirname, resolve } from 'path' import { fileURLToPath } from 'url' import { rnxPublicBrand } from '../src/public-brand' // when bundled by esbuild, this file lives at dist-cli/bin.js // when running from source, this file lives at cli/resolve-assets.ts const thisDir = dirname(fileURLToPath(import.meta.url)) // walk up to find package root: look for package.json with the rnxsim package name function findPackageRoot(): string { let dir = thisDir for (let i = 0; i < 5; i++) { try { const pkgPath = resolve(dir, 'package.json') if (existsSync(pkgPath)) { const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) if (pkg.name === rnxPublicBrand.packageName) return dir } } catch {} dir = dirname(dir) } // fallback: assume one level up from this file return dirname(thisDir) } const packageRoot = findPackageRoot() export interface SootSimAssets { fontsDir: string iconsDir: string soundsDir: string packageRoot: string } export function resolveAssets(): SootSimAssets { // both source and npm-installed layouts use public/ at the package root const publicDir = resolve(packageRoot, 'public') const fontsDir = resolve(publicDir, 'fonts') const iconsDir = resolve(publicDir, 'icons') const soundsDir = resolve(publicDir, 'sounds') if (!existsSync(fontsDir)) { console.warn(`[rnx] warning: fonts directory not found at ${fontsDir}`) } return { fontsDir, iconsDir, soundsDir, packageRoot, } } // re-export packageRoot for use in CLI commands that need SOOTSIM_ROOT export { packageRoot }