import assert from 'node:assert/strict'; import { existsSync, readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; const dist = fileURLToPath(new URL('../dist/', import.meta.url)); const html = readFileSync( new URL('../dist/index.html', import.meta.url), 'utf8' ); const assets = [...html.matchAll(/(?:href|src)="(\/assets\/[^"]+)"/g)].map( match => match[1] ); assert.match(html, /
<\/div>/); assert.match(html, /<\/script>/); assert.ok( html.indexOf('/runtime-config.js') < html.indexOf('type="module"'), 'runtime config must load before the app module' ); assert.ok( assets.some(asset => asset.endsWith('.js')), 'missing JS asset' ); assert.ok( assets.some(asset => asset.endsWith('.css')), 'missing CSS asset' ); assert.ok(!/]*\bsrc=)[^>]*>/i.test(html), 'inline script found'); assets.forEach(asset => assert.ok(existsSync(dist + asset.slice(1)), asset)); const dashboard = assets .filter(asset => asset.endsWith('.js')) .map(asset => readFileSync(dist + asset.slice(1), 'utf8')) .join('\n'); assert.doesNotMatch( dashboard, /=\(?function\(\)\{return this\}\)?\(\);try\{([A-Za-z_$][\w$]*)=\1\|\|new Function\("return this"\)\(\)/, 'dashboard contains a CSP-blocked UMD global shim' );