2026-09-29 20:57:38 +08:00
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' )
2026-09-30 14:27:39 +08:00
const base = '/'
2026-09-29 20:57:38 +08:00
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' )
2026-09-30 14:27:39 +08:00
assert . doesNotMatch ( html + js , /\/pda-(?:domestic|overseas)\// , 'Build must not reference the retired subdirectory deployment' )
2026-09-29 20:57:38 +08:00
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 ))