Skip to content

Commit 698ca74

Browse files
fix: remove probe-image, roll our own solution (#1111)
1 parent 93cbe32 commit 698ca74

File tree

3 files changed

+81
-137
lines changed

3 files changed

+81
-137
lines changed

package-lock.json

+20-133
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
"husky": "9.1.7",
8989
"i18next": "23.16.8",
9090
"i18next-fs-backend": "2.6.0",
91+
"image-size": "2.0.1",
9192
"jest": "29.7.0",
9293
"jest-json-schema-extended": "1.0.1",
9394
"joi": "17.13.3",
@@ -102,7 +103,6 @@
102103
"npm-run-all2": "7.0.2",
103104
"piscina": "4.9.2",
104105
"prettier": "3.4.2",
105-
"probe-image-size": "7.2.3",
106106
"shx": "0.4.0",
107107
"terser": "5.39.0",
108108
"typescript": "5.8.2"

utils/get-image-dimensions.js

+60-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,71 @@
1-
const probe = require('probe-image-size');
1+
const fetch = require('node-fetch');
2+
const { imageSize } = require('image-size');
23
const errorLogger = require('./error-logger');
34
const { getCache, setCache } = require('./cache');
45
const defaultDimensions = { width: 600, height: 400 };
56

7+
// Minimum required bytes for common image formats (approximate)
8+
const imageMinBytes = {
9+
jpg: 410,
10+
png: 33,
11+
gif: 14,
12+
webp: 30,
13+
bmp: 26,
14+
default: 256 // Fallback for other image types
15+
};
16+
17+
const probeImage = async url => {
18+
const response = await fetch(url);
19+
if (!response.ok)
20+
throw new Error(`Failed to fetch image: ${response.statusText}`);
21+
22+
const chunks = [];
23+
let totalLength = 0;
24+
const reader = response.body;
25+
26+
for await (const chunk of reader) {
27+
chunks.push(chunk);
28+
totalLength += chunk.length;
29+
30+
try {
31+
const buffer = Buffer.concat(chunks, totalLength);
32+
33+
// Try to detect image format (first few bytes)
34+
const { type } = imageSize(buffer);
35+
const minBytes = imageMinBytes[type] || imageMinBytes.default;
36+
37+
// Check buffer length before probing image
38+
if (buffer.length < minBytes) continue;
39+
40+
// Get dimensions
41+
const dimensions = imageSize(buffer);
42+
if (dimensions.width && dimensions.height) {
43+
response.body.destroy(); // Stop downloading
44+
return dimensions;
45+
}
46+
} catch (err) {
47+
// Continue reading if more data is needed
48+
}
49+
}
50+
51+
throw new Error('Could not determine image size');
52+
};
53+
654
const getImageDimensions = async (url, description) => {
755
try {
56+
if (url.startsWith('data:')) {
57+
console.warn(`
58+
---------------------------------------------------------------
59+
Warning: Skipping data URL for image dimensions in ${description.substring(0, 350)}...
60+
---------------------------------------------------------------
61+
`);
62+
63+
throw new Error('Data URL');
64+
}
865
let imageDimensions = getCache(url);
966
if (imageDimensions) return imageDimensions;
1067

11-
const res = await probe(url);
68+
const res = await probeImage(url);
1269
imageDimensions = {
1370
width: res?.width ? res?.width : defaultDimensions.width,
1471
height: res?.height ? res?.height : defaultDimensions.height
@@ -17,7 +74,7 @@ const getImageDimensions = async (url, description) => {
1774

1875
return imageDimensions;
1976
} catch (err) {
20-
if (err.statusCode) errorLogger({ type: 'image', name: description }); // Only write HTTP status code errors to log
77+
errorLogger({ type: 'image', name: description });
2178

2279
return defaultDimensions;
2380
}

0 commit comments

Comments
 (0)