Files
ChatLab/apps/cli/scripts/ensure-native.mjs
T
digua 78e41a65b5 refactor: migrate CLI from packages/server to apps/cli
Move the CLI application from packages/server/ to apps/cli/ to align
with the monorepo convention (apps/ for deployable applications,
packages/ for shared libraries). Rename package to @openchatlab/chatlab.

Also fix a bug in ensureToken() that used raw string manipulation to
write config.toml, causing duplicate token fields that corrupted the
TOML file. This led to config parse failures and user_data_dir being
overwritten with defaults. Now uses writeConfigField() for safe writes.
2026-05-19 21:33:00 +08:00

77 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
import { existsSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { spawnSync } from 'node:child_process'
const currentFile = fileURLToPath(import.meta.url)
const scriptDir = dirname(currentFile)
const serverDir = dirname(scriptDir)
const nativePath = resolve(serverDir, 'native/better_sqlite3.node')
const rebuildScript = resolve(scriptDir, 'rebuild-native.sh')
export function getNativeStatus(bindingPath, nodeExecutable = process.execPath) {
if (!existsSync(bindingPath)) {
return { ok: false, reason: 'missing', message: `Native binding not found: ${bindingPath}` }
}
const result = spawnSync(
nodeExecutable,
['-e', 'require(process.argv[1]); process.stdout.write(process.versions.modules)', bindingPath],
{ encoding: 'utf8' }
)
if (result.status === 0) {
return { ok: true, reason: 'valid', abi: result.stdout.trim() }
}
return {
ok: false,
reason: 'invalid',
message: (result.stderr || result.stdout || result.error?.message || 'Native binding failed to load').trim(),
}
}
function runRebuild() {
const result = spawnSync('bash', [rebuildScript], {
cwd: serverDir,
stdio: 'inherit',
})
if (result.status !== 0) {
process.exit(result.status || 1)
}
}
function main() {
const checkOnly = process.argv.includes('--check')
const status = getNativeStatus(nativePath)
if (status.ok) {
console.error(`[server native] better-sqlite3 ready (Node ABI ${status.abi})`)
return
}
if (checkOnly) {
console.error(`[server native] ${status.message}`)
process.exit(1)
}
console.error(`[server native] ${status.message}`)
console.error('[server native] Rebuilding better-sqlite3 for the current system Node.js...')
runRebuild()
const rebuilt = getNativeStatus(nativePath)
if (!rebuilt.ok) {
console.error(`[server native] Rebuild completed, but native binding is still unusable: ${rebuilt.message}`)
process.exit(1)
}
console.error(`[server native] better-sqlite3 ready (Node ABI ${rebuilt.abi})`)
}
if (process.argv[1] && currentFile === resolve(process.argv[1])) {
main()
}