GitNexus/gitnexus/test/unit/lbug-native-check.test.ts
Ofek Gabay bfe8a87831
fix: actionable error + docs for pnpm dlx / pnpx native-load crash (#307) (#1967)
* fix: guide pnpm dlx/pnpx users through skipped native install

`pnpm dlx gitnexus serve` (and `pnpx gitnexus`) crash with a raw
`ERR_DLOPEN_FAILED` stack trace because @ladybugdb/core's native addon
(lbugjs.node) is placed by a postinstall script, and dlx/pnpx run
ephemerally without executing lifecycle scripts.

The existing checkLbugNative() guard already catches the missing binary
for serve/mcp/analyze, but its guidance only mentioned bun and
--ignore-scripts. Extend the message to call out the common pnpm dlx /
pnpx case and the fix (`pnpm add -g gitnexus && pnpm approve-builds -g`,
or use npx/npm). Add a matching README troubleshooting section.

This does not make `pnpm dlx` itself work — that requires a runtime
fallback in @ladybugdb/core. It turns the crash into actionable guidance.

Refs #307

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: add pnpm --allow-build dlx option to native-check guidance

Incorporates collaborator feedback (magyargergo): pnpm's security model
allows `dlx` to run build scripts when you pass `--allow-build` for each
native dep. Add this as the first/preferred pnpm-dlx path in the error
message, README troubleshooting section, and test assertion. Drop the
now-incorrect claim that `pnpm dlx` "cannot be made to work directly".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address PR review on pnpm dlx native-load guidance

Replace removed pnpm approve-builds -g with add -g --allow-build flags,
qualify npm 11 npx caveats, use serve in examples, extend load-failure hints,
and assert --allow-build precedes dlx in tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 05:54:25 +01:00

52 lines
2 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import os from 'os';
import path from 'path';
import fs from 'fs/promises';
import { checkLbugNative } from '../../src/core/lbug/native-check.js';
describe('checkLbugNative', () => {
it('returns ok:true when the real @ladybugdb/core binary is present', () => {
const result = checkLbugNative();
expect(result.ok).toBe(true);
expect(result.binaryPath).toBeDefined();
expect(result.message).toBeUndefined();
});
it('returns ok:false with repair instructions when lbugjs.node is missing', async () => {
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'lbug-check-'));
try {
await fs.writeFile(path.join(tmpDir, 'install.js'), '');
const result = checkLbugNative(tmpDir);
expect(result.ok).toBe(false);
expect(result.message).toContain('missing');
expect(result.message).toContain('install.js');
expect(result.message).toContain('trustedDependencies');
expect(result.message).toContain('ignore-scripts');
expect(result.message).toContain('--allow-build=@ladybugdb/core');
expect(result.message).toContain('pnpm add -g --allow-build=@ladybugdb/core');
const allowBuildIdx = result.message!.indexOf('--allow-build=@ladybugdb/core');
const dlxIdx = result.message!.indexOf('dlx gitnexus');
expect(allowBuildIdx).toBeGreaterThanOrEqual(0);
expect(dlxIdx).toBeGreaterThan(allowBuildIdx);
} finally {
await fs.rm(tmpDir, { recursive: true, force: true });
}
});
it('returns ok:false when lbugjs.node exists but is unloadable (zero-byte)', async () => {
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'lbug-check-'));
try {
await fs.writeFile(path.join(tmpDir, 'lbugjs.node'), Buffer.alloc(0));
const result = checkLbugNative(tmpDir);
expect(result.ok).toBe(false);
expect(result.message).toContain('failed to load');
expect(result.message).toContain('install.js');
} finally {
await fs.rm(tmpDir, { recursive: true, force: true });
}
});
});