feat: shop detection from URL + vitest setup

This commit is contained in:
2026-05-25 13:53:14 +00:00
parent fb308da5c5
commit 91dea772aa
3 changed files with 49 additions and 0 deletions

17
src/lib/shops.ts Normal file
View File

@@ -0,0 +1,17 @@
export type Shop = 'amazon' | 'idealo' | 'geizhals'
const PATTERNS: Array<{ shop: Shop; hostMatch: RegExp }> = [
{ shop: 'amazon', hostMatch: /(^|\.)amazon\.(de|com|co\.uk|fr|it|es|nl)$/i },
{ shop: 'idealo', hostMatch: /(^|\.)idealo\.(de|com|at|fr|it|es|co\.uk)$/i },
{ shop: 'geizhals', hostMatch: /(^|\.)geizhals\.(de|at|eu)$/i },
]
export function detectShop(input: string): Shop | null {
let host: string
try {
host = new URL(input).hostname
} catch {
return null
}
return PATTERNS.find((p) => p.hostMatch.test(host))?.shop ?? null
}

22
tests/shops.test.ts Normal file
View File

@@ -0,0 +1,22 @@
import { describe, it, expect } from 'vitest'
import { detectShop } from '@/lib/shops'
describe('detectShop', () => {
it.each([
['https://www.amazon.de/dp/B0C5BMMJTL', 'amazon'],
['https://amazon.com/gp/product/B0C5BMMJTL', 'amazon'],
['https://www.idealo.de/preisvergleich/OffersOfProduct/123456_-foo.html', 'idealo'],
['https://geizhals.de/sony-playstation-5-a2362829.html', 'geizhals'],
['https://www.geizhals.eu/foo', 'geizhals'],
])('detects %s as %s', (url, expected) => {
expect(detectShop(url)).toBe(expected)
})
it('returns null for unknown shop', () => {
expect(detectShop('https://example.com/foo')).toBeNull()
})
it('returns null for invalid url', () => {
expect(detectShop('not a url')).toBeNull()
})
})

10
vitest.config.ts Normal file
View File

@@ -0,0 +1,10 @@
import { defineConfig } from 'vitest/config'
import path from 'node:path'
export default defineConfig({
test: {
environment: 'node',
include: ['tests/**/*.test.ts'],
},
resolve: { alias: { '@': path.resolve(__dirname, './src') } },
})