import { createServer } from 'node:http'; import { readFile, stat } from 'node:fs/promises'; import { dirname, extname, join, resolve, sep } from 'node:path'; import { fileURLToPath } from 'node:url'; const repositoryRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..'); const distDirectory = join(repositoryRoot, 'dist'); const nestedPath = '/deep/nested/app/'; const mimeTypes = { '.css': 'text/css', '.html': 'text/html', '.ico': 'image/x-icon', '.js': 'text/javascript', '.json': 'application/json', '.png': 'image/png', '.svg': 'image/svg+xml', }; const server = createServer(async (request, response) => { try { const requestUrl = new URL(request.url ?? '/', 'http://localhost'); if (requestUrl.pathname === '/toolbox.catalog.json') { response.setHeader('content-type', 'application/json'); response.end( JSON.stringify({ schemaVersion: 1, id: 'nested-smoke-test', name: 'Nested smoke test', home: './', theme: { mode: 'system', brand: 'Nested smoke test', }, apps: [ { manifest: `${nestedPath}toolbox-app.json`, enabled: true, }, ], }) ); return; } if (!requestUrl.pathname.startsWith(nestedPath)) { response.writeHead(404).end(); return; } const requestedPath = decodeURIComponent( requestUrl.pathname.slice(nestedPath.length) ); const filePath = resolve( distDirectory, requestedPath === '' ? 'index.html' : requestedPath ); if ( filePath !== distDirectory && !filePath.startsWith(`${distDirectory}${sep}`) ) { response.writeHead(403).end(); return; } if (!(await stat(filePath)).isFile()) { response.writeHead(404).end(); return; } response.setHeader( 'content-type', mimeTypes[extname(filePath)] ?? 'application/octet-stream' ); response.end(await readFile(filePath)); } catch { response.writeHead(404).end(); } }); await new Promise((resolveListening) => { server.listen(0, '127.0.0.1', resolveListening); }); try { const address = server.address(); if (!address || typeof address === 'string') { throw new Error('Static smoke server did not expose a TCP port.'); } const appUrl = `http://127.0.0.1:${address.port}${nestedPath}`; const standaloneHtml = await fetchText(appUrl); const toolboxHtml = await fetchText( `${appUrl}?toolbox=${encodeURIComponent('/toolbox.catalog.json')}` ); if (toolboxHtml !== standaloneHtml) { throw new Error('Toolbox mode did not serve the same static app artifact.'); } const assetReferences = Array.from( standaloneHtml.matchAll(/(?:href|src)="([^"]+)"/g), (match) => match[1] ).filter( (reference) => !reference.startsWith('#') && !reference.startsWith('data:') && !reference.startsWith('http:') && !reference.startsWith('https:') ); for (const reference of assetReferences) { const resolved = new URL(reference, appUrl); if (!resolved.pathname.startsWith(nestedPath)) { throw new Error( `Built asset escaped the nested app path: ${reference} -> ${resolved.pathname}` ); } await fetchOk(resolved); } const manifestUrl = new URL('toolbox-app.json', appUrl); const manifest = JSON.parse(await fetchText(manifestUrl)); await fetchOk(new URL(manifest.entry, appUrl)); await fetchOk(new URL(manifest.icon, manifestUrl)); await fetchOk(new URL('vendor/saxon/SaxonJS2.js', appUrl)); await fetchOk(`http://127.0.0.1:${address.port}/toolbox.catalog.json`); console.log( `Static smoke test passed at ${nestedPath} in standalone and toolbox modes.` ); } finally { await new Promise((resolveClosed, reject) => { server.close((error) => (error ? reject(error) : resolveClosed())); }); } async function fetchOk(url) { const response = await fetch(url); if (!response.ok) { throw new Error( `Expected ${url} to be available, received HTTP ${response.status}.` ); } return response; } async function fetchText(url) { return (await fetchOk(url)).text(); }