Skip to content

Commit e2f1bcc

Browse files
Sync public snapshot from freebuff-private
Source: CodebuffAI/freebuff-private@5ef276afee975af8ff666f3cdfe410373a88d35b
1 parent fa2cae9 commit e2f1bcc

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { expect, test } from 'bun:test'
2+
import { imageMimeType } from './image-files'
3+
4+
test('recognizes supported image extensions without misclassifying text or extensionless paths', () => {
5+
for (const extension of [
6+
'png',
7+
'jpg',
8+
'jpeg',
9+
'gif',
10+
'webp',
11+
'avif',
12+
'svg',
13+
'ico',
14+
'bmp',
15+
]) {
16+
expect(
17+
imageMimeType(`assets/photo.${extension}`)?.startsWith('image/'),
18+
).toBe(true)
19+
}
20+
expect(imageMimeType('PHOTO.PNG')).toBe('image/png')
21+
for (const path of [
22+
'png',
23+
'src/png',
24+
'a.png/source',
25+
'image.png.ts',
26+
'data.bin',
27+
'README.md',
28+
]) {
29+
expect(imageMimeType(path)).toBeUndefined()
30+
}
31+
})
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/** Browser-decodable project images. SVGs are displayed only through an <img>. */
2+
const IMAGE_MIME_TYPES = {
3+
png: 'image/png',
4+
jpg: 'image/jpeg',
5+
jpeg: 'image/jpeg',
6+
gif: 'image/gif',
7+
webp: 'image/webp',
8+
avif: 'image/avif',
9+
svg: 'image/svg+xml',
10+
ico: 'image/x-icon',
11+
bmp: 'image/bmp',
12+
} as const
13+
14+
export const IMAGE_FILE_MAX_BYTES = 10 * 1024 * 1024
15+
16+
export interface FileImage {
17+
mimeType: (typeof IMAGE_MIME_TYPES)[keyof typeof IMAGE_MIME_TYPES]
18+
base64: string
19+
}
20+
21+
export function imageMimeType(path: string): FileImage['mimeType'] | undefined {
22+
const extension = /\.([^./\\]+)$/.exec(path)?.[1]?.toLowerCase()
23+
return extension && Object.hasOwn(IMAGE_MIME_TYPES, extension)
24+
? IMAGE_MIME_TYPES[extension as keyof typeof IMAGE_MIME_TYPES]
25+
: undefined
26+
}

0 commit comments

Comments
 (0)