@@ -28,6 +28,7 @@ RouteConfiguration buildRouteConfiguration(Directory directory) {
2828 if (globalMiddleware != null ) globalMiddleware
2929 ];
3030 final routes = < RouteFile > [];
31+ final rogueRoutes = < RouteFile > [];
3132 final directories = _getRouteDirectories (
3233 directory: routesDirectory,
3334 routesDirectory: routesDirectory,
@@ -40,13 +41,15 @@ RouteConfiguration buildRouteConfiguration(Directory directory) {
4041 endpoints[endpoint]! .add (file);
4142 }
4243 },
44+ onRogueRoute: rogueRoutes.add,
4345 );
4446 final publicDirectory = Directory (path.join (directory.path, 'public' ));
4547 return RouteConfiguration (
4648 globalMiddleware: globalMiddleware,
4749 middleware: middleware,
4850 directories: directories,
4951 routes: routes,
52+ rogueRoutes: rogueRoutes,
5053 endpoints: endpoints,
5154 serveStaticFiles: publicDirectory.existsSync (),
5255 );
@@ -58,6 +61,7 @@ List<RouteDirectory> _getRouteDirectories({
5861 required void Function (RouteFile route) onRoute,
5962 required void Function (MiddlewareFile route) onMiddleware,
6063 required void Function (String endpoint, RouteFile file) onEndpoint,
64+ required void Function (RouteFile route) onRogueRoute,
6165}) {
6266 final directories = < RouteDirectory > [];
6367 final entities = directory.listSync ().sorted ();
@@ -87,11 +91,13 @@ List<RouteDirectory> _getRouteDirectories({
8791 directory: directory,
8892 routesDirectory: routesDirectory,
8993 onRoute: onRoute,
94+ onRogueRoute: onRogueRoute,
9095 ),
9196 ..._getRouteFilesForDynamicDirectories (
9297 directory: directory,
9398 routesDirectory: routesDirectory,
9499 onRoute: onRoute,
100+ onRogueRoute: onRogueRoute,
95101 ),
96102 ];
97103
@@ -123,6 +129,7 @@ List<RouteDirectory> _getRouteDirectories({
123129 onRoute: onRoute,
124130 onMiddleware: onMiddleware,
125131 onEndpoint: onEndpoint,
132+ onRogueRoute: onRogueRoute,
126133 ),
127134 );
128135 }
@@ -135,6 +142,7 @@ List<RouteFile> _getRouteFilesForDynamicDirectories({
135142 required Directory directory,
136143 required Directory routesDirectory,
137144 required void Function (RouteFile route) onRoute,
145+ required void Function (RouteFile route) onRogueRoute,
138146 String prefix = '' ,
139147}) {
140148 final files = < RouteFile > [];
@@ -149,12 +157,14 @@ List<RouteFile> _getRouteFilesForDynamicDirectories({
149157 directory: dynamicDirectory,
150158 routesDirectory: routesDirectory,
151159 onRoute: onRoute,
160+ onRogueRoute: onRogueRoute,
152161 prefix: newPrefix,
153162 );
154163 final dynamicSubset = _getRouteFilesForDynamicDirectories (
155164 directory: dynamicDirectory,
156165 routesDirectory: routesDirectory,
157166 onRoute: onRoute,
167+ onRogueRoute: onRogueRoute,
158168 prefix: newPrefix,
159169 );
160170 files.addAll ([...subset, ...dynamicSubset]);
@@ -166,6 +176,7 @@ List<RouteFile> _getRouteFiles({
166176 required Directory directory,
167177 required Directory routesDirectory,
168178 required void Function (RouteFile route) onRoute,
179+ required void Function (RouteFile route) onRogueRoute,
169180 String prefix = '' ,
170181}) {
171182 final files = < RouteFile > [];
@@ -175,6 +186,10 @@ List<RouteFile> _getRouteFiles({
175186 ? directorySegment
176187 : '/$directorySegment ' ;
177188 final entities = directory.listSync ().sorted ();
189+ final subDirectories = entities
190+ .whereType <Directory >()
191+ .map ((directory) => path.basename (directory.path))
192+ .toSet ();
178193 entities.where ((e) => e.isRoute).cast <File >().forEach ((entity) {
179194 final filePath = path
180195 .relative (entity.path, from: routesDirectory.path)
@@ -209,6 +224,10 @@ List<RouteFile> _getRouteFiles({
209224 );
210225 onRoute (route);
211226 files.add (route);
227+
228+ if (subDirectories.contains (path.basenameWithoutExtension (filePath))) {
229+ onRogueRoute (route);
230+ }
212231 });
213232 return files;
214233}
@@ -261,6 +280,7 @@ class RouteConfiguration {
261280 required this .directories,
262281 required this .routes,
263282 required this .endpoints,
283+ required this .rogueRoutes,
264284 this .serveStaticFiles = false ,
265285 });
266286
@@ -283,6 +303,34 @@ class RouteConfiguration {
283303
284304 /// A map of all endpoint paths to resolved route files.
285305 final Map <String , List <RouteFile >> endpoints;
306+
307+ /// List of all rogue routes.
308+ ///
309+ /// A route is considered rogue when it is defined outside
310+ /// of an existing subdirectory with the same name.
311+ ///
312+ /// For example:
313+ ///
314+ /// ```
315+ /// ├── routes
316+ /// │ ├── foo
317+ /// │ │ └── example.dart
318+ /// │ ├── foo.dart
319+ /// ```
320+ ///
321+ /// In the above scenario, `foo.dart` is rogue because it is defined
322+ /// outside of the existing `foo` directory.
323+ ///
324+ /// Instead, `foo.dart` should be renamed to `index.dart` and placed within
325+ /// the `foo` directory like:
326+ ///
327+ /// ```
328+ /// ├── routes
329+ /// │ ├── foo
330+ /// │ │ ├── example.dart
331+ /// │ │ └── index.dart
332+ /// ```
333+ final List <RouteFile > rogueRoutes;
286334}
287335
288336/// {@template route_directory}
@@ -336,7 +384,7 @@ class RouteDirectory {
336384}
337385
338386/// {@template route_file}
339- /// A class containing metadata regarding a route directory .
387+ /// A class containing metadata regarding a route file .
340388/// {@endtemplate}
341389class RouteFile {
342390 /// {@macro route_file}
@@ -346,7 +394,7 @@ class RouteFile {
346394 required this .route,
347395 });
348396
349- /// The alias for the current directory .
397+ /// The alias for the current file .
350398 final String name;
351399
352400 /// The import path for the current instance.
0 commit comments