UNPKG

@hono-filebased-route/core

Version:

A core utility for file-based routing in Hono applications.

102 lines (85 loc) 3.56 kB
import { writeFile } from 'fs/promises' import { getExportedHttpMethods, getExportedMiddlewareHandler, getFiles, getRoutePath, } from '../utils/load-routes-utils' import path from 'path' import { Config, METHODS } from '../types' import { createLogger } from '../utils/logger' const defaultConfig: Config = { dir: './src/routes', output: './src/generated-routes.ts', write: true, verbose: false, externals: [], typescript: true, } as const export async function generateRoutesFile(config?: Partial<Config>) { const { dir, output, write, verbose, externals, typescript } = { ...defaultConfig, ...config } const logger = createLogger(verbose) logger.info(`Generating routes file..., ${dir}, ${output}`) const absoluteRoutesDir = path.resolve(dir) const files = await getFiles(absoluteRoutesDir, externals) const importStatements: string[] = [] const routeDefinitions: string[] = [] importStatements.push(`import { Hono } from 'hono';`) let counter = 0 for (const file of files) { const routePath = getRoutePath(file, absoluteRoutesDir) .replace(/\\/g, '/') .replace(/\/index$/, '') const relativePath = path .relative(path.dirname(output), file) .replace(/\.(ts)$/, '') .replace(/\\/g, '/') const moduleName = `routeModule${counter++}` const exportedMethods = getExportedHttpMethods(file) const middlewareHandler = getExportedMiddlewareHandler(file) if (!exportedMethods.GET && !exportedMethods.POST) continue importStatements.push(`import * as ${moduleName} from './${relativePath}';`) const tempHonoVar = `honoApp${moduleName}` routeDefinitions.push(` const ${tempHonoVar} = new Hono();`) for (const method of METHODS) { if (exportedMethods[method]) { if (routePath.endsWith('/*')) { const len = routePath.replace(/\/\*$/g, '').length + 1 if (!middlewareHandler[method]) routeDefinitions.push( ` ${tempHonoVar}.${method.toLowerCase()}('/', async (c) => ${moduleName}.${method}(c, c.req.path.substring(${len}).split('/')));` ) else routeDefinitions.push( ` ${tempHonoVar}.${method.toLowerCase()}('/', ${moduleName}.config${method}, async (c) => ${moduleName}.${method}(c, c.req.path.substring(${len}).split('/')));` ) } else { if (!middlewareHandler[method]) routeDefinitions.push(` ${tempHonoVar}.${method.toLowerCase()}('/', ${moduleName}.${method});`) else routeDefinitions.push( ` ${tempHonoVar}.${method.toLowerCase()}('/', ${moduleName}.config${method}, ${moduleName}.${method});` ) } logger.info(`Generated route: ${method} ${routePath}`) } } routeDefinitions.push(` mainApp.route('${routePath}', ${tempHonoVar});`) } const fileContent = ` // THIS FILE IS AUTO-GENERATED BY scripts/generate-routes.ts. DO NOT EDIT. ${importStatements.join('\n')} /** * Registers all generated file-based routes to the main Hono application. * @param mainApp The main Hono application instance. */ export function registerGeneratedRoutes(mainApp${typescript ? ': Hono' : ''}) { ${routeDefinitions.join('\n')} } ` if (write) { await writeFile(output, fileContent.trimStart()) logger.info(`Generated routes file: ${output} with ${files.length} routes.`) } return fileContent.trimStart() }