mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-11 13:02:22 +08:00
81 lines
2.8 KiB
JavaScript
81 lines
2.8 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { createHash } from 'node:crypto'
|
|
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
import os from 'node:os'
|
|
import path from 'node:path'
|
|
|
|
import { build } from 'vite'
|
|
|
|
const [command, ...extra] = process.argv.slice(2)
|
|
if (!['--write', '--check'].includes(command) || extra.length) {
|
|
throw new Error(
|
|
'Usage: node scripts/generate-modern-polyfills.mjs --write|--check',
|
|
)
|
|
}
|
|
const inventoryPath = 'scripts/modern-polyfills.json'
|
|
const staleMessage =
|
|
'Modern polyfill inventory is stale; run pnpm polyfills:generate and commit scripts/modern-polyfills.json'
|
|
|
|
function outputHashes(result) {
|
|
assert(
|
|
!Array.isArray(result) && 'output' in result,
|
|
'Expected one app output',
|
|
)
|
|
return result.output
|
|
.map((file) => [
|
|
file.fileName,
|
|
createHash('sha256')
|
|
.update(file.type === 'chunk' ? file.code : file.source)
|
|
.digest('hex'),
|
|
])
|
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
}
|
|
|
|
const temporary = mkdtempSync(path.join(os.tmpdir(), 'modern-polyfills-'))
|
|
const capture = path.join(temporary, 'capture.json')
|
|
const candidate = path.join(temporary, 'inventory.json')
|
|
const snapshots = []
|
|
const fingerprints = []
|
|
let imports
|
|
try {
|
|
process.env.MODERN_POLYFILLS_CAPTURE = capture
|
|
// OS_PLATFORM changes emitted code; certify each production define without
|
|
// launching a native app or normalizing away code the detector actually sees.
|
|
for (const platform of ['darwin', 'linux', 'win32']) {
|
|
const config = {
|
|
logLevel: 'error',
|
|
define: { OS_PLATFORM: JSON.stringify(platform) },
|
|
build: { write: false },
|
|
}
|
|
const automatic = await build(config)
|
|
const detected = JSON.parse(readFileSync(capture, 'utf8'))
|
|
if (imports) assert.deepEqual(detected.imports, imports)
|
|
imports = detected.imports
|
|
fingerprints.push(detected.fingerprint)
|
|
snapshots.push({ config, hashes: outputHashes(automatic) })
|
|
}
|
|
const content = `${JSON.stringify({ imports, fingerprints: [...new Set(fingerprints)].sort() }, null, 2)}\n`
|
|
writeFileSync(candidate, content)
|
|
delete process.env.MODERN_POLYFILLS_CAPTURE
|
|
process.env.MODERN_POLYFILLS_INVENTORY = candidate
|
|
for (const { config, hashes } of snapshots) {
|
|
assert.deepEqual(
|
|
outputHashes(await build(config)),
|
|
hashes,
|
|
'Explicit polyfills must be byte-identical to automatic discovery',
|
|
)
|
|
}
|
|
if (command === '--check') {
|
|
assert.equal(readFileSync(inventoryPath, 'utf8'), content, staleMessage)
|
|
} else {
|
|
writeFileSync(inventoryPath, content)
|
|
}
|
|
console.log(
|
|
`Modern polyfills ${command === '--check' ? 'verified' : 'generated'}: ${imports.length} imports; all three OS outputs byte-identical to automatic discovery`,
|
|
)
|
|
} finally {
|
|
delete process.env.MODERN_POLYFILLS_CAPTURE
|
|
delete process.env.MODERN_POLYFILLS_INVENTORY
|
|
rmSync(temporary, { recursive: true })
|
|
}
|