@@ -24,7 +24,10 @@ import { color } from "../../color";
2424import { memoize } from "../decorators" ;
2525
2626class Hook implements IHook {
27- constructor ( public name : string , public fullPath : string ) { }
27+ constructor (
28+ public name : string ,
29+ public fullPath : string ,
30+ ) { }
2831}
2932
3033export class HooksService implements IHooksService {
@@ -45,7 +48,7 @@ export class HooksService implements IHooksService {
4548 private $projectHelper : IProjectHelper ,
4649 private $options : IOptions ,
4750 private $performanceService : IPerformanceService ,
48- private $projectConfigService : IProjectConfigService
51+ private $projectConfigService : IProjectConfigService ,
4952 ) { }
5053
5154 public get hookArgsName ( ) : string {
@@ -69,12 +72,12 @@ export class HooksService implements IHooksService {
6972
7073 if ( projectDir ) {
7174 this . hooksDirectories . push (
72- path . join ( projectDir , HooksService . HOOKS_DIRECTORY_NAME )
75+ path . join ( projectDir , HooksService . HOOKS_DIRECTORY_NAME ) ,
7376 ) ;
7477 }
7578
7679 this . $logger . trace (
77- "Hooks directories: " + util . inspect ( this . hooksDirectories )
80+ "Hooks directories: " + util . inspect ( this . hooksDirectories ) ,
7881 ) ;
7982
8083 const customHooks = this . $projectConfigService . getValue ( "hooks" , [ ] ) ;
@@ -91,7 +94,7 @@ export class HooksService implements IHooksService {
9194
9295 public executeBeforeHooks (
9396 commandName : string ,
94- hookArguments ?: IDictionary < any >
97+ hookArguments ?: IDictionary < any > ,
9598 ) : Promise < void > {
9699 const beforeHookName = `before-${ HooksService . formatHookName ( commandName ) } ` ;
97100 const traceMessage = `BeforeHookName for command ${ commandName } is ${ beforeHookName } ` ;
@@ -100,7 +103,7 @@ export class HooksService implements IHooksService {
100103
101104 public executeAfterHooks (
102105 commandName : string ,
103- hookArguments ?: IDictionary < any >
106+ hookArguments ?: IDictionary < any > ,
104107 ) : Promise < void > {
105108 const afterHookName = `after-${ HooksService . formatHookName ( commandName ) } ` ;
106109 const traceMessage = `AfterHookName for command ${ commandName } is ${ afterHookName } ` ;
@@ -110,7 +113,7 @@ export class HooksService implements IHooksService {
110113 private async executeHooks (
111114 hookName : string ,
112115 traceMessage : string ,
113- hookArguments ?: IDictionary < any >
116+ hookArguments ?: IDictionary < any > ,
114117 ) : Promise < any > {
115118 if ( this . $config . DISABLE_HOOKS || ! this . $options . hooks ) {
116119 return ;
@@ -135,8 +138,8 @@ export class HooksService implements IHooksService {
135138 await this . executeHooksInDirectory (
136139 hooksDirectory ,
137140 hookName ,
138- hookArguments
139- )
141+ hookArguments ,
142+ ) ,
140143 ) ;
141144 }
142145
@@ -148,8 +151,8 @@ export class HooksService implements IHooksService {
148151 this . $projectHelper . projectDir ,
149152 hookName ,
150153 hook ,
151- hookArguments
152- )
154+ hookArguments ,
155+ ) ,
153156 ) ;
154157 }
155158 } catch ( err ) {
@@ -160,11 +163,16 @@ export class HooksService implements IHooksService {
160163 return _ . flatten ( results ) ;
161164 }
162165
166+ private isESModule ( hook : IHook ) : boolean {
167+ const ext = path . extname ( hook . fullPath ) . toLowerCase ( ) ;
168+ return ext === ".mjs" ;
169+ }
170+
163171 private async executeHook (
164172 directoryPath : string ,
165173 hookName : string ,
166174 hook : IHook ,
167- hookArguments ?: IDictionary < any >
175+ hookArguments ?: IDictionary < any > ,
168176 ) : Promise < any > {
169177 hookArguments = hookArguments || { } ;
170178
@@ -173,15 +181,18 @@ export class HooksService implements IHooksService {
173181 const relativePath = path . relative ( directoryPath , hook . fullPath ) ;
174182 const trackId = relativePath . replace (
175183 new RegExp ( "\\" + path . sep , "g" ) ,
176- AnalyticsEventLabelDelimiter
184+ AnalyticsEventLabelDelimiter ,
177185 ) ;
186+ const isESM = this . isESModule ( hook ) ;
178187 let command = this . getSheBangInterpreter ( hook ) ;
179188 let inProc = false ;
180189 if ( ! command ) {
181190 command = hook . fullPath ;
182191 if ( [ ".mjs" , ".js" ] . includes ( path . extname ( hook . fullPath ) . toLowerCase ( ) ) ) {
183192 command = process . argv [ 0 ] ;
184- inProc = this . shouldExecuteInProcess ( this . $fs . readText ( hook . fullPath ) ) ;
193+ inProc = isESM
194+ ? true
195+ : this . shouldExecuteInProcess ( this . $fs . readText ( hook . fullPath ) ) ;
185196 }
186197 }
187198
@@ -190,24 +201,30 @@ export class HooksService implements IHooksService {
190201 this . $logger . trace (
191202 "Executing %s hook at location %s in-process" ,
192203 hookName ,
193- hook . fullPath
204+ hook . fullPath ,
194205 ) ;
195- const hookEntryPoint = require ( hook . fullPath ) ;
206+ let hookEntryPoint ;
207+ if ( isESM ) {
208+ const { default : hookFn } = await import ( hook . fullPath ) ;
209+ hookEntryPoint = hookFn ;
210+ } else {
211+ hookEntryPoint = require ( hook . fullPath ) ;
212+ }
196213
197214 this . $logger . trace ( `Validating ${ hookName } arguments.` ) ;
198215
199216 const invalidArguments = this . validateHookArguments (
200217 hookEntryPoint ,
201- hook . fullPath
218+ hook . fullPath ,
202219 ) ;
203220
204221 if ( invalidArguments . length ) {
205222 this . $logger . warn (
206223 `${
207224 hook . fullPath
208225 } will NOT be executed because it has invalid arguments - ${ color . grey (
209- invalidArguments . join ( ", " )
210- ) } .`
226+ invalidArguments . join ( ", " ) ,
227+ ) } .`,
211228 ) ;
212229 return ;
213230 }
@@ -220,14 +237,13 @@ export class HooksService implements IHooksService {
220237 const projectDataHookArg =
221238 hookArguments [ "hookArgs" ] && hookArguments [ "hookArgs" ] [ "projectData" ] ;
222239 if ( projectDataHookArg ) {
223- hookArguments [ "projectData" ] = hookArguments [
224- "$projectData"
225- ] = projectDataHookArg ;
240+ hookArguments [ "projectData" ] = hookArguments [ "$projectData" ] =
241+ projectDataHookArg ;
226242 }
227243
228244 const maybePromise = this . $injector . resolve (
229245 hookEntryPoint ,
230- hookArguments
246+ hookArguments ,
231247 ) ;
232248 if ( maybePromise ) {
233249 this . $logger . trace ( "Hook promises to signal completion" ) ;
@@ -255,15 +271,15 @@ export class HooksService implements IHooksService {
255271 "Executing %s hook at location %s with environment " ,
256272 hookName ,
257273 hook . fullPath ,
258- environment
274+ environment ,
259275 ) ;
260276
261277 const output = await this . $childProcess . spawnFromEvent (
262278 command ,
263279 [ hook . fullPath ] ,
264280 "close" ,
265281 environment ,
266- { throwError : false }
282+ { throwError : false } ,
267283 ) ;
268284 result = output ;
269285
@@ -275,7 +291,7 @@ export class HooksService implements IHooksService {
275291 "Finished executing %s hook at location %s with environment " ,
276292 hookName ,
277293 hook . fullPath ,
278- environment
294+ environment ,
279295 ) ;
280296 }
281297 const endTime = this . $performanceService . now ( ) ;
@@ -289,7 +305,7 @@ export class HooksService implements IHooksService {
289305 private async executeHooksInDirectory (
290306 directoryPath : string ,
291307 hookName : string ,
292- hookArguments ?: IDictionary < any >
308+ hookArguments ?: IDictionary < any > ,
293309 ) : Promise < any [ ] > {
294310 hookArguments = hookArguments || { } ;
295311 const results : any [ ] = [ ] ;
@@ -301,7 +317,7 @@ export class HooksService implements IHooksService {
301317 directoryPath ,
302318 hookName ,
303319 hook ,
304- hookArguments
320+ hookArguments ,
305321 ) ;
306322
307323 if ( result ) {
@@ -316,14 +332,14 @@ export class HooksService implements IHooksService {
316332 const hooks : IHook [ ] = [ ] ;
317333 const customHooks : INsConfigHooks [ ] = this . $projectConfigService . getValue (
318334 "hooks" ,
319- [ ]
335+ [ ] ,
320336 ) ;
321337
322338 for ( const cHook of customHooks ) {
323339 if ( cHook . type === hookName ) {
324340 const fullPath = path . join (
325341 this . $projectHelper . projectDir ,
326- cHook . script
342+ cHook . script ,
327343 ) ;
328344 const isFile = this . $fs . getFsStats ( fullPath ) . isFile ( ) ;
329345
@@ -332,8 +348,8 @@ export class HooksService implements IHooksService {
332348 hooks . push (
333349 new Hook (
334350 this . getBaseFilename ( fileNameParts [ fileNameParts . length - 1 ] ) ,
335- fullPath
336- )
351+ fullPath ,
352+ ) ,
337353 ) ;
338354 }
339355 }
@@ -346,10 +362,10 @@ export class HooksService implements IHooksService {
346362 const allBaseHooks = this . getHooksInDirectory ( directoryPath ) ;
347363 const baseHooks = _ . filter (
348364 allBaseHooks ,
349- ( hook ) => hook . name . toLowerCase ( ) === hookName . toLowerCase ( )
365+ ( hook ) => hook . name . toLowerCase ( ) === hookName . toLowerCase ( ) ,
350366 ) ;
351367 const moreHooks = this . getHooksInDirectory (
352- path . join ( directoryPath , hookName )
368+ path . join ( directoryPath , hookName ) ,
353369 ) ;
354370 return baseHooks . concat ( moreHooks ) ;
355371 }
@@ -385,13 +401,11 @@ export class HooksService implements IHooksService {
385401 const clientName = this . $staticConfig . CLIENT_NAME . toUpperCase ( ) ;
386402
387403 const environment : IStringDictionary = { } ;
388- environment [ util . format ( "%s-COMMANDLINE" , clientName ) ] = process . argv . join (
389- " "
390- ) ;
404+ environment [ util . format ( "%s-COMMANDLINE" , clientName ) ] =
405+ process . argv . join ( " " ) ;
391406 environment [ util . format ( "%s-HOOK_FULL_PATH" , clientName ) ] = hookFullPath ;
392- environment [
393- util . format ( "%s-VERSION" , clientName )
394- ] = this . $staticConfig . version ;
407+ environment [ util . format ( "%s-VERSION" , clientName ) ] =
408+ this . $staticConfig . version ;
395409
396410 return {
397411 cwd : this . $projectHelper . projectDir ,
@@ -463,7 +477,7 @@ export class HooksService implements IHooksService {
463477
464478 private validateHookArguments (
465479 hookConstructor : any ,
466- hookFullPath : string
480+ hookFullPath : string ,
467481 ) : string [ ] {
468482 const invalidArguments : string [ ] = [ ] ;
469483
@@ -477,7 +491,7 @@ export class HooksService implements IHooksService {
477491 }
478492 } catch ( err ) {
479493 this . $logger . trace (
480- `Cannot resolve ${ argument } of hook ${ hookFullPath } , reason: ${ err } `
494+ `Cannot resolve ${ argument } of hook ${ hookFullPath } , reason: ${ err } ` ,
481495 ) ;
482496 invalidArguments . push ( argument ) ;
483497 }
0 commit comments