navilo 1.2.7 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -68,9 +68,8 @@ declare class RouteTreeBuilder {
68
68
  }
69
69
 
70
70
  declare class RouteDefinitionGenerator {
71
- static generate(node: RouteNode, indent?: string, inheritedNotFound?: string): string;
71
+ static generate(node: RouteNode, indent?: string): string;
72
72
  private static generateIndexRoute;
73
- private static generateNotFoundRoute;
74
73
  private static generateRouteObject;
75
74
  private static generateElementString;
76
75
  private static generateLayoutProps;
package/dist/index.d.ts CHANGED
@@ -68,9 +68,8 @@ declare class RouteTreeBuilder {
68
68
  }
69
69
 
70
70
  declare class RouteDefinitionGenerator {
71
- static generate(node: RouteNode, indent?: string, inheritedNotFound?: string): string;
71
+ static generate(node: RouteNode, indent?: string): string;
72
72
  private static generateIndexRoute;
73
- private static generateNotFoundRoute;
74
73
  private static generateRouteObject;
75
74
  private static generateElementString;
76
75
  private static generateLayoutProps;
package/dist/index.js CHANGED
@@ -268,19 +268,15 @@ var RouteTreeBuilder = class {
268
268
 
269
269
  // src/generator/parser/routeDefinitionGenerator.ts
270
270
  var RouteDefinitionGenerator = class {
271
- static generate(node, indent = " ", inheritedNotFound) {
271
+ static generate(node, indent = " ") {
272
272
  const childNodes = Array.from(node.children.values());
273
273
  const children = [];
274
- const effectiveNotFound = node.notFound || inheritedNotFound;
275
274
  if (node.indexPage) {
276
275
  children.push(this.generateIndexRoute(node, indent));
277
276
  }
278
277
  children.push(...childNodes.map(
279
- (child) => this.generate(child, indent + " ", effectiveNotFound)
278
+ (child) => this.generate(child, indent + " ")
280
279
  ));
281
- if (effectiveNotFound) {
282
- children.push(this.generateNotFoundRoute(effectiveNotFound, indent));
283
- }
284
280
  return this.generateRouteObject(node, children, indent);
285
281
  }
286
282
  static generateIndexRoute(node, indent) {
@@ -289,14 +285,6 @@ ${indent} index: true,
289
285
  ${indent} element: React.createElement(RouteWrapper, {
290
286
  ${indent} Component: ${node.indexPage}
291
287
  ${indent} })
292
- ${indent} }`;
293
- }
294
- static generateNotFoundRoute(notFoundComponent, indent) {
295
- return `${indent} {
296
- ${indent} path: '*',
297
- ${indent} element: React.createElement(RouteWrapper, {
298
- ${indent} Component: ${notFoundComponent}
299
- ${indent} })
300
288
  ${indent} }`;
301
289
  }
302
290
  static generateRouteObject(node, children, indent) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/plugin.ts","../src/constants.ts","../src/generator/createRoutes.ts","../src/generator/parser/segmentParser.ts","../src/generator/parser/routeTreeBuilder.ts","../src/generator/parser/routeDefinitionGenerator.ts"],"sourcesContent":["export { navilo } from './plugin';\n\nexport type {\n RouteFile,\n RouteType,\n RouteNode,\n ParserOptions\n} from './types';\n\nexport {\n normalizeFilePath,\n getRouteType,\n getComponentName,\n findRouteFiles\n} from './generator/createRoutes';\n\nexport { SegmentParser } from './generator/parser/segmentParser';\nexport { RouteTreeBuilder } from './generator/parser/routeTreeBuilder';\nexport { RouteDefinitionGenerator } from './generator/parser/routeDefinitionGenerator';","// src/plugin.ts\nimport { Plugin } from 'vite';\nimport path from 'path';\nimport fs from 'fs';\nimport { DEFAULT_OPTIONS, RESOLVED_VIRTUAL_ROUTE_MODULE_ID, VIRTUAL_ROUTE_MODULE_ID } from './constants';\nimport {naviloOptions, RouteFile} from './types';\nimport { findRouteFiles } from './generator/createRoutes';\nimport {RouteTreeBuilder} from \"./generator/parser/routeTreeBuilder\";\nimport {RouteDefinitionGenerator} from \"./generator/parser/routeDefinitionGenerator\";\n\nexport function navilo(options: naviloOptions = {}): Plugin {\n const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };\n let root: string;\n const routeTreeBuilder = new RouteTreeBuilder();\n\n return {\n name: 'navilo',\n\n configResolved(config) {\n root = config.root;\n },\n\n configureServer(server) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n server.watcher.add(pagesDir);\n\n const handleFileChange = (file: string) => {\n if (file.startsWith(pagesDir)) {\n const module = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ROUTE_MODULE_ID);\n if (module) {\n server.moduleGraph.invalidateModule(module);\n }\n server.ws.send({ type: 'full-reload' });\n }\n };\n\n server.watcher.on('add', handleFileChange);\n server.watcher.on('unlink', handleFileChange);\n server.watcher.on('change', handleFileChange);\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ROUTE_MODULE_ID) {\n return RESOLVED_VIRTUAL_ROUTE_MODULE_ID;\n }\n },\n\n async load(id) {\n if (id === RESOLVED_VIRTUAL_ROUTE_MODULE_ID) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n if (!fs.existsSync(pagesDir)) {\n fs.mkdirSync(pagesDir, { recursive: true });\n return `export const router = null;`;\n }\n\n const routes = await findRouteFiles(pagesDir);\n\n if (routes.length === 0) {\n return `export const router = null;`;\n }\n\n const routeTree = routeTreeBuilder.build(routes, {\n strict: true,\n dynamicSegmentTransform: (segment) => `:${segment.toLowerCase()}`\n });\n\n const routeDefinitions = RouteDefinitionGenerator.generate(routeTree);\n\n return routerJSX(routes, routeDefinitions);\n }\n }\n };\n}\n\nexport function routerJSX(routes: RouteFile[], routeDefinitions: string): string {\n const importMap = new Map<string, string>();\n routes.forEach(route => importMap.set(route.filePath, route.componentName));\n\n const imports = Array.from(importMap.entries())\n .map(([filePath, componentName]) => `import ${componentName} from '${filePath}';`)\n .join('\\n');\n\n return `\nimport React, { Suspense } from 'react';\nimport { createBrowserRouter, useParams, Outlet, useRouteError, isRouteErrorResponse } from 'react-router-dom';\n${imports}\n\nfunction ErrorBoundary({ Component }) {\n const error = useRouteError();\n const params = useParams();\n\n if (!Component) {\n return React.createElement('div', { className: 'error-container' },\n React.createElement('div', { className: 'error-content' }, [\n React.createElement('h1', null, \n isRouteErrorResponse(error) ? \\`\\${error.status} - \\${error.statusText}\\` : 'Error'\n ),\n React.createElement('pre', { className: 'error-stack' },\n error instanceof Error ? error.stack : JSON.stringify(error, null, 2)\n ),\n React.createElement('button', {\n onClick: () => window.location.reload()\n }, 'Try again')\n ])\n );\n }\n\n return React.createElement(Component, { error, params });\n}\n\nfunction LoadingBoundary({ Component, children }) {\n if (!Component) {\n return children;\n }\n\n return React.createElement(Suspense, {\n fallback: React.createElement(Component)\n }, children);\n}\n\nfunction RouteWrapper({ Component, isLayout, loading, notFound }) {\n const params = useParams();\n \n if (isLayout) {\n const outlet = React.createElement(Outlet);\n const content = loading ? \n React.createElement(LoadingBoundary, { Component: loading }, outlet) :\n outlet;\n\n return React.createElement(Component, {\n children: content,\n params\n });\n }\n \n return React.createElement(Component, { params });\n}\n\n// Add global error listener\nwindow.addEventListener('error', (event) => {\n console.error('Global error:', event.error);\n});\n\n// Add global promise rejection handler\nwindow.addEventListener('unhandledrejection', (event) => {\n console.error('Unhandled promise rejection:', event.reason);\n});\n\nconst router = createBrowserRouter([\n${routeDefinitions}\n], {\n defaultErrorElement: React.createElement(ErrorBoundary, { Component: ${routes.find(r => r.type === 'not-found')?.componentName || 'null'} })\n});\n\nexport { router };\n`;\n}","export const DEFAULT_OPTIONS = {\n pagesDir: 'src/app',\n typescript: true,\n};\n\nexport const VIRTUAL_ROUTE_MODULE_ID = 'virtual:navilo-routes';\nexport const RESOLVED_VIRTUAL_ROUTE_MODULE_ID = '\\0' + VIRTUAL_ROUTE_MODULE_ID;","import path from 'path';\nimport glob from 'fast-glob';\nimport { RouteFile, RouteType } from '../types';\n\n/** Normalize Windows paths to forward slashes */\nexport function normalizeFilePath(filePath: string): string {\n return filePath.replace(/\\\\/g, '/');\n}\n\n/** Determine the type of a route file */\nexport function getRouteType(filePath: string): RouteType {\n const basename = path.basename(filePath);\n const fileTypes: Record<string, RouteType> = {\n 'layout.jsx': 'layout',\n 'layout.tsx': 'layout',\n 'page.jsx': 'page',\n 'page.tsx': 'page',\n 'error.jsx': 'error',\n 'error.tsx': 'error',\n 'loading.jsx': 'loading',\n 'loading.tsx': 'loading',\n 'not-found.jsx': 'not-found',\n 'not-found.tsx': 'not-found'\n };\n return fileTypes[basename] || 'page';\n}\n\n/** Generate a PascalCase component name based on folder structure */\nexport function getComponentName(filePath: string, pagesDir: string): string {\n const segments = normalizeFilePath(path.relative(pagesDir, filePath)).split('/');\n const fileNameWithExt = segments.pop()!;\n const fileName = path.basename(fileNameWithExt, path.extname(fileNameWithExt));\n\n const relevantSegments = segments.map(segment => {\n if (segment.startsWith('[') && segment.endsWith(']')) {\n return segment.slice(1, -1)\n .replace(/^\\.\\.\\./, 'CatchAll')\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n }\n return segment\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n });\n\n const typeSuffix = {\n page: 'Page',\n layout: 'Layout',\n error: 'Error',\n loading: 'Loading',\n 'not-found': 'NotFound'\n }[fileName] || 'Component';\n\n return relevantSegments.length === 0 ? `Root${typeSuffix}` : `${relevantSegments.join('')}${typeSuffix}`;\n}\n\n/** Extract segments from file path for building route tree */\nexport function getPathSegments(filePath: string, pagesDir: string): string[] {\n const relativePath = normalizeFilePath(path.relative(pagesDir, filePath));\n const segments = relativePath.split('/');\n const fileName = segments.pop()!;\n\n const filteredSegments = segments.filter(seg => !(seg.startsWith('(') && seg.endsWith(')')));\n\n if (/^page\\.(jsx|tsx)$/.test(fileName)) {\n filteredSegments.push('');\n }\n\n return filteredSegments;\n}\n\n/** Find all route files in the pages directory */\nexport async function findRouteFiles(pagesDir: string): Promise<RouteFile[]> {\n const files = await glob(['**/*.{jsx,tsx}'], {\n cwd: pagesDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.*/**', '**/_*/**'],\n });\n\n const validFiles = files.filter(file => {\n const base = path.basename(file);\n return /^(layout|page|error|loading|not-found)\\.(jsx|tsx)$/.test(base);\n });\n\n return validFiles.map(file => {\n const type = getRouteType(file);\n return {\n type,\n path: '/' + normalizeFilePath(path.relative(pagesDir, path.dirname(file))),\n filePath: normalizeFilePath(file),\n componentName: getComponentName(file, pagesDir),\n segments: getPathSegments(file, pagesDir),\n };\n });\n}\n","import {ParserOptions} from \"../../types\";\n\nexport class SegmentParser {\n private static readonly SEGMENT_PATTERNS = {\n OPTIONAL_CATCH_ALL: /^\\[\\[\\.{3}(.+)\\]\\]$/,\n CATCH_ALL: /^\\[\\.{3}(.+)\\]$/,\n DYNAMIC: /^\\[(.+)\\]$/,\n GROUP: /^\\((.+)\\)$/\n };\n\n static normalize(segment: string, options?: ParserOptions): string | null {\n if (this.isGroupSegment(segment)) return null;\n\n if (segment.includes('/')) {\n return segment.split('/')\n .map(seg => this.normalizeSegment(seg, options))\n .filter(Boolean)\n .join('/');\n }\n\n return this.normalizeSegment(segment, options);\n }\n\n private static normalizeSegment(segment: string, options?: ParserOptions): string | null {\n const transform = options?.dynamicSegmentTransform || this.defaultTransform;\n\n if (this.isOptionalCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL)![1];\n return transform(`${name}*?`);\n }\n\n if (this.isCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.CATCH_ALL)![1];\n return transform(`${name}*`);\n }\n\n if (this.isDynamicSegment(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.DYNAMIC)![1];\n return transform(name);\n }\n\n return segment;\n }\n\n private static defaultTransform(name: string): string {\n return `:${name}`;\n }\n\n private static isGroupSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.GROUP.test(segment);\n }\n\n private static isOptionalCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL.test(segment);\n }\n\n private static isCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.CATCH_ALL.test(segment);\n }\n\n private static isDynamicSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.DYNAMIC.test(segment);\n }\n}","import {SegmentParser} from './segmentParser';\nimport {ParserOptions, RouteFile, RouteNode} from \"../../types\";\n\nexport class RouteTreeBuilder {\n private readonly typeSetters: Record<string, (node: RouteNode, route: RouteFile) => void>;\n\n constructor() {\n this.typeSetters = {\n layout: (node, route) => {\n node.layout = route.componentName;\n },\n error: (node, route) => {\n node.error = route.componentName;\n },\n loading: (node, route) => {\n node.loading = route.componentName;\n },\n 'not-found': (node, route) => {\n node.notFound = route.componentName;\n },\n page: this.handlePageType.bind(this)\n };\n }\n\n build(routes: RouteFile[], options?: ParserOptions): RouteNode {\n const root: RouteNode = {\n segment: '',\n path: '/',\n fullPath: '/',\n children: new Map(),\n metadata: options?.metadata\n };\n\n const sortedRoutes = this.sortRoutes(routes);\n sortedRoutes.forEach(route => {\n this.processRoute(root, route, options);\n });\n\n return root;\n }\n\n private sortRoutes(routes: RouteFile[]): RouteFile[] {\n return [...routes].sort((a, b) =>\n a.type === 'layout' && b.type !== 'layout' ? -1 :\n a.type !== 'layout' && b.type === 'layout' ? 1 : 0\n );\n }\n\n private processRoute(root: RouteNode, route: RouteFile, options?: ParserOptions): void {\n const segments = route.segments.map(seg => String(seg));\n\n if (segments.length === 0) {\n this.applyTypeHandler(root, route);\n if (route.type === 'page') root.isIndex = true;\n return;\n }\n\n let current = root;\n let currentPath = '';\n\n segments.forEach((seg, idx) => {\n const isLast = idx === segments.length - 1;\n const key = SegmentParser.normalize(seg, options);\n\n if (key === null) return;\n\n currentPath = this.buildFullPath(currentPath, key);\n\n if (!current.children.has(key)) {\n current.children.set(key, {\n segment: key,\n path: key,\n fullPath: currentPath,\n children: new Map(),\n metadata: options?.metadata\n });\n }\n\n current = current.children.get(key)!;\n\n if (isLast) this.applyTypeHandler(current, route);\n });\n }\n\n private buildFullPath(currentPath: string, key: string): string {\n if (currentPath === '' || currentPath === '/') {\n return key === '' ? '/' : `/${key}`;\n }\n return `${currentPath}/${key}`;\n }\n\n private applyTypeHandler(node: RouteNode, route: RouteFile): void {\n const handler = this.typeSetters[route.type];\n if (handler) handler(node, route);\n }\n\n private handlePageType(node: RouteNode, route: RouteFile): void {\n const lastSegment = route.segments[route.segments.length - 1];\n const isDynamic = lastSegment?.startsWith('[');\n\n if (isDynamic || lastSegment === '') {\n node.component = route.componentName;\n node.isIndex = false;\n } else {\n node.indexPage = route.componentName;\n }\n }\n}","import { RouteNode } from \"../../types\";\n\nexport class RouteDefinitionGenerator {\n static generate(node: RouteNode, indent = ' ', inheritedNotFound?: string): string {\n const childNodes = Array.from(node.children.values());\n const children: string[] = [];\n const effectiveNotFound = node.notFound || inheritedNotFound;\n\n if (node.indexPage) {\n children.push(this.generateIndexRoute(node, indent));\n }\n\n children.push(...childNodes.map(child =>\n this.generate(child, indent + ' ', effectiveNotFound)\n ));\n\n if (effectiveNotFound) {\n children.push(this.generateNotFoundRoute(effectiveNotFound, indent));\n }\n\n return this.generateRouteObject(node, children, indent);\n }\n\n private static generateIndexRoute(node: RouteNode, indent: string): string {\n return `${indent} {\n${indent} index: true,\n${indent} element: React.createElement(RouteWrapper, {\n${indent} Component: ${node.indexPage}\n${indent} })\n${indent} }`;\n }\n\n private static generateNotFoundRoute(notFoundComponent: string, indent: string): string {\n return `${indent} {\n${indent} path: '*',\n${indent} element: React.createElement(RouteWrapper, {\n${indent} Component: ${notFoundComponent}\n${indent} })\n${indent} }`;\n }\n\n private static generateRouteObject(node: RouteNode, children: string[], indent: string): string {\n const pathStr = node.fullPath;\n const elementStr = this.generateElementString(node, indent);\n const errorStr = this.generateErrorString(node, indent);\n\n return [\n `${indent}{`,\n `${indent} path: '${pathStr}'${elementStr}${errorStr}`,\n children.length > 0 ? `,\\n${indent} children: [\\n${children.join(',\\n')}\\n${indent} ]` : '',\n `${indent}}`\n ].filter(Boolean).join('');\n }\n\n private static generateElementString(node: RouteNode, indent: string): string {\n if (!node.layout && !node.component) return '';\n\n const props = node.layout\n ? this.generateLayoutProps(node, indent)\n : this.generateComponentProps(node, indent);\n\n return `,\\n${indent} element: React.createElement(RouteWrapper, ${props})`;\n }\n\n private static generateLayoutProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.layout},\n${indent} isLayout: true,\n${indent} loading: ${node.loading || 'undefined'},\n${indent} notFound: ${node.notFound || 'undefined'}\n${indent} }`;\n }\n\n private static generateComponentProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.component}\n${indent} }`;\n }\n\n private static generateErrorString(node: RouteNode, indent: string): string {\n if (!node.error) return '';\n\n return `,\\n${indent} errorElement: React.createElement(ErrorBoundary, {\n${indent} Component: ${node.error}\n${indent} })`;\n }\n}"],"mappings":"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","names":["import_path","path","glob","path","module","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/plugin.ts","../src/constants.ts","../src/generator/createRoutes.ts","../src/generator/parser/segmentParser.ts","../src/generator/parser/routeTreeBuilder.ts","../src/generator/parser/routeDefinitionGenerator.ts"],"sourcesContent":["export { navilo } from './plugin';\n\nexport type {\n RouteFile,\n RouteType,\n RouteNode,\n ParserOptions\n} from './types';\n\nexport {\n normalizeFilePath,\n getRouteType,\n getComponentName,\n findRouteFiles\n} from './generator/createRoutes';\n\nexport { SegmentParser } from './generator/parser/segmentParser';\nexport { RouteTreeBuilder } from './generator/parser/routeTreeBuilder';\nexport { RouteDefinitionGenerator } from './generator/parser/routeDefinitionGenerator';","// src/plugin.ts\nimport { Plugin } from 'vite';\nimport path from 'path';\nimport fs from 'fs';\nimport { DEFAULT_OPTIONS, RESOLVED_VIRTUAL_ROUTE_MODULE_ID, VIRTUAL_ROUTE_MODULE_ID } from './constants';\nimport {naviloOptions, RouteFile} from './types';\nimport { findRouteFiles } from './generator/createRoutes';\nimport {RouteTreeBuilder} from \"./generator/parser/routeTreeBuilder\";\nimport {RouteDefinitionGenerator} from \"./generator/parser/routeDefinitionGenerator\";\n\nexport function navilo(options: naviloOptions = {}): Plugin {\n const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };\n let root: string;\n const routeTreeBuilder = new RouteTreeBuilder();\n\n return {\n name: 'navilo',\n\n configResolved(config) {\n root = config.root;\n },\n\n configureServer(server) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n server.watcher.add(pagesDir);\n\n const handleFileChange = (file: string) => {\n if (file.startsWith(pagesDir)) {\n const module = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ROUTE_MODULE_ID);\n if (module) {\n server.moduleGraph.invalidateModule(module);\n }\n server.ws.send({ type: 'full-reload' });\n }\n };\n\n server.watcher.on('add', handleFileChange);\n server.watcher.on('unlink', handleFileChange);\n server.watcher.on('change', handleFileChange);\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ROUTE_MODULE_ID) {\n return RESOLVED_VIRTUAL_ROUTE_MODULE_ID;\n }\n },\n\n async load(id) {\n if (id === RESOLVED_VIRTUAL_ROUTE_MODULE_ID) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n if (!fs.existsSync(pagesDir)) {\n fs.mkdirSync(pagesDir, { recursive: true });\n return `export const router = null;`;\n }\n\n const routes = await findRouteFiles(pagesDir);\n\n if (routes.length === 0) {\n return `export const router = null;`;\n }\n\n const routeTree = routeTreeBuilder.build(routes, {\n strict: true,\n dynamicSegmentTransform: (segment) => `:${segment.toLowerCase()}`\n });\n\n const routeDefinitions = RouteDefinitionGenerator.generate(routeTree);\n\n return routerJSX(routes, routeDefinitions);\n }\n }\n };\n}\n\nexport function routerJSX(routes: RouteFile[], routeDefinitions: string): string {\n const importMap = new Map<string, string>();\n routes.forEach(route => importMap.set(route.filePath, route.componentName));\n\n const imports = Array.from(importMap.entries())\n .map(([filePath, componentName]) => `import ${componentName} from '${filePath}';`)\n .join('\\n');\n\n return `\nimport React, { Suspense } from 'react';\nimport { createBrowserRouter, useParams, Outlet, useRouteError, isRouteErrorResponse } from 'react-router-dom';\n${imports}\n\nfunction ErrorBoundary({ Component }) {\n const error = useRouteError();\n const params = useParams();\n\n if (!Component) {\n return React.createElement('div', { className: 'error-container' },\n React.createElement('div', { className: 'error-content' }, [\n React.createElement('h1', null, \n isRouteErrorResponse(error) ? \\`\\${error.status} - \\${error.statusText}\\` : 'Error'\n ),\n React.createElement('pre', { className: 'error-stack' },\n error instanceof Error ? error.stack : JSON.stringify(error, null, 2)\n ),\n React.createElement('button', {\n onClick: () => window.location.reload()\n }, 'Try again')\n ])\n );\n }\n\n return React.createElement(Component, { error, params });\n}\n\nfunction LoadingBoundary({ Component, children }) {\n if (!Component) {\n return children;\n }\n\n return React.createElement(Suspense, {\n fallback: React.createElement(Component)\n }, children);\n}\n\nfunction RouteWrapper({ Component, isLayout, loading, notFound }) {\n const params = useParams();\n \n if (isLayout) {\n const outlet = React.createElement(Outlet);\n const content = loading ? \n React.createElement(LoadingBoundary, { Component: loading }, outlet) :\n outlet;\n\n return React.createElement(Component, {\n children: content,\n params\n });\n }\n \n return React.createElement(Component, { params });\n}\n\n// Add global error listener\nwindow.addEventListener('error', (event) => {\n console.error('Global error:', event.error);\n});\n\n// Add global promise rejection handler\nwindow.addEventListener('unhandledrejection', (event) => {\n console.error('Unhandled promise rejection:', event.reason);\n});\n\nconst router = createBrowserRouter([\n${routeDefinitions}\n], {\n defaultErrorElement: React.createElement(ErrorBoundary, { Component: ${routes.find(r => r.type === 'not-found')?.componentName || 'null'} })\n});\n\nexport { router };\n`;\n}","export const DEFAULT_OPTIONS = {\n pagesDir: 'src/app',\n typescript: true,\n};\n\nexport const VIRTUAL_ROUTE_MODULE_ID = 'virtual:navilo-routes';\nexport const RESOLVED_VIRTUAL_ROUTE_MODULE_ID = '\\0' + VIRTUAL_ROUTE_MODULE_ID;","import path from 'path';\nimport glob from 'fast-glob';\nimport { RouteFile, RouteType } from '../types';\n\n/** Normalize Windows paths to forward slashes */\nexport function normalizeFilePath(filePath: string): string {\n return filePath.replace(/\\\\/g, '/');\n}\n\n/** Determine the type of a route file */\nexport function getRouteType(filePath: string): RouteType {\n const basename = path.basename(filePath);\n const fileTypes: Record<string, RouteType> = {\n 'layout.jsx': 'layout',\n 'layout.tsx': 'layout',\n 'page.jsx': 'page',\n 'page.tsx': 'page',\n 'error.jsx': 'error',\n 'error.tsx': 'error',\n 'loading.jsx': 'loading',\n 'loading.tsx': 'loading',\n 'not-found.jsx': 'not-found',\n 'not-found.tsx': 'not-found'\n };\n return fileTypes[basename] || 'page';\n}\n\n/** Generate a PascalCase component name based on folder structure */\nexport function getComponentName(filePath: string, pagesDir: string): string {\n const segments = normalizeFilePath(path.relative(pagesDir, filePath)).split('/');\n const fileNameWithExt = segments.pop()!;\n const fileName = path.basename(fileNameWithExt, path.extname(fileNameWithExt));\n\n const relevantSegments = segments.map(segment => {\n if (segment.startsWith('[') && segment.endsWith(']')) {\n return segment.slice(1, -1)\n .replace(/^\\.\\.\\./, 'CatchAll')\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n }\n return segment\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n });\n\n const typeSuffix = {\n page: 'Page',\n layout: 'Layout',\n error: 'Error',\n loading: 'Loading',\n 'not-found': 'NotFound'\n }[fileName] || 'Component';\n\n return relevantSegments.length === 0 ? `Root${typeSuffix}` : `${relevantSegments.join('')}${typeSuffix}`;\n}\n\n/** Extract segments from file path for building route tree */\nexport function getPathSegments(filePath: string, pagesDir: string): string[] {\n const relativePath = normalizeFilePath(path.relative(pagesDir, filePath));\n const segments = relativePath.split('/');\n const fileName = segments.pop()!;\n\n const filteredSegments = segments.filter(seg => !(seg.startsWith('(') && seg.endsWith(')')));\n\n if (/^page\\.(jsx|tsx)$/.test(fileName)) {\n filteredSegments.push('');\n }\n\n return filteredSegments;\n}\n\n/** Find all route files in the pages directory */\nexport async function findRouteFiles(pagesDir: string): Promise<RouteFile[]> {\n const files = await glob(['**/*.{jsx,tsx}'], {\n cwd: pagesDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.*/**', '**/_*/**'],\n });\n\n const validFiles = files.filter(file => {\n const base = path.basename(file);\n return /^(layout|page|error|loading|not-found)\\.(jsx|tsx)$/.test(base);\n });\n\n return validFiles.map(file => {\n const type = getRouteType(file);\n return {\n type,\n path: '/' + normalizeFilePath(path.relative(pagesDir, path.dirname(file))),\n filePath: normalizeFilePath(file),\n componentName: getComponentName(file, pagesDir),\n segments: getPathSegments(file, pagesDir),\n };\n });\n}\n","import {ParserOptions} from \"../../types\";\n\nexport class SegmentParser {\n private static readonly SEGMENT_PATTERNS = {\n OPTIONAL_CATCH_ALL: /^\\[\\[\\.{3}(.+)\\]\\]$/,\n CATCH_ALL: /^\\[\\.{3}(.+)\\]$/,\n DYNAMIC: /^\\[(.+)\\]$/,\n GROUP: /^\\((.+)\\)$/\n };\n\n static normalize(segment: string, options?: ParserOptions): string | null {\n if (this.isGroupSegment(segment)) return null;\n\n if (segment.includes('/')) {\n return segment.split('/')\n .map(seg => this.normalizeSegment(seg, options))\n .filter(Boolean)\n .join('/');\n }\n\n return this.normalizeSegment(segment, options);\n }\n\n private static normalizeSegment(segment: string, options?: ParserOptions): string | null {\n const transform = options?.dynamicSegmentTransform || this.defaultTransform;\n\n if (this.isOptionalCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL)![1];\n return transform(`${name}*?`);\n }\n\n if (this.isCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.CATCH_ALL)![1];\n return transform(`${name}*`);\n }\n\n if (this.isDynamicSegment(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.DYNAMIC)![1];\n return transform(name);\n }\n\n return segment;\n }\n\n private static defaultTransform(name: string): string {\n return `:${name}`;\n }\n\n private static isGroupSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.GROUP.test(segment);\n }\n\n private static isOptionalCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL.test(segment);\n }\n\n private static isCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.CATCH_ALL.test(segment);\n }\n\n private static isDynamicSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.DYNAMIC.test(segment);\n }\n}","import {SegmentParser} from './segmentParser';\nimport {ParserOptions, RouteFile, RouteNode} from \"../../types\";\n\nexport class RouteTreeBuilder {\n private readonly typeSetters: Record<string, (node: RouteNode, route: RouteFile) => void>;\n\n constructor() {\n this.typeSetters = {\n layout: (node, route) => {\n node.layout = route.componentName;\n },\n error: (node, route) => {\n node.error = route.componentName;\n },\n loading: (node, route) => {\n node.loading = route.componentName;\n },\n 'not-found': (node, route) => {\n node.notFound = route.componentName;\n },\n page: this.handlePageType.bind(this)\n };\n }\n\n build(routes: RouteFile[], options?: ParserOptions): RouteNode {\n const root: RouteNode = {\n segment: '',\n path: '/',\n fullPath: '/',\n children: new Map(),\n metadata: options?.metadata\n };\n\n const sortedRoutes = this.sortRoutes(routes);\n sortedRoutes.forEach(route => {\n this.processRoute(root, route, options);\n });\n\n return root;\n }\n\n private sortRoutes(routes: RouteFile[]): RouteFile[] {\n return [...routes].sort((a, b) =>\n a.type === 'layout' && b.type !== 'layout' ? -1 :\n a.type !== 'layout' && b.type === 'layout' ? 1 : 0\n );\n }\n\n private processRoute(root: RouteNode, route: RouteFile, options?: ParserOptions): void {\n const segments = route.segments.map(seg => String(seg));\n\n if (segments.length === 0) {\n this.applyTypeHandler(root, route);\n if (route.type === 'page') root.isIndex = true;\n return;\n }\n\n let current = root;\n let currentPath = '';\n\n segments.forEach((seg, idx) => {\n const isLast = idx === segments.length - 1;\n const key = SegmentParser.normalize(seg, options);\n\n if (key === null) return;\n\n currentPath = this.buildFullPath(currentPath, key);\n\n if (!current.children.has(key)) {\n current.children.set(key, {\n segment: key,\n path: key,\n fullPath: currentPath,\n children: new Map(),\n metadata: options?.metadata\n });\n }\n\n current = current.children.get(key)!;\n\n if (isLast) this.applyTypeHandler(current, route);\n });\n }\n\n private buildFullPath(currentPath: string, key: string): string {\n if (currentPath === '' || currentPath === '/') {\n return key === '' ? '/' : `/${key}`;\n }\n return `${currentPath}/${key}`;\n }\n\n private applyTypeHandler(node: RouteNode, route: RouteFile): void {\n const handler = this.typeSetters[route.type];\n if (handler) handler(node, route);\n }\n\n private handlePageType(node: RouteNode, route: RouteFile): void {\n const lastSegment = route.segments[route.segments.length - 1];\n const isDynamic = lastSegment?.startsWith('[');\n\n if (isDynamic || lastSegment === '') {\n node.component = route.componentName;\n node.isIndex = false;\n } else {\n node.indexPage = route.componentName;\n }\n }\n}","import { RouteNode } from \"../../types\";\n\nexport class RouteDefinitionGenerator {\n static generate(node: RouteNode, indent = ' '): string {\n const childNodes = Array.from(node.children.values());\n const children: string[] = [];\n\n if (node.indexPage) {\n children.push(this.generateIndexRoute(node, indent));\n }\n\n children.push(...childNodes.map(child =>\n this.generate(child, indent + ' ')\n ));\n\n return this.generateRouteObject(node, children, indent);\n }\n\n private static generateIndexRoute(node: RouteNode, indent: string): string {\n return `${indent} {\n${indent} index: true,\n${indent} element: React.createElement(RouteWrapper, {\n${indent} Component: ${node.indexPage}\n${indent} })\n${indent} }`;\n }\n\n private static generateRouteObject(node: RouteNode, children: string[], indent: string): string {\n const pathStr = node.fullPath;\n const elementStr = this.generateElementString(node, indent);\n const errorStr = this.generateErrorString(node, indent);\n\n return [\n `${indent}{`,\n `${indent} path: '${pathStr}'${elementStr}${errorStr}`,\n children.length > 0 ? `,\\n${indent} children: [\\n${children.join(',\\n')}\\n${indent} ]` : '',\n `${indent}}`\n ].filter(Boolean).join('');\n }\n\n private static generateElementString(node: RouteNode, indent: string): string {\n if (!node.layout && !node.component) return '';\n\n const props = node.layout\n ? this.generateLayoutProps(node, indent)\n : this.generateComponentProps(node, indent);\n\n return `,\\n${indent} element: React.createElement(RouteWrapper, ${props})`;\n }\n\n private static generateLayoutProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.layout},\n${indent} isLayout: true,\n${indent} loading: ${node.loading || 'undefined'},\n${indent} notFound: ${node.notFound || 'undefined'}\n${indent} }`;\n }\n\n private static generateComponentProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.component}\n${indent} }`;\n }\n\n private static generateErrorString(node: RouteNode, indent: string): string {\n if (!node.error) return '';\n\n return `,\\n${indent} errorElement: React.createElement(ErrorBoundary, {\n${indent} Component: ${node.error}\n${indent} })`;\n }\n}"],"mappings":"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","names":["import_path","path","glob","path","module","fs"]}
package/dist/index.mjs CHANGED
@@ -225,19 +225,15 @@ var RouteTreeBuilder = class {
225
225
 
226
226
  // src/generator/parser/routeDefinitionGenerator.ts
227
227
  var RouteDefinitionGenerator = class {
228
- static generate(node, indent = " ", inheritedNotFound) {
228
+ static generate(node, indent = " ") {
229
229
  const childNodes = Array.from(node.children.values());
230
230
  const children = [];
231
- const effectiveNotFound = node.notFound || inheritedNotFound;
232
231
  if (node.indexPage) {
233
232
  children.push(this.generateIndexRoute(node, indent));
234
233
  }
235
234
  children.push(...childNodes.map(
236
- (child) => this.generate(child, indent + " ", effectiveNotFound)
235
+ (child) => this.generate(child, indent + " ")
237
236
  ));
238
- if (effectiveNotFound) {
239
- children.push(this.generateNotFoundRoute(effectiveNotFound, indent));
240
- }
241
237
  return this.generateRouteObject(node, children, indent);
242
238
  }
243
239
  static generateIndexRoute(node, indent) {
@@ -246,14 +242,6 @@ ${indent} index: true,
246
242
  ${indent} element: React.createElement(RouteWrapper, {
247
243
  ${indent} Component: ${node.indexPage}
248
244
  ${indent} })
249
- ${indent} }`;
250
- }
251
- static generateNotFoundRoute(notFoundComponent, indent) {
252
- return `${indent} {
253
- ${indent} path: '*',
254
- ${indent} element: React.createElement(RouteWrapper, {
255
- ${indent} Component: ${notFoundComponent}
256
- ${indent} })
257
245
  ${indent} }`;
258
246
  }
259
247
  static generateRouteObject(node, children, indent) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin.ts","../src/constants.ts","../src/generator/createRoutes.ts","../src/generator/parser/segmentParser.ts","../src/generator/parser/routeTreeBuilder.ts","../src/generator/parser/routeDefinitionGenerator.ts"],"sourcesContent":["// src/plugin.ts\nimport { Plugin } from 'vite';\nimport path from 'path';\nimport fs from 'fs';\nimport { DEFAULT_OPTIONS, RESOLVED_VIRTUAL_ROUTE_MODULE_ID, VIRTUAL_ROUTE_MODULE_ID } from './constants';\nimport {naviloOptions, RouteFile} from './types';\nimport { findRouteFiles } from './generator/createRoutes';\nimport {RouteTreeBuilder} from \"./generator/parser/routeTreeBuilder\";\nimport {RouteDefinitionGenerator} from \"./generator/parser/routeDefinitionGenerator\";\n\nexport function navilo(options: naviloOptions = {}): Plugin {\n const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };\n let root: string;\n const routeTreeBuilder = new RouteTreeBuilder();\n\n return {\n name: 'navilo',\n\n configResolved(config) {\n root = config.root;\n },\n\n configureServer(server) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n server.watcher.add(pagesDir);\n\n const handleFileChange = (file: string) => {\n if (file.startsWith(pagesDir)) {\n const module = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ROUTE_MODULE_ID);\n if (module) {\n server.moduleGraph.invalidateModule(module);\n }\n server.ws.send({ type: 'full-reload' });\n }\n };\n\n server.watcher.on('add', handleFileChange);\n server.watcher.on('unlink', handleFileChange);\n server.watcher.on('change', handleFileChange);\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ROUTE_MODULE_ID) {\n return RESOLVED_VIRTUAL_ROUTE_MODULE_ID;\n }\n },\n\n async load(id) {\n if (id === RESOLVED_VIRTUAL_ROUTE_MODULE_ID) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n if (!fs.existsSync(pagesDir)) {\n fs.mkdirSync(pagesDir, { recursive: true });\n return `export const router = null;`;\n }\n\n const routes = await findRouteFiles(pagesDir);\n\n if (routes.length === 0) {\n return `export const router = null;`;\n }\n\n const routeTree = routeTreeBuilder.build(routes, {\n strict: true,\n dynamicSegmentTransform: (segment) => `:${segment.toLowerCase()}`\n });\n\n const routeDefinitions = RouteDefinitionGenerator.generate(routeTree);\n\n return routerJSX(routes, routeDefinitions);\n }\n }\n };\n}\n\nexport function routerJSX(routes: RouteFile[], routeDefinitions: string): string {\n const importMap = new Map<string, string>();\n routes.forEach(route => importMap.set(route.filePath, route.componentName));\n\n const imports = Array.from(importMap.entries())\n .map(([filePath, componentName]) => `import ${componentName} from '${filePath}';`)\n .join('\\n');\n\n return `\nimport React, { Suspense } from 'react';\nimport { createBrowserRouter, useParams, Outlet, useRouteError, isRouteErrorResponse } from 'react-router-dom';\n${imports}\n\nfunction ErrorBoundary({ Component }) {\n const error = useRouteError();\n const params = useParams();\n\n if (!Component) {\n return React.createElement('div', { className: 'error-container' },\n React.createElement('div', { className: 'error-content' }, [\n React.createElement('h1', null, \n isRouteErrorResponse(error) ? \\`\\${error.status} - \\${error.statusText}\\` : 'Error'\n ),\n React.createElement('pre', { className: 'error-stack' },\n error instanceof Error ? error.stack : JSON.stringify(error, null, 2)\n ),\n React.createElement('button', {\n onClick: () => window.location.reload()\n }, 'Try again')\n ])\n );\n }\n\n return React.createElement(Component, { error, params });\n}\n\nfunction LoadingBoundary({ Component, children }) {\n if (!Component) {\n return children;\n }\n\n return React.createElement(Suspense, {\n fallback: React.createElement(Component)\n }, children);\n}\n\nfunction RouteWrapper({ Component, isLayout, loading, notFound }) {\n const params = useParams();\n \n if (isLayout) {\n const outlet = React.createElement(Outlet);\n const content = loading ? \n React.createElement(LoadingBoundary, { Component: loading }, outlet) :\n outlet;\n\n return React.createElement(Component, {\n children: content,\n params\n });\n }\n \n return React.createElement(Component, { params });\n}\n\n// Add global error listener\nwindow.addEventListener('error', (event) => {\n console.error('Global error:', event.error);\n});\n\n// Add global promise rejection handler\nwindow.addEventListener('unhandledrejection', (event) => {\n console.error('Unhandled promise rejection:', event.reason);\n});\n\nconst router = createBrowserRouter([\n${routeDefinitions}\n], {\n defaultErrorElement: React.createElement(ErrorBoundary, { Component: ${routes.find(r => r.type === 'not-found')?.componentName || 'null'} })\n});\n\nexport { router };\n`;\n}","export const DEFAULT_OPTIONS = {\n pagesDir: 'src/app',\n typescript: true,\n};\n\nexport const VIRTUAL_ROUTE_MODULE_ID = 'virtual:navilo-routes';\nexport const RESOLVED_VIRTUAL_ROUTE_MODULE_ID = '\\0' + VIRTUAL_ROUTE_MODULE_ID;","import path from 'path';\nimport glob from 'fast-glob';\nimport { RouteFile, RouteType } from '../types';\n\n/** Normalize Windows paths to forward slashes */\nexport function normalizeFilePath(filePath: string): string {\n return filePath.replace(/\\\\/g, '/');\n}\n\n/** Determine the type of a route file */\nexport function getRouteType(filePath: string): RouteType {\n const basename = path.basename(filePath);\n const fileTypes: Record<string, RouteType> = {\n 'layout.jsx': 'layout',\n 'layout.tsx': 'layout',\n 'page.jsx': 'page',\n 'page.tsx': 'page',\n 'error.jsx': 'error',\n 'error.tsx': 'error',\n 'loading.jsx': 'loading',\n 'loading.tsx': 'loading',\n 'not-found.jsx': 'not-found',\n 'not-found.tsx': 'not-found'\n };\n return fileTypes[basename] || 'page';\n}\n\n/** Generate a PascalCase component name based on folder structure */\nexport function getComponentName(filePath: string, pagesDir: string): string {\n const segments = normalizeFilePath(path.relative(pagesDir, filePath)).split('/');\n const fileNameWithExt = segments.pop()!;\n const fileName = path.basename(fileNameWithExt, path.extname(fileNameWithExt));\n\n const relevantSegments = segments.map(segment => {\n if (segment.startsWith('[') && segment.endsWith(']')) {\n return segment.slice(1, -1)\n .replace(/^\\.\\.\\./, 'CatchAll')\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n }\n return segment\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n });\n\n const typeSuffix = {\n page: 'Page',\n layout: 'Layout',\n error: 'Error',\n loading: 'Loading',\n 'not-found': 'NotFound'\n }[fileName] || 'Component';\n\n return relevantSegments.length === 0 ? `Root${typeSuffix}` : `${relevantSegments.join('')}${typeSuffix}`;\n}\n\n/** Extract segments from file path for building route tree */\nexport function getPathSegments(filePath: string, pagesDir: string): string[] {\n const relativePath = normalizeFilePath(path.relative(pagesDir, filePath));\n const segments = relativePath.split('/');\n const fileName = segments.pop()!;\n\n const filteredSegments = segments.filter(seg => !(seg.startsWith('(') && seg.endsWith(')')));\n\n if (/^page\\.(jsx|tsx)$/.test(fileName)) {\n filteredSegments.push('');\n }\n\n return filteredSegments;\n}\n\n/** Find all route files in the pages directory */\nexport async function findRouteFiles(pagesDir: string): Promise<RouteFile[]> {\n const files = await glob(['**/*.{jsx,tsx}'], {\n cwd: pagesDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.*/**', '**/_*/**'],\n });\n\n const validFiles = files.filter(file => {\n const base = path.basename(file);\n return /^(layout|page|error|loading|not-found)\\.(jsx|tsx)$/.test(base);\n });\n\n return validFiles.map(file => {\n const type = getRouteType(file);\n return {\n type,\n path: '/' + normalizeFilePath(path.relative(pagesDir, path.dirname(file))),\n filePath: normalizeFilePath(file),\n componentName: getComponentName(file, pagesDir),\n segments: getPathSegments(file, pagesDir),\n };\n });\n}\n","import {ParserOptions} from \"../../types\";\n\nexport class SegmentParser {\n private static readonly SEGMENT_PATTERNS = {\n OPTIONAL_CATCH_ALL: /^\\[\\[\\.{3}(.+)\\]\\]$/,\n CATCH_ALL: /^\\[\\.{3}(.+)\\]$/,\n DYNAMIC: /^\\[(.+)\\]$/,\n GROUP: /^\\((.+)\\)$/\n };\n\n static normalize(segment: string, options?: ParserOptions): string | null {\n if (this.isGroupSegment(segment)) return null;\n\n if (segment.includes('/')) {\n return segment.split('/')\n .map(seg => this.normalizeSegment(seg, options))\n .filter(Boolean)\n .join('/');\n }\n\n return this.normalizeSegment(segment, options);\n }\n\n private static normalizeSegment(segment: string, options?: ParserOptions): string | null {\n const transform = options?.dynamicSegmentTransform || this.defaultTransform;\n\n if (this.isOptionalCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL)![1];\n return transform(`${name}*?`);\n }\n\n if (this.isCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.CATCH_ALL)![1];\n return transform(`${name}*`);\n }\n\n if (this.isDynamicSegment(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.DYNAMIC)![1];\n return transform(name);\n }\n\n return segment;\n }\n\n private static defaultTransform(name: string): string {\n return `:${name}`;\n }\n\n private static isGroupSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.GROUP.test(segment);\n }\n\n private static isOptionalCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL.test(segment);\n }\n\n private static isCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.CATCH_ALL.test(segment);\n }\n\n private static isDynamicSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.DYNAMIC.test(segment);\n }\n}","import {SegmentParser} from './segmentParser';\nimport {ParserOptions, RouteFile, RouteNode} from \"../../types\";\n\nexport class RouteTreeBuilder {\n private readonly typeSetters: Record<string, (node: RouteNode, route: RouteFile) => void>;\n\n constructor() {\n this.typeSetters = {\n layout: (node, route) => {\n node.layout = route.componentName;\n },\n error: (node, route) => {\n node.error = route.componentName;\n },\n loading: (node, route) => {\n node.loading = route.componentName;\n },\n 'not-found': (node, route) => {\n node.notFound = route.componentName;\n },\n page: this.handlePageType.bind(this)\n };\n }\n\n build(routes: RouteFile[], options?: ParserOptions): RouteNode {\n const root: RouteNode = {\n segment: '',\n path: '/',\n fullPath: '/',\n children: new Map(),\n metadata: options?.metadata\n };\n\n const sortedRoutes = this.sortRoutes(routes);\n sortedRoutes.forEach(route => {\n this.processRoute(root, route, options);\n });\n\n return root;\n }\n\n private sortRoutes(routes: RouteFile[]): RouteFile[] {\n return [...routes].sort((a, b) =>\n a.type === 'layout' && b.type !== 'layout' ? -1 :\n a.type !== 'layout' && b.type === 'layout' ? 1 : 0\n );\n }\n\n private processRoute(root: RouteNode, route: RouteFile, options?: ParserOptions): void {\n const segments = route.segments.map(seg => String(seg));\n\n if (segments.length === 0) {\n this.applyTypeHandler(root, route);\n if (route.type === 'page') root.isIndex = true;\n return;\n }\n\n let current = root;\n let currentPath = '';\n\n segments.forEach((seg, idx) => {\n const isLast = idx === segments.length - 1;\n const key = SegmentParser.normalize(seg, options);\n\n if (key === null) return;\n\n currentPath = this.buildFullPath(currentPath, key);\n\n if (!current.children.has(key)) {\n current.children.set(key, {\n segment: key,\n path: key,\n fullPath: currentPath,\n children: new Map(),\n metadata: options?.metadata\n });\n }\n\n current = current.children.get(key)!;\n\n if (isLast) this.applyTypeHandler(current, route);\n });\n }\n\n private buildFullPath(currentPath: string, key: string): string {\n if (currentPath === '' || currentPath === '/') {\n return key === '' ? '/' : `/${key}`;\n }\n return `${currentPath}/${key}`;\n }\n\n private applyTypeHandler(node: RouteNode, route: RouteFile): void {\n const handler = this.typeSetters[route.type];\n if (handler) handler(node, route);\n }\n\n private handlePageType(node: RouteNode, route: RouteFile): void {\n const lastSegment = route.segments[route.segments.length - 1];\n const isDynamic = lastSegment?.startsWith('[');\n\n if (isDynamic || lastSegment === '') {\n node.component = route.componentName;\n node.isIndex = false;\n } else {\n node.indexPage = route.componentName;\n }\n }\n}","import { RouteNode } from \"../../types\";\n\nexport class RouteDefinitionGenerator {\n static generate(node: RouteNode, indent = ' ', inheritedNotFound?: string): string {\n const childNodes = Array.from(node.children.values());\n const children: string[] = [];\n const effectiveNotFound = node.notFound || inheritedNotFound;\n\n if (node.indexPage) {\n children.push(this.generateIndexRoute(node, indent));\n }\n\n children.push(...childNodes.map(child =>\n this.generate(child, indent + ' ', effectiveNotFound)\n ));\n\n if (effectiveNotFound) {\n children.push(this.generateNotFoundRoute(effectiveNotFound, indent));\n }\n\n return this.generateRouteObject(node, children, indent);\n }\n\n private static generateIndexRoute(node: RouteNode, indent: string): string {\n return `${indent} {\n${indent} index: true,\n${indent} element: React.createElement(RouteWrapper, {\n${indent} Component: ${node.indexPage}\n${indent} })\n${indent} }`;\n }\n\n private static generateNotFoundRoute(notFoundComponent: string, indent: string): string {\n return `${indent} {\n${indent} path: '*',\n${indent} element: React.createElement(RouteWrapper, {\n${indent} Component: ${notFoundComponent}\n${indent} })\n${indent} }`;\n }\n\n private static generateRouteObject(node: RouteNode, children: string[], indent: string): string {\n const pathStr = node.fullPath;\n const elementStr = this.generateElementString(node, indent);\n const errorStr = this.generateErrorString(node, indent);\n\n return [\n `${indent}{`,\n `${indent} path: '${pathStr}'${elementStr}${errorStr}`,\n children.length > 0 ? `,\\n${indent} children: [\\n${children.join(',\\n')}\\n${indent} ]` : '',\n `${indent}}`\n ].filter(Boolean).join('');\n }\n\n private static generateElementString(node: RouteNode, indent: string): string {\n if (!node.layout && !node.component) return '';\n\n const props = node.layout\n ? this.generateLayoutProps(node, indent)\n : this.generateComponentProps(node, indent);\n\n return `,\\n${indent} element: React.createElement(RouteWrapper, ${props})`;\n }\n\n private static generateLayoutProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.layout},\n${indent} isLayout: true,\n${indent} loading: ${node.loading || 'undefined'},\n${indent} notFound: ${node.notFound || 'undefined'}\n${indent} }`;\n }\n\n private static generateComponentProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.component}\n${indent} }`;\n }\n\n private static generateErrorString(node: RouteNode, indent: string): string {\n if (!node.error) return '';\n\n return `,\\n${indent} errorElement: React.createElement(ErrorBoundary, {\n${indent} Component: ${node.error}\n${indent} })`;\n }\n}"],"mappings":"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","names":["path","path"]}
1
+ {"version":3,"sources":["../src/plugin.ts","../src/constants.ts","../src/generator/createRoutes.ts","../src/generator/parser/segmentParser.ts","../src/generator/parser/routeTreeBuilder.ts","../src/generator/parser/routeDefinitionGenerator.ts"],"sourcesContent":["// src/plugin.ts\nimport { Plugin } from 'vite';\nimport path from 'path';\nimport fs from 'fs';\nimport { DEFAULT_OPTIONS, RESOLVED_VIRTUAL_ROUTE_MODULE_ID, VIRTUAL_ROUTE_MODULE_ID } from './constants';\nimport {naviloOptions, RouteFile} from './types';\nimport { findRouteFiles } from './generator/createRoutes';\nimport {RouteTreeBuilder} from \"./generator/parser/routeTreeBuilder\";\nimport {RouteDefinitionGenerator} from \"./generator/parser/routeDefinitionGenerator\";\n\nexport function navilo(options: naviloOptions = {}): Plugin {\n const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };\n let root: string;\n const routeTreeBuilder = new RouteTreeBuilder();\n\n return {\n name: 'navilo',\n\n configResolved(config) {\n root = config.root;\n },\n\n configureServer(server) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n server.watcher.add(pagesDir);\n\n const handleFileChange = (file: string) => {\n if (file.startsWith(pagesDir)) {\n const module = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ROUTE_MODULE_ID);\n if (module) {\n server.moduleGraph.invalidateModule(module);\n }\n server.ws.send({ type: 'full-reload' });\n }\n };\n\n server.watcher.on('add', handleFileChange);\n server.watcher.on('unlink', handleFileChange);\n server.watcher.on('change', handleFileChange);\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ROUTE_MODULE_ID) {\n return RESOLVED_VIRTUAL_ROUTE_MODULE_ID;\n }\n },\n\n async load(id) {\n if (id === RESOLVED_VIRTUAL_ROUTE_MODULE_ID) {\n const pagesDir = path.resolve(root, resolvedOptions.pagesDir);\n\n if (!fs.existsSync(pagesDir)) {\n fs.mkdirSync(pagesDir, { recursive: true });\n return `export const router = null;`;\n }\n\n const routes = await findRouteFiles(pagesDir);\n\n if (routes.length === 0) {\n return `export const router = null;`;\n }\n\n const routeTree = routeTreeBuilder.build(routes, {\n strict: true,\n dynamicSegmentTransform: (segment) => `:${segment.toLowerCase()}`\n });\n\n const routeDefinitions = RouteDefinitionGenerator.generate(routeTree);\n\n return routerJSX(routes, routeDefinitions);\n }\n }\n };\n}\n\nexport function routerJSX(routes: RouteFile[], routeDefinitions: string): string {\n const importMap = new Map<string, string>();\n routes.forEach(route => importMap.set(route.filePath, route.componentName));\n\n const imports = Array.from(importMap.entries())\n .map(([filePath, componentName]) => `import ${componentName} from '${filePath}';`)\n .join('\\n');\n\n return `\nimport React, { Suspense } from 'react';\nimport { createBrowserRouter, useParams, Outlet, useRouteError, isRouteErrorResponse } from 'react-router-dom';\n${imports}\n\nfunction ErrorBoundary({ Component }) {\n const error = useRouteError();\n const params = useParams();\n\n if (!Component) {\n return React.createElement('div', { className: 'error-container' },\n React.createElement('div', { className: 'error-content' }, [\n React.createElement('h1', null, \n isRouteErrorResponse(error) ? \\`\\${error.status} - \\${error.statusText}\\` : 'Error'\n ),\n React.createElement('pre', { className: 'error-stack' },\n error instanceof Error ? error.stack : JSON.stringify(error, null, 2)\n ),\n React.createElement('button', {\n onClick: () => window.location.reload()\n }, 'Try again')\n ])\n );\n }\n\n return React.createElement(Component, { error, params });\n}\n\nfunction LoadingBoundary({ Component, children }) {\n if (!Component) {\n return children;\n }\n\n return React.createElement(Suspense, {\n fallback: React.createElement(Component)\n }, children);\n}\n\nfunction RouteWrapper({ Component, isLayout, loading, notFound }) {\n const params = useParams();\n \n if (isLayout) {\n const outlet = React.createElement(Outlet);\n const content = loading ? \n React.createElement(LoadingBoundary, { Component: loading }, outlet) :\n outlet;\n\n return React.createElement(Component, {\n children: content,\n params\n });\n }\n \n return React.createElement(Component, { params });\n}\n\n// Add global error listener\nwindow.addEventListener('error', (event) => {\n console.error('Global error:', event.error);\n});\n\n// Add global promise rejection handler\nwindow.addEventListener('unhandledrejection', (event) => {\n console.error('Unhandled promise rejection:', event.reason);\n});\n\nconst router = createBrowserRouter([\n${routeDefinitions}\n], {\n defaultErrorElement: React.createElement(ErrorBoundary, { Component: ${routes.find(r => r.type === 'not-found')?.componentName || 'null'} })\n});\n\nexport { router };\n`;\n}","export const DEFAULT_OPTIONS = {\n pagesDir: 'src/app',\n typescript: true,\n};\n\nexport const VIRTUAL_ROUTE_MODULE_ID = 'virtual:navilo-routes';\nexport const RESOLVED_VIRTUAL_ROUTE_MODULE_ID = '\\0' + VIRTUAL_ROUTE_MODULE_ID;","import path from 'path';\nimport glob from 'fast-glob';\nimport { RouteFile, RouteType } from '../types';\n\n/** Normalize Windows paths to forward slashes */\nexport function normalizeFilePath(filePath: string): string {\n return filePath.replace(/\\\\/g, '/');\n}\n\n/** Determine the type of a route file */\nexport function getRouteType(filePath: string): RouteType {\n const basename = path.basename(filePath);\n const fileTypes: Record<string, RouteType> = {\n 'layout.jsx': 'layout',\n 'layout.tsx': 'layout',\n 'page.jsx': 'page',\n 'page.tsx': 'page',\n 'error.jsx': 'error',\n 'error.tsx': 'error',\n 'loading.jsx': 'loading',\n 'loading.tsx': 'loading',\n 'not-found.jsx': 'not-found',\n 'not-found.tsx': 'not-found'\n };\n return fileTypes[basename] || 'page';\n}\n\n/** Generate a PascalCase component name based on folder structure */\nexport function getComponentName(filePath: string, pagesDir: string): string {\n const segments = normalizeFilePath(path.relative(pagesDir, filePath)).split('/');\n const fileNameWithExt = segments.pop()!;\n const fileName = path.basename(fileNameWithExt, path.extname(fileNameWithExt));\n\n const relevantSegments = segments.map(segment => {\n if (segment.startsWith('[') && segment.endsWith(']')) {\n return segment.slice(1, -1)\n .replace(/^\\.\\.\\./, 'CatchAll')\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n }\n return segment\n .split(/[^a-zA-Z0-9]/)\n .map(p => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n });\n\n const typeSuffix = {\n page: 'Page',\n layout: 'Layout',\n error: 'Error',\n loading: 'Loading',\n 'not-found': 'NotFound'\n }[fileName] || 'Component';\n\n return relevantSegments.length === 0 ? `Root${typeSuffix}` : `${relevantSegments.join('')}${typeSuffix}`;\n}\n\n/** Extract segments from file path for building route tree */\nexport function getPathSegments(filePath: string, pagesDir: string): string[] {\n const relativePath = normalizeFilePath(path.relative(pagesDir, filePath));\n const segments = relativePath.split('/');\n const fileName = segments.pop()!;\n\n const filteredSegments = segments.filter(seg => !(seg.startsWith('(') && seg.endsWith(')')));\n\n if (/^page\\.(jsx|tsx)$/.test(fileName)) {\n filteredSegments.push('');\n }\n\n return filteredSegments;\n}\n\n/** Find all route files in the pages directory */\nexport async function findRouteFiles(pagesDir: string): Promise<RouteFile[]> {\n const files = await glob(['**/*.{jsx,tsx}'], {\n cwd: pagesDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.*/**', '**/_*/**'],\n });\n\n const validFiles = files.filter(file => {\n const base = path.basename(file);\n return /^(layout|page|error|loading|not-found)\\.(jsx|tsx)$/.test(base);\n });\n\n return validFiles.map(file => {\n const type = getRouteType(file);\n return {\n type,\n path: '/' + normalizeFilePath(path.relative(pagesDir, path.dirname(file))),\n filePath: normalizeFilePath(file),\n componentName: getComponentName(file, pagesDir),\n segments: getPathSegments(file, pagesDir),\n };\n });\n}\n","import {ParserOptions} from \"../../types\";\n\nexport class SegmentParser {\n private static readonly SEGMENT_PATTERNS = {\n OPTIONAL_CATCH_ALL: /^\\[\\[\\.{3}(.+)\\]\\]$/,\n CATCH_ALL: /^\\[\\.{3}(.+)\\]$/,\n DYNAMIC: /^\\[(.+)\\]$/,\n GROUP: /^\\((.+)\\)$/\n };\n\n static normalize(segment: string, options?: ParserOptions): string | null {\n if (this.isGroupSegment(segment)) return null;\n\n if (segment.includes('/')) {\n return segment.split('/')\n .map(seg => this.normalizeSegment(seg, options))\n .filter(Boolean)\n .join('/');\n }\n\n return this.normalizeSegment(segment, options);\n }\n\n private static normalizeSegment(segment: string, options?: ParserOptions): string | null {\n const transform = options?.dynamicSegmentTransform || this.defaultTransform;\n\n if (this.isOptionalCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL)![1];\n return transform(`${name}*?`);\n }\n\n if (this.isCatchAll(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.CATCH_ALL)![1];\n return transform(`${name}*`);\n }\n\n if (this.isDynamicSegment(segment)) {\n const name = segment.match(this.SEGMENT_PATTERNS.DYNAMIC)![1];\n return transform(name);\n }\n\n return segment;\n }\n\n private static defaultTransform(name: string): string {\n return `:${name}`;\n }\n\n private static isGroupSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.GROUP.test(segment);\n }\n\n private static isOptionalCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.OPTIONAL_CATCH_ALL.test(segment);\n }\n\n private static isCatchAll(segment: string): boolean {\n return this.SEGMENT_PATTERNS.CATCH_ALL.test(segment);\n }\n\n private static isDynamicSegment(segment: string): boolean {\n return this.SEGMENT_PATTERNS.DYNAMIC.test(segment);\n }\n}","import {SegmentParser} from './segmentParser';\nimport {ParserOptions, RouteFile, RouteNode} from \"../../types\";\n\nexport class RouteTreeBuilder {\n private readonly typeSetters: Record<string, (node: RouteNode, route: RouteFile) => void>;\n\n constructor() {\n this.typeSetters = {\n layout: (node, route) => {\n node.layout = route.componentName;\n },\n error: (node, route) => {\n node.error = route.componentName;\n },\n loading: (node, route) => {\n node.loading = route.componentName;\n },\n 'not-found': (node, route) => {\n node.notFound = route.componentName;\n },\n page: this.handlePageType.bind(this)\n };\n }\n\n build(routes: RouteFile[], options?: ParserOptions): RouteNode {\n const root: RouteNode = {\n segment: '',\n path: '/',\n fullPath: '/',\n children: new Map(),\n metadata: options?.metadata\n };\n\n const sortedRoutes = this.sortRoutes(routes);\n sortedRoutes.forEach(route => {\n this.processRoute(root, route, options);\n });\n\n return root;\n }\n\n private sortRoutes(routes: RouteFile[]): RouteFile[] {\n return [...routes].sort((a, b) =>\n a.type === 'layout' && b.type !== 'layout' ? -1 :\n a.type !== 'layout' && b.type === 'layout' ? 1 : 0\n );\n }\n\n private processRoute(root: RouteNode, route: RouteFile, options?: ParserOptions): void {\n const segments = route.segments.map(seg => String(seg));\n\n if (segments.length === 0) {\n this.applyTypeHandler(root, route);\n if (route.type === 'page') root.isIndex = true;\n return;\n }\n\n let current = root;\n let currentPath = '';\n\n segments.forEach((seg, idx) => {\n const isLast = idx === segments.length - 1;\n const key = SegmentParser.normalize(seg, options);\n\n if (key === null) return;\n\n currentPath = this.buildFullPath(currentPath, key);\n\n if (!current.children.has(key)) {\n current.children.set(key, {\n segment: key,\n path: key,\n fullPath: currentPath,\n children: new Map(),\n metadata: options?.metadata\n });\n }\n\n current = current.children.get(key)!;\n\n if (isLast) this.applyTypeHandler(current, route);\n });\n }\n\n private buildFullPath(currentPath: string, key: string): string {\n if (currentPath === '' || currentPath === '/') {\n return key === '' ? '/' : `/${key}`;\n }\n return `${currentPath}/${key}`;\n }\n\n private applyTypeHandler(node: RouteNode, route: RouteFile): void {\n const handler = this.typeSetters[route.type];\n if (handler) handler(node, route);\n }\n\n private handlePageType(node: RouteNode, route: RouteFile): void {\n const lastSegment = route.segments[route.segments.length - 1];\n const isDynamic = lastSegment?.startsWith('[');\n\n if (isDynamic || lastSegment === '') {\n node.component = route.componentName;\n node.isIndex = false;\n } else {\n node.indexPage = route.componentName;\n }\n }\n}","import { RouteNode } from \"../../types\";\n\nexport class RouteDefinitionGenerator {\n static generate(node: RouteNode, indent = ' '): string {\n const childNodes = Array.from(node.children.values());\n const children: string[] = [];\n\n if (node.indexPage) {\n children.push(this.generateIndexRoute(node, indent));\n }\n\n children.push(...childNodes.map(child =>\n this.generate(child, indent + ' ')\n ));\n\n return this.generateRouteObject(node, children, indent);\n }\n\n private static generateIndexRoute(node: RouteNode, indent: string): string {\n return `${indent} {\n${indent} index: true,\n${indent} element: React.createElement(RouteWrapper, {\n${indent} Component: ${node.indexPage}\n${indent} })\n${indent} }`;\n }\n\n private static generateRouteObject(node: RouteNode, children: string[], indent: string): string {\n const pathStr = node.fullPath;\n const elementStr = this.generateElementString(node, indent);\n const errorStr = this.generateErrorString(node, indent);\n\n return [\n `${indent}{`,\n `${indent} path: '${pathStr}'${elementStr}${errorStr}`,\n children.length > 0 ? `,\\n${indent} children: [\\n${children.join(',\\n')}\\n${indent} ]` : '',\n `${indent}}`\n ].filter(Boolean).join('');\n }\n\n private static generateElementString(node: RouteNode, indent: string): string {\n if (!node.layout && !node.component) return '';\n\n const props = node.layout\n ? this.generateLayoutProps(node, indent)\n : this.generateComponentProps(node, indent);\n\n return `,\\n${indent} element: React.createElement(RouteWrapper, ${props})`;\n }\n\n private static generateLayoutProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.layout},\n${indent} isLayout: true,\n${indent} loading: ${node.loading || 'undefined'},\n${indent} notFound: ${node.notFound || 'undefined'}\n${indent} }`;\n }\n\n private static generateComponentProps(node: RouteNode, indent: string): string {\n return `{\n${indent} Component: ${node.component}\n${indent} }`;\n }\n\n private static generateErrorString(node: RouteNode, indent: string): string {\n if (!node.error) return '';\n\n return `,\\n${indent} errorElement: React.createElement(ErrorBoundary, {\n${indent} Component: ${node.error}\n${indent} })`;\n }\n}"],"mappings":"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","names":["path","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "navilo",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "description": "File-based routing plugin for Vite + React applications",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",