feat: integrate XSLT Tools with toolbox portal

This commit is contained in:
2026-07-20 18:16:18 +02:00
parent 3193cc395c
commit 8f8a59e76c
36 changed files with 1737 additions and 243 deletions

View File

@@ -0,0 +1,151 @@
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();
}