1- import { ResourceProtocol } from "../resources/BaseResource.js" ;
2- import { join , dirname } from "path" ;
3- import { promises as fs } from "fs" ;
4- import { logger } from "../core/Logger.js" ;
1+ import { ResourceProtocol } from '../resources/BaseResource.js' ;
2+ import { join , dirname } from 'path' ;
3+ import { promises as fs } from 'fs' ;
4+ import { logger } from '../core/Logger.js' ;
5+ import { discoverFilesRecursively , hasValidFiles } from '../utils/fileDiscovery.js' ;
56
67export class ResourceLoader {
78 private readonly RESOURCES_DIR : string ;
8- private readonly EXCLUDED_FILES = [
9- "BaseResource.js" ,
10- "*.test.js" ,
11- "*.spec.js" ,
12- ] ;
9+ private readonly EXCLUDED_FILES = [ 'BaseResource.js' , '*.test.js' , '*.spec.js' ] ;
1310
1411 constructor ( basePath ?: string ) {
15- const mainModulePath = basePath || process . argv [ 1 ] ;
16- this . RESOURCES_DIR = join ( dirname ( mainModulePath ) , "resources" ) ;
17- logger . debug (
18- `Initialized ResourceLoader with directory: ${ this . RESOURCES_DIR } `
19- ) ;
12+ if ( basePath ) {
13+ // If basePath is provided, it should be the directory containing the resources folder
14+ this . RESOURCES_DIR = join ( basePath , 'resources' ) ;
15+ } else {
16+ // For backwards compatibility, use the old behavior with process.argv[1]
17+ const mainModulePath = process . argv [ 1 ] ;
18+ this . RESOURCES_DIR = join ( dirname ( mainModulePath ) , 'resources' ) ;
19+ }
20+ logger . debug ( `Initialized ResourceLoader with directory: ${ this . RESOURCES_DIR } ` ) ;
2021 }
2122
2223 async hasResources ( ) : Promise < boolean > {
2324 try {
24- const stats = await fs . stat ( this . RESOURCES_DIR ) ;
25- if ( ! stats . isDirectory ( ) ) {
26- logger . debug ( "Resources path exists but is not a directory" ) ;
27- return false ;
28- }
29-
30- const files = await fs . readdir ( this . RESOURCES_DIR ) ;
31- const hasValidFiles = files . some ( ( file ) => this . isResourceFile ( file ) ) ;
32- logger . debug ( `Resources directory has valid files: ${ hasValidFiles } ` ) ;
33- return hasValidFiles ;
25+ return await hasValidFiles ( this . RESOURCES_DIR , {
26+ extensions : [ '.js' ] ,
27+ excludePatterns : this . EXCLUDED_FILES ,
28+ } ) ;
3429 } catch ( error ) {
3530 logger . debug ( `No resources directory found: ${ ( error as Error ) . message } ` ) ;
3631 return false ;
3732 }
3833 }
3934
40- private isResourceFile ( file : string ) : boolean {
41- if ( ! file . endsWith ( ".js" ) ) return false ;
42- const isExcluded = this . EXCLUDED_FILES . some ( ( pattern ) => {
43- if ( pattern . includes ( "*" ) ) {
44- const regex = new RegExp ( pattern . replace ( "*" , ".*" ) ) ;
45- return regex . test ( file ) ;
46- }
47- return file === pattern ;
48- } ) ;
49-
50- logger . debug (
51- `Checking file ${ file } : ${ isExcluded ? "excluded" : "included" } `
52- ) ;
53- return ! isExcluded ;
54- }
55-
5635 private validateResource ( resource : any ) : resource is ResourceProtocol {
5736 const isValid = Boolean (
5837 resource &&
59- typeof resource . uri === " string" &&
60- typeof resource . name === " string" &&
38+ typeof resource . uri === ' string' &&
39+ typeof resource . name === ' string' &&
6140 resource . resourceDefinition &&
62- typeof resource . read === " function"
41+ typeof resource . read === ' function'
6342 ) ;
6443
6544 if ( isValid ) {
@@ -75,29 +54,21 @@ export class ResourceLoader {
7554 try {
7655 logger . debug ( `Attempting to load resources from: ${ this . RESOURCES_DIR } ` ) ;
7756
78- let stats ;
79- try {
80- stats = await fs . stat ( this . RESOURCES_DIR ) ;
81- } catch ( error ) {
82- logger . debug ( `No resources directory found: ${ ( error as Error ) . message } ` ) ;
83- return [ ] ;
84- }
57+ const resourceFiles = await discoverFilesRecursively ( this . RESOURCES_DIR , {
58+ extensions : [ '.js' ] ,
59+ excludePatterns : this . EXCLUDED_FILES ,
60+ } ) ;
8561
86- if ( ! stats . isDirectory ( ) ) {
87- logger . error ( `Path is not a directory: ${ this . RESOURCES_DIR } ` ) ;
62+ if ( resourceFiles . length === 0 ) {
63+ logger . debug ( 'No resource files found' ) ;
8864 return [ ] ;
8965 }
9066
91- const files = await fs . readdir ( this . RESOURCES_DIR ) ;
92- logger . debug ( `Found files in directory: ${ files . join ( ", " ) } ` ) ;
67+ logger . debug ( `Found resource files: ${ resourceFiles . join ( ', ' ) } ` ) ;
9368
9469 const resources : ResourceProtocol [ ] = [ ] ;
9570
96- for ( const file of files ) {
97- if ( ! this . isResourceFile ( file ) ) {
98- continue ;
99- }
100-
71+ for ( const file of resourceFiles ) {
10172 try {
10273 const fullPath = join ( this . RESOURCES_DIR , file ) ;
10374 logger . debug ( `Attempting to load resource from: ${ fullPath } ` ) ;
@@ -120,9 +91,7 @@ export class ResourceLoader {
12091 }
12192
12293 logger . debug (
123- `Successfully loaded ${ resources . length } resources: ${ resources
124- . map ( ( r ) => r . name )
125- . join ( ", " ) } `
94+ `Successfully loaded ${ resources . length } resources: ${ resources . map ( ( r ) => r . name ) . join ( ', ' ) } `
12695 ) ;
12796 return resources ;
12897 } catch ( error ) {
0 commit comments