Files
stylebot-harmony/scripts/plugins/esbuild-browserslist.ts
2023-08-03 20:09:32 -04:00

108 lines
2.9 KiB
TypeScript

// https://github.com/nihalgonsalves/esbuild-plugin-browserslist
// MIT License. Copyright (c) 2021 Nihal Gonsalves
import { z } from "zod"
import browserslist from "browserslist"
export function getDefaultTarget() {
return getTarget(
["Chrome", "Firefox", "Edge", "Safari"].map(browser => `last 2 ${browser} versions`),
)
}
enum BrowserslistKind {
Edge = "edge",
Firefox = "firefox",
Chrome = "chrome",
Safari = "safari",
iOS = "ios_saf",
Android = "android",
AndroidChrome = "and_chr",
AndroidFirefox = "and_ff",
AndroidUC = "and_uc",
AndroidQQ = "and_qq",
Samsung = "samsung",
Opera = "opera",
OperaMini = "op_mini",
OperaMobile = "op_mob",
IE = "ie",
IEMobile = "ie_mob",
BlackBerry = "bb",
Baidu = "baidu",
Kaios = "kaios",
Node = "node",
}
const enum EsbuildEngine {
Chrome = "chrome",
Edge = "edge",
ES = "es",
Firefox = "firefox",
Hermes = "hermes",
IE = "ie",
IOS = "ios",
Node = "node",
Opera = "opera",
Rhino = "rhino",
Safari = "safari",
}
const BrowserslistEsbuildMapping: Partial<Record<BrowserslistKind, EsbuildEngine>> = {
// exact map
[BrowserslistKind.Edge]: EsbuildEngine.Edge,
[BrowserslistKind.Firefox]: EsbuildEngine.Firefox,
[BrowserslistKind.Chrome]: EsbuildEngine.Chrome,
[BrowserslistKind.Safari]: EsbuildEngine.Safari,
[BrowserslistKind.iOS]: EsbuildEngine.IOS,
[BrowserslistKind.Node]: EsbuildEngine.Node,
[BrowserslistKind.IE]: EsbuildEngine.IE,
[BrowserslistKind.Opera]: EsbuildEngine.Opera,
// approximate mapping
[BrowserslistKind.Android]: EsbuildEngine.Chrome,
[BrowserslistKind.AndroidChrome]: EsbuildEngine.Chrome,
[BrowserslistKind.AndroidFirefox]: EsbuildEngine.Firefox,
// the rest have no equivalent for esbuild
}
const BrowserSchema = z.nativeEnum(BrowserslistKind)
/** 123 or 123.456 or 123.456.789 */
const VersionSchema = z.string().regex(/^(\d+\.\d+\.\d+|\d+\.\d+|\d+)$/)
export function getTarget(targets: string[]): string[] {
const result = browserslist(targets)
.map(entry => {
const [rawBrowser, rawVersionOrRange] = entry.split(" ")
const rawVersionNormalized = rawVersionOrRange
// e.g. 13.4-13.7, take the lower range
?.replace(/-[\d.]+$/, "")
// all => replace with 1
?.replace("all", "1")
const browserResult = BrowserSchema.safeParse(rawBrowser)
const versionResult = VersionSchema.safeParse(rawVersionNormalized)
if (!browserResult.success || !versionResult.success) {
return
}
const { data: browser } = browserResult
const { data: version } = versionResult
const esbuildTarget = BrowserslistEsbuildMapping[browser]
if (!esbuildTarget) {
return
}
return { target: esbuildTarget, version }
})
.filter(Boolean)
.map(({ target, version }) => `${target}${version}`)
if (result.length === 0) {
throw new Error("Could not resolve any esbuild targets")
}
return result
}