import assert from 'node:assert/strict' import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs' import { resolve, dirname, relative } from 'node:path' import { fileURLToPath } from 'node:url' import { createHash } from 'node:crypto' const project = resolve(dirname(fileURLToPath(import.meta.url)), '..') const output = resolve(project, 'unpackage/dist/build/web') const base = '/' function walk(dir) { return readdirSync(dir).flatMap(name => { const path = resolve(dir, name); return statSync(path).isDirectory() ? walk(path) : [path] }) } assert.ok(existsSync(resolve(output, 'index.html')), 'Build H5 before verifying') const files = walk(output).sort() const html = readFileSync(resolve(output, 'index.html'), 'utf8') const refs = [...html.matchAll(/(?:src|href)="([^"]+)"/g)].map(match => match[1]) assert.ok(refs.length >= 2, 'HTML must reference compiled assets') for (const ref of refs) { assert.ok(ref.startsWith(base), `Asset must remain under ${base}: ${ref}`) assert.ok(existsSync(resolve(output, ref.slice(base.length))), `Missing asset: ${ref}`) } const js = files.filter(path => path.endsWith('.js')).map(path => readFileSync(path, 'utf8')).join('\n') assert.doesNotMatch(html + js, /\/pda-(?:domestic|overseas)\//, 'Build must not reference the retired subdirectory deployment') assert.doesNotMatch(js, /VITE_ROOT_DIR|VITE_AUTH_API_BASE_URL|VITE_OVERSEAS_API_BASE_URL|overseas-api|overseasAccessToken/, 'Build contains broad local env or old overseas config') assert.doesNotMatch(js, /https?:\/\/(?:localhost|127\.0\.0\.1):\d+/, 'Build must not depend on a local dev server') assert.doesNotMatch(js, /https?:\/\/[^"'\s]+\/api["']/, 'API must be same-origin for this H5 deployment') for (const path of files.filter(path => /\.(?:js|css)$/.test(path))) { const source = readFileSync(path, 'utf8') for (const match of source.matchAll(/(?:from\s*|import\s*\(\s*)["'](\.[^"']+\.(?:js|css))["']/g)) { assert.ok(existsSync(resolve(dirname(path), match[1])), `Missing chunk ${match[1]}`) } } const digest = createHash('sha256') for (const path of files) { digest.update(relative(output,path).replaceAll('\\','/')); digest.update('\0'); digest.update(readFileSync(path)) } console.log(JSON.stringify({output, base, files: files.length, bytes: files.reduce((sum,path)=>sum+statSync(path).size,0), sha256: digest.digest('hex')}, null, 2))