Use path-to-regexp to test route files against express-compatible routing.

This commit is contained in:
Andrew Pietila 2023-03-20 08:48:55 -05:00
parent aa58093b91
commit 8b0b3fd2ef
3 changed files with 43 additions and 15 deletions

41
app.js
View file

@ -1,6 +1,7 @@
const express = require('express');
const fsPromises = require('fs').promises;
const glob = require('glob');
const { match: createPathMatch } = require('path-to-regexp');
(async () => {
const app = express();
@ -8,20 +9,40 @@ const glob = require('glob');
cwd: './routes',
dot: true,
});
const pathMatches = [];
app.use(async (req, res, next) => {
let stats = await Promise.all([
fsPromises.stat(`./routes/${req.url}.js`).catch(() => "nofile"),
fsPromises.stat(`./routes/${req.url}/index.js`).catch(() => "nofile"),
]);
if ( req.url.endsWith('/') && stats[1] !== "nofile" ) {
req.url = `${req.url}index`;
} else if ( stats[0] === "nofile" && stats[1] !== "nofile" ) {
req.url = `${req.url}/index`
const requestUrl = new URL(req.url, "https://example.com/");
var candidateUrl = "";
var secondCandidateUrl = "";
for ( let pathMatch in pathMatches ) {
if ( patchMatches[pathMatch](requestUrl.pathname) ) {
// If we get an exact match, we don't need to process further.
return next();
} else if ( requestUrl.pathname.endsWith('/') && patchMatches[pathMatch](`${requestUrl.pathname}index`) ) {
// If we end with a /, and the index path matches, lets do the index path, but prioritize the non-index path.
let secondRequestUrl = new URL(requestUrl);
secondRequestUrl.pathname = `${requestUrl.pathname}index`;
candidateUrl = secondRequestUrl.toString().substring(19);
} else if ( pathName[pathMatch](`${requestUrl.pathname}/index`) ) {
// If we don't end with a /, and the /index path matches, lets do the /index path, but prioritize paths checked previously.
let secondRequestUrl = new URL(requestUrl);
secondRequestUrl.pathname = `${requestUrl.pathname}/index`;
secondCandidateUrl = secondRequestUrl.toString().substring(19);
}
}
next();
if ( candidateUrl !== "" ) {
req.url = candidateUrl;
return next();
}
if ( secondCandidateUrl !== "" ) {
req.url = secondCandidateUrl;
return next();
}
return next();
});
for ( let routeScript in routes ) {
let route = routes[routeScript].replace(".js", "");
let route = routes[routeScript].replace(/\.js$/, "");
pathMatches.push(createPathMatch(route));
let routeObj = require(`./routes/${route}`);
if ( routeObj.get ) {
app.get(`/${route}`, routeObj.get);

14
package-lock.json generated
View file

@ -10,7 +10,8 @@
"license": "WTFPL",
"dependencies": {
"express": "^4.18.2",
"glob": "^9.3.0"
"glob": "^9.3.0",
"path-to-regexp": "^6.2.1"
}
},
"node_modules/accepts": {
@ -210,6 +211,11 @@
"node": ">= 0.10.0"
}
},
"node_modules/express/node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"node_modules/finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
@ -481,9 +487,9 @@
}
},
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
},
"node_modules/proxy-addr": {
"version": "2.0.7",

View file

@ -14,6 +14,7 @@
"license": "WTFPL",
"dependencies": {
"express": "^4.18.2",
"glob": "^9.3.0"
"glob": "^9.3.0",
"path-to-regexp": "^6.2.1"
}
}