/** * When optional native deps (e.g. @tailwindcss/oxide-*) fail to install (permissions, npm bugs), * fetch the correct platform package via npm pack and copy the .node file into vendor/. */ import { execSync } from 'node:child_process' import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync } from 'node:fs' import { join, dirname } from 'node:path' import { fileURLToPath } from 'node:url' const __dirname = dirname(fileURLToPath(import.meta.url)) const root = join(__dirname, '..') const vendorDir = join(root, 'vendor') function isMusl() { try { return execSync('ldd --version', { encoding: 'utf8' }).includes('musl') } catch { return false } } function detectLinuxX64Oxide() { if (process.platform !== 'linux' || process.arch !== 'x64') return null return isMusl() ? { pkg: '@tailwindcss/oxide-linux-x64-musl', version: '4.2.2', nodeName: 'tailwindcss-oxide.linux-x64-musl.node' } : { pkg: '@tailwindcss/oxide-linux-x64-gnu', version: '4.2.2', nodeName: 'tailwindcss-oxide.linux-x64-gnu.node' } } function tryResolveOxidePackage(spec) { const sub = spec.pkg.replace('@tailwindcss/', '') const direct = join(root, 'node_modules', '@tailwindcss', sub, 'package.json') if (existsSync(direct)) return true return false } function ensure() { const spec = detectLinuxX64Oxide() if (!spec) return if (tryResolveOxidePackage(spec)) return const outPath = join(vendorDir, spec.nodeName) if (existsSync(outPath)) return mkdirSync(vendorDir, { recursive: true }) const tmp = join(__dirname, '.native-tmp') rmSync(tmp, { recursive: true, force: true }) mkdirSync(tmp, { recursive: true }) execSync(`npm pack ${spec.pkg}@${spec.version}`, { cwd: tmp, stdio: 'inherit' }) const tgz = readdirSync(tmp).find((f) => f.endsWith('.tgz')) if (!tgz) throw new Error('ensure-native-bindings: npm pack produced no .tgz') execSync(`tar -xzf "${tgz}"`, { cwd: tmp, stdio: 'inherit' }) const nodeSrc = join(tmp, 'package', spec.nodeName) if (!existsSync(nodeSrc)) { throw new Error(`ensure-native-bindings: missing ${nodeSrc}`) } copyFileSync(nodeSrc, outPath) rmSync(tmp, { recursive: true, force: true }) } ensure()