Skip to content

Instantly share code, notes, and snippets.

@sorrycc
Created May 6, 2022 12:15
Show Gist options
  • Save sorrycc/09fdc9130489c135041b47823dbdea56 to your computer and use it in GitHub Desktop.
Save sorrycc/09fdc9130489c135041b47823dbdea56 to your computer and use it in GitHub Desktop.
const assert = require('assert');
const { basename, dirname } = require('path');
const fg = require('fast-glob');
const getRoutes = async (opts) => {
// e.g. ['a/a.route.jsx', 'b/b.route.jsx', 'a.c/b.route.jsx']
const files = await fg(['*/*.route.jsx'], {
cwd: opts.baseDir,
});
return getRoutesByFiles({
...opts,
files,
});
};
const getRoutesByFiles = async (opts) => {
const routes = {};
opts.files.forEach((file) => {
const id = basename(dirname(file));
assert(!routes[id], `Duplicate route id: ${id}`);
routes[id] = {
id,
file,
path: getPath(id),
};
});
// ['a.c', 'a', 'b']
const ids = Object.keys(routes).sort(byLongestFirst);
const layoutIds = ids.filter((id) => {
return id.endsWith('.');
});
layoutIds.forEach((layoutId) => {
const childIds = findChildRoutes(ids, routes, layoutId);
childIds.forEach((id) => {
routes[id].parentId = layoutId;
});
});
return routes;
};
function byLongestFirst(a, b) {
return b.length - a.length;
}
function findChildRoutes(ids, routes, layoutId) {
const compareId = layoutId.replace(/index\.$/, '');
return ids.filter((id) => {
return id !== layoutId && !routes[id].parentId && id.startsWith(compareId);
});
}
function getPath(id) {
let path = id;
// layout id is ends with .
if (path.endsWith('.')) path = path.slice(0, -1);
if (path.endsWith('index')) path = path.slice(0, -5);
path = path
.split('.')
.map((part) => {
// ignore _ prefixed path
if (part.startsWith('_')) return '';
// splat
if (part.endsWith('$')) return '*';
// dynamic import
if (part.startsWith('$')) return `:${part.slice(1)}`;
return part;
})
.join('/');
return `/${path}`;
}
exports.getRoutes = getRoutes;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment