UNPKG

uws-autoload

Version:

Plugin for [µWebSockets.js](https://github.com/uNetworking/uWebSockets.js) that autoloads all routes in a directory.

56 lines (52 loc) 2.34 kB
import fs from 'node:fs'; import { pathToFileURL } from 'node:url'; const countParams = (filepath) => { return (filepath.match(/\[(.*?)\]/gu) || []).length; }; const sortRoutesByParams = (routes) => { return routes.sort((a, b) => countParams(a) - countParams(b)); }; const transformToRoute = (filepath) => { return filepath.replace(/\.(ts|tsx|mjs|js|jsx|cjs)$/u, "").replaceAll(/\[\.\.\..*?\]/gu, "*").replaceAll(/\[(.+?)\]/gu, (_, match) => `:${match}`).replace(/\/?\((.*?)\)/, "").replaceAll("]-[", "-:").replaceAll("]/", "/").replaceAll(/\[|\]/gu, "").replace(/\/?index$/, ""); }; const DEFAULT_ROUTES_DIR = "./routes"; const DEFAULT_PATTERN = "**/*.{ts,tsx,mjs,js,jsx,cjs}"; const autoloadRoutes = async (app, { importKey = "default", failGlob = true, pattern = DEFAULT_PATTERN, prefix = "", routesDir = DEFAULT_ROUTES_DIR, skipImportErrors = false }) => { if (!fs.existsSync(routesDir)) { throw new Error(`Directory ${routesDir} doesn't exist`); } if (!fs.statSync(routesDir).isDirectory()) { throw new Error(`${routesDir} isn't a directory`); } const files = typeof Bun === "undefined" ? fs.globSync(pattern, { cwd: routesDir }) : await Array.fromAsync(new Bun.Glob(pattern).scan({ cwd: routesDir })); if (failGlob && files.length === 0) { throw new Error(`No matches found in ${routesDir} (you can disable this error with 'failGlob' option to false)`); } for (const file of sortRoutesByParams(files)) { const universalFile = file.replaceAll("\\", "/"); const filePath = `${routesDir}/${universalFile}`; const importedFile = await import(pathToFileURL(filePath).href); const resolvedImportName = typeof importKey === "string" ? importKey : importKey(importedFile); const importedRoute = importedFile[resolvedImportName]; if (!importedRoute && !skipImportErrors) { throw new Error(`${filePath} doesn't export ${resolvedImportName}`); } if (typeof importedRoute === "function") { const matchedFile = universalFile.match(/\/?\((.*?)\)/); const method = matchedFile ? matchedFile[1] : "get"; const route = `${prefix}/${transformToRoute(universalFile)}`; app[method](route, importedRoute); } else { console.warn(`Exported function of ${filePath} is not a function`); } } return app; }; export { autoloadRoutes };