mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-29 10:50:58 +00:00
Fallback to Jiti when bun is unavailable
This commit is contained in:
@@ -77,6 +77,13 @@ function shouldRetryViaIsolatedCopy(error: unknown): boolean {
|
||||
return code === "ERR_MODULE_NOT_FOUND" && message.includes(`${path.sep}node_modules${path.sep}`);
|
||||
}
|
||||
|
||||
function isMissingExecutableError(error: unknown): boolean {
|
||||
if (!error || typeof error !== "object") {
|
||||
return false;
|
||||
}
|
||||
return "code" in error && error.code === "ENOENT";
|
||||
}
|
||||
|
||||
const SOURCE_FILE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
||||
|
||||
function resolveImportCandidates(basePath: string): string[] {
|
||||
@@ -232,6 +239,12 @@ export async function loadChannelConfigSurfaceModule(
|
||||
OPENCLAW_CONFIG_SURFACE_MODULE: path.resolve(candidatePath),
|
||||
},
|
||||
});
|
||||
if (result.error) {
|
||||
if (isMissingExecutableError(result.error)) {
|
||||
return null;
|
||||
}
|
||||
throw result.error;
|
||||
}
|
||||
if (result.status !== 0) {
|
||||
throw new Error(result.stderr || result.stdout || `bun loader failed for ${candidatePath}`);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { loadChannelConfigSurfaceModule } from "../../scripts/load-channel-config-surface.ts";
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
@@ -12,6 +12,25 @@ function makeTempRoot(prefix: string): string {
|
||||
return root;
|
||||
}
|
||||
|
||||
async function importLoaderWithMissingBun() {
|
||||
vi.resetModules();
|
||||
const spawnSync = vi.fn(() => ({
|
||||
error: Object.assign(new Error("bun not found"), { code: "ENOENT" }),
|
||||
status: null,
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
}));
|
||||
vi.doMock("node:child_process", () => ({ spawnSync }));
|
||||
|
||||
try {
|
||||
const imported = await import("../../scripts/load-channel-config-surface.ts");
|
||||
return { loadChannelConfigSurfaceModule: imported.loadChannelConfigSurfaceModule, spawnSync };
|
||||
} finally {
|
||||
vi.doUnmock("node:child_process");
|
||||
vi.resetModules();
|
||||
}
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
for (const dir of tempDirs.splice(0, tempDirs.length)) {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
@@ -19,6 +38,45 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("loadChannelConfigSurfaceModule", () => {
|
||||
it("falls back to Jiti when bun is unavailable", async () => {
|
||||
const repoRoot = makeTempRoot("openclaw-config-surface-");
|
||||
const packageRoot = path.join(repoRoot, "extensions", "demo");
|
||||
const modulePath = path.join(packageRoot, "src", "config-schema.js");
|
||||
|
||||
fs.mkdirSync(path.join(packageRoot, "src"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(packageRoot, "package.json"),
|
||||
JSON.stringify({ name: "@openclaw/demo", type: "module" }, null, 2),
|
||||
"utf8",
|
||||
);
|
||||
fs.writeFileSync(
|
||||
modulePath,
|
||||
[
|
||||
"export const DemoChannelConfigSchema = {",
|
||||
" schema: {",
|
||||
" type: 'object',",
|
||||
" properties: { ok: { type: 'string' } },",
|
||||
" },",
|
||||
"};",
|
||||
"",
|
||||
].join("\n"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const { loadChannelConfigSurfaceModule: loadWithMissingBun, spawnSync } =
|
||||
await importLoaderWithMissingBun();
|
||||
|
||||
await expect(loadWithMissingBun(modulePath, { repoRoot })).resolves.toMatchObject({
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
ok: { type: "string" },
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(spawnSync).toHaveBeenCalledWith("bun", expect.any(Array), expect.any(Object));
|
||||
});
|
||||
|
||||
it("retries from an isolated package copy when extension-local node_modules is broken", async () => {
|
||||
const repoRoot = makeTempRoot("openclaw-config-surface-");
|
||||
const packageRoot = path.join(repoRoot, "extensions", "demo");
|
||||
|
||||
Reference in New Issue
Block a user