1
- import * as nodeUrl from "node:url" ;
2
1
import * as nodePath from "node:path" ;
3
2
import * as nodeFsPromises from "node:fs/promises" ;
4
3
import * as nodeUtilTypes from "node:util/types" ;
5
- import { getModules } from "file-folder-loader" ;
4
+ import { getModules , loadModules } from "file-folder-loader" ;
6
5
import type { EventEmitter } from "node:events" ;
7
6
import type { PathLike } from "node:fs" ;
8
- import type {
9
- EventExecute ,
10
- EventHandlerModuleExport ,
11
- EventHandlerModuleNamespace ,
12
- EventHandlerKeys ,
13
- LoadEventHandlersOptions ,
14
- BindEventListenerOverride ,
15
- } from "./types.js" ;
7
+ import type { ProcessMode , ExportType , EventExecute , EventHandlerModuleExport , EventHandlerKeys , LoadEventHandlersOptions , BindEventListenerOverride } from "./types.js" ;
16
8
17
- const DEFAULT_EXPORT_NAME = "default" ;
18
9
const EVENT_EMITTER_ADD_LISTENER_METHOD_NAMES = [ "on" , "once" , "addListener" , "prependListener" , "prependOnceListener" ] ;
19
10
20
11
const DEFAULT_EVENT_HANDLER_KEY_NAMES = {
@@ -23,16 +14,16 @@ const DEFAULT_EVENT_HANDLER_KEY_NAMES = {
23
14
isPrepend : "isPrepend" ,
24
15
execute : "execute" ,
25
16
} ;
26
- const DEFAULT_IMPORT_MODE = "concurrent" ;
17
+ const DEFAULT_PROCESS_MODE = "concurrent" ;
27
18
const DEFAULT_EXPORT_TYPE = "default" ;
28
19
const DEFAULT_NAMED_EXPORT = "eventHandler" ;
29
20
const DEFAULT_IMPORT_MODES = [ "concurrent" , "sequential" ] ;
30
21
const DEFAULT_EXPORT_TYPES = [ "default" , "named" , "all" ] ;
31
22
const DEFAULT_LOAD_EVENT_HANDLERS_OPTIONS = {
32
- importMode : DEFAULT_IMPORT_MODE ,
23
+ processMode : DEFAULT_PROCESS_MODE ,
33
24
exportType : DEFAULT_EXPORT_TYPE ,
34
25
listenerPrependedArgs : [ ] ,
35
- preferredNamedExport : DEFAULT_NAMED_EXPORT ,
26
+ preferredExportName : DEFAULT_NAMED_EXPORT ,
36
27
preferredEventHandlerKeys : { } ,
37
28
isRecursive : false ,
38
29
} ;
@@ -132,44 +123,6 @@ function bindEventListener(
132
123
eventEmitterLike . on ( nameValue , listener ) ;
133
124
}
134
125
135
- async function importModule ( fileUrlHref : string , exportType : string , preferredExportName : string ) {
136
- const isNamedExportType = exportType === "named" ;
137
- const moduleNamespace : EventHandlerModuleNamespace = await import ( fileUrlHref ) ;
138
- if ( exportType === "all" ) {
139
- const moduleExports : EventHandlerModuleExport [ ] = [ ] ;
140
- for ( const exportName in moduleNamespace ) {
141
- const moduleExport = moduleNamespace [ exportName ] ;
142
- if ( ! moduleExport || ! Object . prototype . hasOwnProperty . call ( moduleNamespace , exportName ) ) {
143
- console . error ( `Invalid module export. Must be a default or named export. Unable to verify export '${ exportName } '. Module: ${ fileUrlHref } ` ) ;
144
- continue ;
145
- }
146
- moduleExports . push ( moduleExport ) ;
147
- }
148
- return moduleExports ;
149
- }
150
- if ( isNamedExportType && preferredExportName === "*" ) {
151
- const moduleExports : EventHandlerModuleExport [ ] = [ ] ;
152
- for ( const exportName in moduleNamespace ) {
153
- const moduleExport = moduleNamespace [ exportName ] ;
154
- if ( ! moduleExport || ! Object . prototype . hasOwnProperty . call ( moduleNamespace , exportName ) || exportName === DEFAULT_EXPORT_NAME ) {
155
- console . error ( `Invalid module export. Must be a named export. Unable to verify named export '${ exportName } '. Module: ${ fileUrlHref } ` ) ;
156
- continue ;
157
- }
158
- moduleExports . push ( moduleExport ) ;
159
- }
160
- return moduleExports ;
161
- }
162
- const exportName = isNamedExportType ? preferredExportName : DEFAULT_EXPORT_NAME ;
163
- const moduleExport = moduleNamespace [ exportName ] ;
164
- if ( ! moduleExport || ! Object . prototype . hasOwnProperty . call ( moduleNamespace , exportName ) ) {
165
- const errorMessage = isNamedExportType
166
- ? `Must be a named export called '${ preferredExportName } '. ${ exportName === DEFAULT_EXPORT_NAME ? "Unable to verify named export" : "Unable to verify preferred export name" } '${ exportName } '.`
167
- : `Must be a default export. Unable to verify default export '${ exportName } '` ;
168
- throw new Error ( `Invalid module export. ${ errorMessage } . Module: ${ fileUrlHref } ` ) ;
169
- }
170
- return [ moduleExport ] ;
171
- }
172
-
173
126
async function loadEventHandlers (
174
127
dirPath : string ,
175
128
eventEmitterLike : EventEmitter ,
@@ -188,10 +141,10 @@ async function loadEventHandlers(
188
141
throw new Error ( `Invalid options: '${ options } '. Must be a an object.` ) ;
189
142
}
190
143
const eventHandlerOptions = { ...DEFAULT_LOAD_EVENT_HANDLERS_OPTIONS , ...( options || { } ) } ;
191
- const importMode = eventHandlerOptions . importMode ;
144
+ const processMode = eventHandlerOptions . processMode ;
192
145
const exportType = eventHandlerOptions . exportType ;
193
146
const listenerPrependedArgs = eventHandlerOptions . listenerPrependedArgs ;
194
- const preferredNamedExport = eventHandlerOptions . preferredNamedExport ;
147
+ const preferredExportName = eventHandlerOptions . preferredExportName ;
195
148
const isRecursive = eventHandlerOptions . isRecursive ;
196
149
const preferredEventHandlerKeys = { ...DEFAULT_EVENT_HANDLER_KEY_NAMES , ...( eventHandlerOptions . preferredEventHandlerKeys || { } ) } ;
197
150
const { name : nameKeyName , isOnce : isOnceKeyName , isPrepend : isPrependKeyName , execute : executeKeyName } = preferredEventHandlerKeys ;
@@ -208,46 +161,34 @@ async function loadEventHandlers(
208
161
if ( typeof executeKeyName !== "string" || executeKeyName . trim ( ) === "" ) {
209
162
throw new Error ( `Invalid preferredEventHandlerKeys execute: '${ executeKeyName } '. Must be a non-empty string.` ) ;
210
163
}
211
- if ( ! DEFAULT_IMPORT_MODES . includes ( importMode ) ) {
212
- throw new Error ( `Invalid import mode: '${ importMode } '. Must be one of string: ${ DEFAULT_IMPORT_MODES . join ( ", " ) } ` ) ;
164
+ if ( ! DEFAULT_IMPORT_MODES . includes ( processMode ) ) {
165
+ throw new Error ( `Invalid process mode: '${ processMode } '. Must be one of string: ${ DEFAULT_IMPORT_MODES . join ( ", " ) } ` ) ;
213
166
}
214
167
if ( ! DEFAULT_EXPORT_TYPES . includes ( exportType ) ) {
215
168
throw new Error ( `Invalid export type: '${ exportType } '. Must be one of string: ${ DEFAULT_EXPORT_TYPES . join ( ", " ) } ` ) ;
216
169
}
217
- if ( typeof preferredNamedExport !== "string" || preferredNamedExport . trim ( ) === "" ) {
218
- throw new Error ( `Invalid preferred named export: '${ preferredNamedExport } '. Must be a non-empty string.` ) ;
170
+ if ( typeof preferredExportName !== "string" || preferredExportName . trim ( ) === "" ) {
171
+ throw new Error ( `Invalid preferred export name : '${ preferredExportName } '. Must be a non-empty string.` ) ;
219
172
}
220
173
if ( typeof isRecursive !== "boolean" ) {
221
174
throw new Error ( `Invalid isRecursive: '${ isRecursive } '. Must be a boolean.` ) ;
222
175
}
223
- const filePaths = await getModules ( absolutePath , { isRecursive : isRecursive , processMode : importMode } ) ;
224
- async function loadEventHandler ( filePath : string ) {
225
- const fileUrlHref = nodeUrl . pathToFileURL ( filePath ) . href ;
226
- /**
227
- * Some type casts were necessary here because TypeScript
228
- * didn't consider the guard clauses outside this async function declaration
229
- * - xaya
230
- */
231
- const moduleExports = await importModule ( fileUrlHref , exportType as string , preferredNamedExport as string ) ;
232
- for ( const moduleExport of moduleExports ) {
176
+ const filePaths = await getModules ( absolutePath , { isRecursive : isRecursive , processMode : processMode } ) ;
177
+ await loadModules (
178
+ filePaths ,
179
+ async function ( moduleExport , fileUrlHref ) {
233
180
if ( typeof bindEventListenerOverride !== "function" ) {
234
- bindEventListener ( eventEmitterLike , moduleExport , preferredEventHandlerKeys , listenerPrependedArgs as unknown [ ] , fileUrlHref ) ;
235
- continue ;
181
+ bindEventListener ( eventEmitterLike , moduleExport as EventHandlerModuleExport , preferredEventHandlerKeys , listenerPrependedArgs as unknown [ ] , fileUrlHref ) ;
182
+ return ;
236
183
}
237
184
if ( nodeUtilTypes . isAsyncFunction ( bindEventListenerOverride ) ) {
238
- await bindEventListenerOverride ( eventEmitterLike , moduleExport , fileUrlHref , listenerPrependedArgs as unknown [ ] ) ;
239
- continue ;
185
+ await bindEventListenerOverride ( eventEmitterLike , moduleExport as EventHandlerModuleExport , fileUrlHref , listenerPrependedArgs as unknown [ ] ) ;
186
+ return ;
240
187
}
241
- bindEventListenerOverride ( eventEmitterLike , moduleExport , fileUrlHref , listenerPrependedArgs as unknown [ ] ) ;
242
- }
243
- }
244
- if ( importMode === "concurrent" ) {
245
- await Promise . all ( filePaths . map ( loadEventHandler ) ) ;
246
- return true ;
247
- }
248
- for ( const filePath of filePaths ) {
249
- await loadEventHandler ( filePath ) ;
250
- }
188
+ bindEventListenerOverride ( eventEmitterLike , moduleExport as EventHandlerModuleExport , fileUrlHref , listenerPrependedArgs as unknown [ ] ) ;
189
+ } ,
190
+ { exportType : exportType as ExportType , preferredExportName : preferredExportName , processMode : processMode as ProcessMode } ,
191
+ ) ;
251
192
return true ;
252
193
}
253
194
0 commit comments