auto format

This commit is contained in:
cupcakearmy 2021-11-16 14:22:30 +01:00
parent 8770b1fa2a
commit 65919ef75d
No known key found for this signature in database
GPG Key ID: 3235314B4D31232F
2 changed files with 35 additions and 20 deletions

View File

@ -13,16 +13,12 @@ import { RouteHandlerMethod } from 'fastify'
import sharp, { FitEnum, FormatEnum } from 'sharp' import sharp, { FitEnum, FormatEnum } from 'sharp'
import { flatten, unflatten } from 'flat' import { flatten, unflatten } from 'flat'
import ms from 'ms' import ms from 'ms'
import DeviceDetector from 'device-detector-js'
import Avif from 'caniuse-db/features-json/avif.json'
import WebP from 'caniuse-db/features-json/webp.json'
import { storage } from '../storage' import { storage } from '../storage'
import { transform } from '../transform' import { transform } from '../transform'
import { sha3, sortObjectByKeys, validateSyncOrFail } from '../utils/utils' import { sha3, sortObjectByKeys, validateSyncOrFail } from '../utils/utils'
import { Config, URLClean } from '../config' import { Config, URLClean } from '../config'
import { supportsAvif, supportsWebP } from '../utils/caniuse'
const detector = new DeviceDetector()
export class ComplexParameter<N = string, T extends object = {}> { export class ComplexParameter<N = string, T extends object = {}> {
@IsString() @IsString()
@ -170,11 +166,9 @@ export class TransformQueryBase {
} }
autoFormat(ua: string) { autoFormat(ua: string) {
const parsed = detector.parse(ua) if (supportsAvif(ua)) this.format!.name = 'avif'
//https://caniuse.com/avif else if (supportsWebP(ua)) this.format!.name = 'webp'
console.log(parsed) else this.format!.name = 'jpeg'
console.log(WebP)
// https://caniuse.com/webp
} }
} }

View File

@ -4,16 +4,17 @@ import WebP from 'caniuse-db/features-json/webp.json'
const detector = new DeviceDetector() const detector = new DeviceDetector()
function findLowestCompatibleVersion(stat: Record<string, string>): string { function findLowestSupportedVersion(stat: Record<string, string>): number | null {
const entries = Object.entries(stat).sort((a, b) => parseInt(a[0]) - parseInt(b[0])) const entries = Object.entries(stat).sort((a, b) => parseInt(a[0]) - parseInt(b[0]))
for (const [version, support] of entries) { for (const [version, support] of entries) {
if (support.startsWith('y') || support.startsWith('a')) { if (support.startsWith('y') || support.startsWith('a')) {
return version return parseInt(version)
} }
} }
return null
} }
const mapping = { const BrowserMappings = {
'Internet Explorer': 'ie', 'Internet Explorer': 'ie',
'Microsoft Edge': 'edge', 'Microsoft Edge': 'edge',
Firefox: 'firefox', Firefox: 'firefox',
@ -31,20 +32,40 @@ const mapping = {
} }
function matchBrowserToStat(browser: DeviceDetector.DeviceDetectorResult): string { function matchBrowserToStat(browser: DeviceDetector.DeviceDetectorResult): string {
if (!browser.os || !browser.client) throw new Error('Invalid browser') if (browser.os!.name === 'iOS') {
if (browser.os.name === 'iOS') {
return 'ios_saf' return 'ios_saf'
} }
if (browser.os.name in mapping) { if (browser.client!.name in BrowserMappings) {
return mapping[browser.os.name as keyof typeof mapping] return BrowserMappings[browser.client!.name as keyof typeof BrowserMappings]
} }
throw new Error('Could not determine mapping for browser') throw new Error('Could not determine mapping for browser')
} }
function match(feature: typeof Avif | typeof WebP, ua: string): boolean { function match(feature: typeof Avif | typeof WebP, ua: string): boolean {
const browser = detector.parse(ua) const browser = detector.parse(ua)
if (!browser.client || !browser.os) {
throw new Error('Could not parse browser')
}
const stats = feature.stats[matchBrowserToStat(browser) as keyof typeof feature.stats] const stats = feature.stats[matchBrowserToStat(browser) as keyof typeof feature.stats]
console.debug(stats) const lowestSupported = findLowestSupportedVersion(stats)
console.debug(findLowestCompatibleVersion(stats)) if (lowestSupported === null) {
return false return false
}
return lowestSupported <= parseInt(browser.client.version)
}
export function supportsAvif(ua: string): boolean {
try {
return match(Avif, ua)
} catch {
return false
}
}
export function supportsWebP(ua: string): boolean {
try {
return match(WebP, ua)
} catch {
return false
}
} }