Files
2026-07-08 15:03:45 +02:00

112 lines
3.0 KiB
TypeScript

// @ts-ignore
export const isBun = typeof Bun !== 'undefined'
// @ts-ignore
export const isElectron = typeof process !== 'undefined' && process.versions?.electron !== undefined
// @ts-ignore
export const isDeno = typeof Deno !== 'undefined'
export const isBrowser =
typeof navigator !== 'undefined' && navigator.userAgent?.startsWith?.('Mozilla/5.0 ')
export const isWorkerd =
typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers'
// @ts-ignore
export const isNode =
!isBun && !isElectron && !isDeno && !isWorkerd && typeof process !== 'undefined'
const BOWSER = 'https://cdn.jsdelivr.net/npm/[email protected]/src/bowser.js'
let parsedUserAgent: any
async function parseUserAgent() {
const { default: Bowser } = await import(BOWSER)
parsedUserAgent || (parsedUserAgent = Bowser.parse(window.navigator.userAgent))
return parsedUserAgent
}
async function isEngine(engine: string) {
const userAgentData = await parseUserAgent()
return userAgentData.engine.name === engine
}
export function isBrowserVersionAtLeast(version: number) {
if (!parsedUserAgent) throw new Error()
return parseInt(parsedUserAgent.browser.version.split('.')[0], 10) >= version
}
export const isBlink = isBrowser && (await isEngine('Blink'))
export const isWebKit = isBrowser && (await isEngine('WebKit'))
export const isGecko = isBrowser && (await isEngine('Gecko'))
function isNodeVersionAtLeast(major: number, minor: number) {
const parts = process.versions.node.split('.').map((i) => parseInt(i, 10))
return parts[0] > major || (parts[0] === major && parts[1] >= minor)
}
function isElectronChromiumVersionAtLeast(major: number) {
const version = (process.versions as Record<string, string | undefined>).chrome
return typeof version === 'string' && parseInt(version.split('.')[0], 10) >= major
}
export function supported(identifier?: string, op?: string) {
switch (identifier) {
case 'RSA1_5':
case 'X448':
case 'Ed448':
case 'ES256K':
case 'secp256k1':
return false
}
switch (identifier) {
case 'ML-DSA-44':
case 'ML-DSA-65':
case 'ML-DSA-87':
if (isElectron) {
if (!isNodeVersionAtLeast(24, 18)) {
return false
}
switch (op) {
case 'private jwk import':
case 'pem import':
return true
default:
return isElectronChromiumVersionAtLeast(150)
}
}
return isDeno || (isNode && isNodeVersionAtLeast(24, 7))
}
if (isBlink) {
switch (identifier) {
case 'A192CBC-HS384':
case 'A192GCM':
case 'A192GCMKW':
case 'A192KW':
case 'PBES2-HS384+A192KW':
return false
}
}
if (isElectron) {
switch (identifier) {
case 'A128KW':
case 'A192KW':
case 'A256KW':
case 'PBES2-HS256+A128KW':
case 'PBES2-HS384+A192KW':
case 'PBES2-HS512+A256KW':
case 'ECDH-ES+A128KW':
case 'ECDH-ES+A192KW':
case 'ECDH-ES+A256KW':
return isNodeVersionAtLeast(24, 18)
}
}
return true
}