@itwin/certa
Version:
A mocha-based integration test runner
90 lines • 3.69 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
const detect = require("detect-port");
const express = require("express");
const http = require("http");
const path = require("path");
const app = express();
// Enable CORS for all apis
app.all("/*", (_req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
res.header("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, X-Correlation-Id, X-Session-Id, X-Application-Id, X-Application-Version, X-User-Id, X-Protocol-Version");
next();
});
// The generated HTML file should be served at the "root" URL (i.e., http://localhost:3000/).
app.use("/", (req, resp, next) => {
if (req.path === "/") {
const certaPath = process.env.CERTA_PATH;
if (undefined === certaPath) {
resp.sendStatus(500);
return;
}
resp.sendFile(certaPath);
}
else
next();
});
// Handle a special route for serving absolute paths and files from node_modules
app.use("/@/", (_req, resp) => {
const filePath = _req.originalUrl.replace(/^\/@\//, "");
const canonicalPath = require("canonical-path");
const sourceMap = require("source-map-support").retrieveSourceMap(filePath);
const fullPath = path.resolve("/", filePath);
resp.sendFile(canonicalPath.normalize(fullPath), {
headers: (sourceMap) && {
"X-SourceMap": `/@/${sourceMap.url}`,
},
});
});
// Serve static assets from any configured "public" directories
const publicDirs = JSON.parse(process.env.CERTA_PUBLIC_DIRS || "[]");
for (const publicDir of publicDirs) {
app.use(express.static(publicDir));
}
// All other routes should log a warning
const alreadyLogged = new Set();
app.use("*", (req, resp) => {
// Don't repeat these warnings if the same asset was requested multiple times.
if (!alreadyLogged.has(req.originalUrl)) {
console.warn(`WARNING: Tests attempted to load missing asset: "${req.originalUrl}"`);
alreadyLogged.add(req.originalUrl);
}
resp.sendStatus(404);
});
// Once the server actually starts, we should log and send the actual port back to the parent process
let port = parseInt(process.env.CERTA_PORT ?? "3000", 10);
const server = http.createServer(app);
server.on("listening", async () => {
console.log(`Certa web frontend now listening on port ${port}`);
if (undefined !== process.send)
process.send(port);
});
// The preferred port (process.env.CERTA_PORT) may be in use. If that happens detect a free port and try again.
// Even though we detect a free port, there can still be race conditions when many certa processes run simultaneously.
// Therefore, we'll retry up to 4 times with a new free port.
const maxRetries = 4;
let numRetries = 0;
server.on("error", async (e) => {
if (e.code !== "EADDRINUSE" || numRetries >= maxRetries) {
console.error(e);
process.exit(1);
}
try {
numRetries++;
port = await detect(port);
server.close();
server.listen(port);
}
catch (error) {
console.error(error);
process.exit(1);
}
});
// Run the server...
server.listen(port);
//# sourceMappingURL=webserver.js.map