mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: sync API docs, register content-aware-resize, normalize tool counts
- Fix 23 OpenAPI schema discrepancies across 16+ tools (wrong ranges, missing fields, incorrect schemas for gif-tools/collage/ocr) - Add content-aware-resize to canonical TOOLS array and landing BentoGrid - Normalize tool count to 47 across README, docs, landing, i18n, OpenAPI - Remove dead "automation" ToolCategory variant - Add BMP and JPEG XL format decoding via ImageMagick - Add libopenexr-dev to Docker runtime image - Update e2e test selectors for current pipeline builder UI
This commit is contained in:
@@ -8,7 +8,7 @@ import { promisify } from "node:util";
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
/** Formats that need external CLI tools (not decodable by Sharp). */
|
||||
const CLI_DECODED_FORMATS = new Set(["raw", "ico", "tga", "psd", "exr", "hdr"]);
|
||||
const CLI_DECODED_FORMATS = new Set(["raw", "ico", "tga", "psd", "exr", "hdr", "bmp", "jxl"]);
|
||||
|
||||
export function needsCliDecode(format: string): boolean {
|
||||
return CLI_DECODED_FORMATS.has(format);
|
||||
@@ -32,6 +32,10 @@ export async function decodeToSharpCompat(buffer: Buffer, format: string): Promi
|
||||
return decodeExr(buffer);
|
||||
case "hdr":
|
||||
return decodeHdr(buffer);
|
||||
case "bmp":
|
||||
return decodeBmp(buffer);
|
||||
case "jxl":
|
||||
return decodeJxl(buffer);
|
||||
default:
|
||||
return buffer;
|
||||
}
|
||||
@@ -192,3 +196,39 @@ async function decodeHdr(buffer: Buffer): Promise<Buffer> {
|
||||
await rm(outputPath, { force: true }).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
async function decodeBmp(buffer: Buffer): Promise<Buffer> {
|
||||
const cmd = await findMagickCmd();
|
||||
const id = randomUUID();
|
||||
const inputPath = join(tmpdir(), `bmp-in-${id}.bmp`);
|
||||
const outputPath = join(tmpdir(), `bmp-out-${id}.png`);
|
||||
|
||||
try {
|
||||
await writeFile(inputPath, buffer);
|
||||
await execFileAsync(cmd, magickArgs(cmd, [inputPath, `png:${outputPath}`]), {
|
||||
timeout: 120_000,
|
||||
});
|
||||
return await readFile(outputPath);
|
||||
} finally {
|
||||
await rm(inputPath, { force: true }).catch(() => {});
|
||||
await rm(outputPath, { force: true }).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
async function decodeJxl(buffer: Buffer): Promise<Buffer> {
|
||||
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);
|
||||
await execFileAsync(cmd, magickArgs(cmd, [inputPath, `png:${outputPath}`]), {
|
||||
timeout: 120_000,
|
||||
});
|
||||
return await readFile(outputPath);
|
||||
} finally {
|
||||
await rm(inputPath, { force: true }).catch(() => {});
|
||||
await rm(outputPath, { force: true }).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user