UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

75 lines (67 loc) 2.71 kB
import { writeFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import FSExtra from 'fs-extra' import micromatch from 'micromatch' import { globbedRoutesToRouteContext } from '../router/useViteRoutes' import { globDir } from '../utils/globDir' import type { One } from '../vite/types' import { getTypedRoutesDeclarationFile } from './getTypedRoutesDeclarationFile' import { injectRouteHelpers, type InjectMode } from './injectRouteHelpers' import { removeSupportedExtensions } from '../router/matchers' export async function generateRouteTypes( outFile: string, routerRoot: string, ignoredRouteFiles?: string[], typedRoutesMode?: 'type' | 'runtime' ) { let routePaths = globDir(routerRoot) if (ignoredRouteFiles && ignoredRouteFiles.length > 0) { routePaths = micromatch.not(routePaths, ignoredRouteFiles, { // The path starts with './', such as './foo/bar/baz.test.tsx', and ignoredRouteFiles is like ['**/*.test.*'], so we need matchBase here. matchBase: true, }) } const routes = routePaths.reduce((acc, cur) => { acc[cur] = {} return acc }, {}) const context = globbedRoutesToRouteContext(routes, routerRoot) const declarations = getTypedRoutesDeclarationFile(context) const outDir = dirname(outFile) await FSExtra.ensureDir(outDir) await writeFile(outFile, declarations) // If experimental.typedRoutesGeneration is enabled, inject helpers into route files if (typedRoutesMode) { const mode: InjectMode = typedRoutesMode === 'type' ? 'type' : 'runtime' // Inject helpers into each route file for (const routePath of routePaths) { // Skip non-route files (layouts, middlewares, type definitions, etc.) if ( routePath.includes('_layout') || routePath.includes('+api') || routePath.startsWith('_') || routePath.endsWith('.d.ts') ) { continue } // Convert route path to route name // e.g., "./app/(site)/docs/[slug]+ssg.tsx" -> "/(site)/docs/[slug]" const fullPath = join(process.cwd(), routerRoot, routePath) const routeName = routePath .replace(/^\.\//, '') .replace(/\+[^/]*$/, '') // Remove +ssg, +ssr, etc. .replace(/\/index$/, '') .replace(/index$/, '') let cleanRouteName = removeSupportedExtensions(routeName).replace(/\/?index$/, '') // Ensure leading slash if (!cleanRouteName.startsWith('/')) { cleanRouteName = '/' + cleanRouteName } // Skip routes without dynamic segments (no params to type) if (!cleanRouteName.includes('[')) { continue } await injectRouteHelpers(fullPath, cleanRouteName, mode) } } }