mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
SVG files were rejected by the convert endpoint because validateImageBuffer only recognized raster magic bytes. This adds text-based SVG detection, sanitization in the tool factory, and proper Sharp density handling so SVG-to-raster conversion works through the standard convert route.
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
/**
|
|
* Piscina worker that executes image tool processing in a worker thread.
|
|
*
|
|
* On first call, it imports all tool registration modules using a mock
|
|
* Fastify instance (only the registry-populating side effects are needed,
|
|
* not the HTTP route registrations). Subsequent calls reuse the populated
|
|
* registry for O(1) lookup.
|
|
*/
|
|
import { autoOrient } from "./auto-orient.js";
|
|
|
|
export interface WorkerInput {
|
|
toolId: string;
|
|
inputBuffer: Buffer;
|
|
settings: unknown;
|
|
filename: string;
|
|
inputFormat?: string;
|
|
}
|
|
|
|
export interface WorkerOutput {
|
|
buffer: Buffer;
|
|
filename: string;
|
|
contentType: string;
|
|
}
|
|
|
|
let registryReady = false;
|
|
|
|
async function ensureRegistry(): Promise<void> {
|
|
if (registryReady) return;
|
|
|
|
// Create a minimal mock that satisfies the register functions.
|
|
// createToolRoute calls app.post() (no-op here) and toolRegistry.set() (the part we want).
|
|
// AI tools also call app.post() and registerToolProcessFn() (also populates the registry).
|
|
const mockApp = {
|
|
post: () => {},
|
|
get: () => {},
|
|
log: { info: () => {}, warn: () => {}, error: () => {} },
|
|
};
|
|
|
|
const { registerToolRoutes } = await import("../routes/tools/index.js");
|
|
await registerToolRoutes(mockApp as never);
|
|
registryReady = true;
|
|
}
|
|
|
|
export default async function processInWorker(input: WorkerInput): Promise<WorkerOutput> {
|
|
await ensureRegistry();
|
|
|
|
const { getToolConfig } = await import("../routes/tool-factory.js");
|
|
const config = getToolConfig(input.toolId);
|
|
|
|
if (!config) {
|
|
throw new Error(`Tool "${input.toolId}" not found in worker registry`);
|
|
}
|
|
|
|
const buf = Buffer.from(input.inputBuffer);
|
|
const oriented = input.inputFormat === "svg" ? buf : await autoOrient(buf);
|
|
const result = await config.process(oriented, input.settings, input.filename);
|
|
|
|
return {
|
|
buffer: result.buffer,
|
|
filename: result.filename,
|
|
contentType: result.contentType,
|
|
};
|
|
}
|