diff --git a/apps/api/src/lib/format-decoders.ts b/apps/api/src/lib/format-decoders.ts index a45d8730..49ba3965 100644 --- a/apps/api/src/lib/format-decoders.ts +++ b/apps/api/src/lib/format-decoders.ts @@ -216,13 +216,23 @@ async function decodeBmp(buffer: Buffer): Promise { } async function decodeJxl(buffer: Buffer): Promise { - const cmd = await findMagickCmd(); const id = randomUUID(); const inputPath = join(tmpdir(), `jxl-in-${id}.jxl`); const outputPath = join(tmpdir(), `jxl-out-${id}.png`); try { await writeFile(inputPath, buffer); + + // Try djxl first (from libjxl-tools) — works even when ImageMagick + // lacks a JXL delegate (common on Ubuntu stock packages). + try { + await execFileAsync("djxl", [inputPath, outputPath], { timeout: 120_000 }); + return await readFile(outputPath); + } catch { + // djxl not available, fall back to ImageMagick + } + + const cmd = await findMagickCmd(); await execFileAsync(cmd, magickArgs(cmd, [inputPath, `png:${outputPath}`]), { timeout: 120_000, }); diff --git a/docker/Dockerfile b/docker/Dockerfile index a84e97cb..4236afa4 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -148,6 +148,7 @@ RUN for i in 1 2 3; do apt-get -o Acquire::Retries=3 update && break || sleep $( apt-get install -y --no-install-recommends \ tini \ imagemagick \ + libjxl-tools \ libraw-dev \ libopenexr-dev \ potrace \ diff --git a/playwright.docker.config.ts b/playwright.docker.config.ts index 86ed581c..c12b62c0 100644 --- a/playwright.docker.config.ts +++ b/playwright.docker.config.ts @@ -6,7 +6,8 @@ const authFile = path.join(__dirname, "test-results", ".auth", "user.json"); // Point raw-fetch tests (api.spec, security.spec, people.spec, rbac.spec) at // the Docker container instead of the dev-server default (port 13490). // Start the container with: SKIP_MUST_CHANGE_PASSWORD=true docker compose -f docker/docker-compose.yml up -d -process.env.API_URL ??= "http://localhost:1349"; +const containerUrl = process.env.BASE_URL || "http://localhost:1349"; +process.env.API_URL ??= containerUrl; export default defineConfig({ testDir: "./tests/e2e", @@ -19,7 +20,7 @@ export default defineConfig({ workers: 1, reporter: [["html", { open: "never" }], ["list"]], use: { - baseURL: "http://localhost:1349", + baseURL: containerUrl, screenshot: "only-on-failure", trace: "retain-on-failure", },