fix(image-service): resolve next.js build crash and strict TS lint warnings for ci deploy

This commit is contained in:
2026-02-22 22:14:35 +01:00
parent 5f7a254fcb
commit c00f4e5ea5
5 changed files with 65 additions and 44 deletions

View File

@@ -1,6 +1,13 @@
import mintelNextConfig from "@mintel/next-config";
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
serverExternalPackages: [
"@mintel/image-processor",
"@tensorflow/tfjs-node",
"sharp",
"canvas",
],
};
export default mintelNextConfig(nextConfig);

View File

@@ -1,45 +1,60 @@
import { NextRequest, NextResponse } from 'next/server';
import { processImageWithSmartCrop } from '@mintel/image-processor';
import { NextRequest, NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export const runtime = "nodejs";
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const url = searchParams.get('url');
let width = parseInt(searchParams.get('w') || '800');
let height = parseInt(searchParams.get('h') || '600');
let q = parseInt(searchParams.get('q') || '80');
const { searchParams } = new URL(request.url);
const url = searchParams.get("url");
const width = parseInt(searchParams.get("w") || "800");
const height = parseInt(searchParams.get("h") || "600");
const q = parseInt(searchParams.get("q") || "80");
if (!url) {
return NextResponse.json({ error: 'Missing url parameter' }, { status: 400 });
if (!url) {
return NextResponse.json(
{ error: "Missing url parameter" },
{ status: 400 },
);
}
try {
// 1. Fetch image from original URL
const response = await fetch(url);
if (!response.ok) {
return NextResponse.json(
{ error: "Failed to fetch original image" },
{ status: response.status },
);
}
try {
// 1. Fetch image from original URL
const response = await fetch(url);
if (!response.ok) {
return NextResponse.json({ error: 'Failed to fetch original image' }, { status: response.status });
}
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
// Dynamically import to prevent Next.js from trying to bundle tfjs-node/sharp locally at build time
const { processImageWithSmartCrop } =
await import("@mintel/image-processor");
// 2. Process image with Face-API and Sharp
const processedBuffer = await processImageWithSmartCrop(buffer, {
width,
height,
format: 'webp',
quality: q,
});
// 2. Process image with Face-API and Sharp
const processedBuffer = await processImageWithSmartCrop(buffer, {
width,
height,
format: "webp",
quality: q,
});
// 3. Return the processed image
return new NextResponse(new Uint8Array(processedBuffer), {
status: 200,
headers: {
'Content-Type': 'image/webp',
'Cache-Control': 'public, max-age=31536000, immutable',
},
});
} catch (error) {
console.error('Image Processing Error:', error);
return NextResponse.json({ error: 'Failed to process image' }, { status: 500 });
}
// 3. Return the processed image
return new NextResponse(new Uint8Array(processedBuffer), {
status: 200,
headers: {
"Content-Type": "image/webp",
"Cache-Control": "public, max-age=31536000, immutable",
},
});
} catch (error) {
console.error("Image Processing Error:", error);
return NextResponse.json(
{ error: "Failed to process image" },
{ status: 500 },
);
}
}