fix(image-engine): support sharp 0.35 types

This commit is contained in:
SnapOtter
2026-06-29 16:04:17 +08:00
parent 744bd482c8
commit 2137be479e
5 changed files with 22 additions and 17 deletions
+2 -1
View File
@@ -34,6 +34,7 @@ import type {
Sharp,
SharpenAdvancedOptions,
SharpenOptions,
SharpFormat,
StripMetadataOptions,
} from "./types.js";
import { getImageInfo } from "./utils/metadata.js";
@@ -109,7 +110,7 @@ export async function processImage(
if (!sharpFormat) {
throw new Error(`Unsupported output format: ${outputFormat}`);
}
image = image.toFormat(sharpFormat as keyof sharp.FormatEnum);
image = image.toFormat(sharpFormat as SharpFormat);
}
const buffer = await image.toBuffer();
@@ -5,6 +5,8 @@ import type {
CorrectionParams,
EnhancementMode,
Sharp,
SharpChannelStats,
SharpMetadata,
} from "../types.js";
/**
@@ -123,9 +125,9 @@ export async function analyzeImage(buffer: Buffer): Promise<AnalysisResult> {
}
function computeScores(
rCh: sharp.ChannelStats,
gCh: sharp.ChannelStats,
bCh: sharp.ChannelStats,
rCh: SharpChannelStats,
gCh: SharpChannelStats,
bCh: SharpChannelStats,
meanLum: number,
stdevLum: number,
isGrayscale: boolean,
@@ -200,7 +202,7 @@ function detectIssues(scores: AnalysisScores): string[] {
return issues;
}
function suggestMode(scores: AnalysisScores, _meta: sharp.Metadata): EnhancementMode {
function suggestMode(scores: AnalysisScores, _meta: SharpMetadata): EnhancementMode {
if (scores.exposure < 30) return "low-light";
if (scores.contrast > 60 && scores.saturation < 30) return "document";
return "auto";
@@ -1,7 +1,7 @@
import sharp from "sharp";
import type { CompressOptions, Sharp } from "../types.js";
import type { CompressOptions, Sharp, SharpFormat } from "../types.js";
const FORMAT_MAP: Record<string, string> = {
const FORMAT_MAP: Record<string, SharpFormat> = {
jpg: "jpeg",
jpeg: "jpeg",
png: "png",
@@ -16,7 +16,7 @@ const FORMAT_MAP: Record<string, string> = {
/** Formats that Sharp cannot encode — fall back to PNG for output. */
const NO_ENCODER = new Set(["svg", "raw", "tga", "psd", "exr", "hdr"]);
function formatOpts(format: string, quality: number): Record<string, unknown> {
function formatOpts(format: SharpFormat, quality: number): Record<string, unknown> {
const opts: Record<string, unknown> = { quality };
if (format === "avif") opts.effort = 4;
return opts;
@@ -31,7 +31,7 @@ export async function compress(image: Sharp, options: CompressOptions): Promise<
const safeDetected = NO_ENCODER.has(detected) ? "png" : detected;
const outputFormat = (FORMAT_MAP[format ?? ""] ??
FORMAT_MAP[safeDetected] ??
safeDetected) as keyof sharp.FormatEnum;
safeDetected) as SharpFormat;
if (targetSizeBytes !== undefined) {
if (targetSizeBytes <= 0) {
@@ -52,7 +52,7 @@ export async function compress(image: Sharp, options: CompressOptions): Promise<
async function findBestQuality(
inputBuffer: Buffer,
resize: { width: number; height: number } | null,
format: keyof sharp.FormatEnum,
format: SharpFormat,
targetBytes: number,
): Promise<number | null> {
let low = 1;
@@ -82,7 +82,7 @@ async function findBestQuality(
async function compressToTargetSize(
inputBuffer: Buffer,
format: keyof sharp.FormatEnum,
format: SharpFormat,
targetBytes: number,
): Promise<Sharp> {
const quality = await findBestQuality(inputBuffer, null, format, targetBytes);
@@ -1,12 +1,11 @@
import type sharp from "sharp";
import type { ConvertOptions, Sharp } from "../types.js";
import type { ConvertOptions, Sharp, SharpFormat } from "../types.js";
/**
* Maps user-facing format names to Sharp format strings.
* Note: HEIC is excluded because Sharp cannot encode HEVC.
* HEIC encoding is handled at the API route level via heif-enc.
*/
const FORMAT_MAP: Record<string, string> = {
const FORMAT_MAP: Partial<Record<ConvertOptions["format"], SharpFormat>> = {
jpg: "jpeg",
png: "png",
webp: "webp",
@@ -32,5 +31,5 @@ export async function convert(image: Sharp, options: ConvertOptions): Promise<Sh
formatOptions.quality = quality;
}
return image.toFormat(sharpFormat as keyof sharp.FormatEnum, formatOptions);
return image.toFormat(sharpFormat, formatOptions);
}
+5 -2
View File
@@ -1,6 +1,9 @@
import type sharp from "sharp";
import type { ChannelStats, FormatEnum, Metadata, Sharp as SharpInstance } from "sharp";
export type Sharp = sharp.Sharp;
export type Sharp = SharpInstance;
export type SharpFormat = Extract<keyof FormatEnum, string> | "avif";
export type SharpChannelStats = ChannelStats;
export type SharpMetadata = Metadata;
export interface ImageInfo {
width: number;