- Store product images locally with hierarchy: /images/products/<state>/<store>/<brand>/<product>/ - Add /img/* proxy endpoint for on-demand resizing via Sharp - Implement per-product image checking to skip existing downloads - Fix pathToUrl() to correctly generate /images/... URLs - Add frontend getImageUrl() helper with preset sizes (thumb, medium, large) - Update all product pages to use optimized image URLs - Add stealth session support for Dutchie GraphQL crawls - Include test scripts for crawl and image verification 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
#!/usr/bin/env npx tsx
|
|
/**
|
|
* Test Image Proxy - Standalone test without backend
|
|
*
|
|
* Usage:
|
|
* npx tsx src/scripts/test-image-proxy.ts
|
|
*/
|
|
|
|
import express from 'express';
|
|
import imageProxyRoutes from '../routes/image-proxy';
|
|
|
|
const app = express();
|
|
const PORT = 3099;
|
|
|
|
// Mount the image proxy
|
|
app.use('/img', imageProxyRoutes);
|
|
|
|
// Start server
|
|
app.listen(PORT, async () => {
|
|
console.log(`Test image proxy running on http://localhost:${PORT}`);
|
|
console.log('');
|
|
console.log('Testing image proxy...');
|
|
console.log('');
|
|
|
|
const axios = require('axios');
|
|
|
|
// Test cases
|
|
const tests = [
|
|
{
|
|
name: 'Original image',
|
|
url: '/img/products/az/az-deeply-rooted/clout-king/68b4b20a0f9ef3e90eb51e96/image-268a6e44.webp',
|
|
},
|
|
{
|
|
name: 'Resize to 200px width',
|
|
url: '/img/products/az/az-deeply-rooted/clout-king/68b4b20a0f9ef3e90eb51e96/image-268a6e44.webp?w=200',
|
|
},
|
|
{
|
|
name: 'Resize to 100x100 cover',
|
|
url: '/img/products/az/az-deeply-rooted/clout-king/68b4b20a0f9ef3e90eb51e96/image-268a6e44.webp?w=100&h=100&fit=cover',
|
|
},
|
|
{
|
|
name: 'Grayscale + blur',
|
|
url: '/img/products/az/az-deeply-rooted/clout-king/68b4b20a0f9ef3e90eb51e96/image-268a6e44.webp?w=200&gray=1&blur=2',
|
|
},
|
|
{
|
|
name: 'Convert to JPEG',
|
|
url: '/img/products/az/az-deeply-rooted/clout-king/68b4b20a0f9ef3e90eb51e96/image-268a6e44.webp?w=200&format=jpeg&q=70',
|
|
},
|
|
{
|
|
name: 'Non-existent image',
|
|
url: '/img/products/az/nonexistent/image.webp',
|
|
},
|
|
];
|
|
|
|
for (const test of tests) {
|
|
try {
|
|
const response = await axios.get(`http://localhost:${PORT}${test.url}`, {
|
|
responseType: 'arraybuffer',
|
|
validateStatus: () => true,
|
|
});
|
|
|
|
const contentType = response.headers['content-type'];
|
|
const size = response.data.length;
|
|
const status = response.status;
|
|
|
|
console.log(`${test.name}:`);
|
|
console.log(` URL: ${test.url.slice(0, 80)}${test.url.length > 80 ? '...' : ''}`);
|
|
console.log(` Status: ${status}`);
|
|
console.log(` Content-Type: ${contentType}`);
|
|
console.log(` Size: ${(size / 1024).toFixed(1)} KB`);
|
|
console.log('');
|
|
} catch (error: any) {
|
|
console.log(`${test.name}: ERROR - ${error.message}`);
|
|
console.log('');
|
|
}
|
|
}
|
|
|
|
console.log('Tests complete!');
|
|
process.exit(0);
|
|
});
|