1
1
import assert from 'node:assert' ;
2
2
import fs from 'node:fs/promises' ;
3
3
import path from 'node:path' ;
4
- import url from 'node:url' ;
4
+ import { pathToFileURL , fileURLToPath } from 'node:url' ;
5
5
import { isNativeError , isPromise } from 'node:util/types' ;
6
6
7
7
import makeVanillaYargs from 'yargs/yargs' ;
@@ -67,38 +67,38 @@ suppressNodeWarnings('ExperimentalWarning');
67
67
* `PreExecutionContext::execute` is called.
68
68
*/
69
69
export async function discoverCommands (
70
- basePath : string ,
70
+ basePath_ : string ,
71
71
context : ExecutionContext
72
72
) : Promise < void > {
73
73
// ! Invariant: first command to be discovered, if any, is the root command.
74
74
let alreadyLoadedRootCommand = false ;
75
75
76
- const basePath_ = basePath ?. startsWith ?.( 'file://' )
77
- ? url . fileURLToPath ( basePath )
78
- : basePath ;
76
+ const basePath = basePath_ ?. startsWith ?.( 'file://' )
77
+ ? fileURLToPath ( basePath_ )
78
+ : basePath_ ;
79
79
80
80
const debug = context . debug . extend ( 'discover' ) ;
81
81
const debug_load = debug . extend ( 'load' ) ;
82
82
83
- debug ( 'ensuring base path directory exists and is readable: "%O"' , basePath_ ) ;
83
+ debug ( 'ensuring base path directory exists and is readable: "%O"' , basePath ) ;
84
84
85
85
try {
86
- await fs . access ( basePath_ , fs . constants . R_OK ) ;
87
- if ( ! ( await fs . stat ( basePath_ ) ) . isDirectory ( ) ) {
86
+ await fs . access ( basePath , fs . constants . R_OK ) ;
87
+ if ( ! ( await fs . stat ( basePath ) ) . isDirectory ( ) ) {
88
88
// ? This will be caught and re-thrown as an AssertionFailedError 👍🏿
89
89
throw new Error ( 'path is not a directory' ) ;
90
90
}
91
91
} catch ( error ) {
92
- debug . error ( 'failed due to invalid base path "%O": %O' , basePath_ , error ) ;
92
+ debug . error ( 'failed due to invalid base path "%O": %O' , basePath , error ) ;
93
93
throw new AssertionFailedError (
94
- ErrorMessage . AssertionFailureBadConfigurationPath ( basePath_ )
94
+ ErrorMessage . AssertionFailureBadConfigurationPath ( basePath )
95
95
) ;
96
96
}
97
97
98
- debug ( 'searching upwards for nearest package.json file starting at %O' , basePath_ ) ;
98
+ debug ( 'searching upwards for nearest package.json file starting at %O' , basePath ) ;
99
99
100
100
const pkg = {
101
- path : await ( await import ( 'pkg -up' ) ) . pkgUp ( { cwd : basePath_ } ) ,
101
+ path : await ( await import ( 'package -up' ) ) . packageUp ( { cwd : basePath } ) ,
102
102
name : undefined as string | undefined ,
103
103
version : undefined as string | undefined
104
104
} ;
@@ -136,9 +136,9 @@ export async function discoverCommands(
136
136
}
137
137
}
138
138
139
- debug ( 'beginning configuration module auto-discovery at %O' , basePath_ ) ;
139
+ debug ( 'beginning configuration module auto-discovery at %O' , basePath ) ;
140
140
141
- await discover ( basePath_ ) ;
141
+ await discover ( basePath ) ;
142
142
143
143
debug ( 'configuration module auto-discovery completed' ) ;
144
144
@@ -151,7 +151,7 @@ export async function discoverCommands(
151
151
debug_load . message ( '%O' , context . commands ) ;
152
152
} else {
153
153
throw new AssertionFailedError (
154
- ErrorMessage . AssertionFailureNoConfigurationLoaded ( basePath_ )
154
+ ErrorMessage . AssertionFailureNoConfigurationLoaded ( basePath )
155
155
) ;
156
156
}
157
157
@@ -347,14 +347,21 @@ export async function discoverCommands(
347
347
while ( maybeConfigPaths . length ) {
348
348
try {
349
349
const maybeConfigPath = maybeConfigPaths . shift ( ) ! ;
350
- debug_ ( 'attempting to load configuration file: %O' , maybeConfigPath ) ;
350
+ const maybeConfigFileURL = pathToFileURL ( maybeConfigPath ) . toString ( ) ;
351
+
352
+ debug_ (
353
+ 'attempting to load configuration file url: %O (real path: %O)' ,
354
+ maybeConfigFileURL ,
355
+ maybeConfigPath
356
+ ) ;
351
357
352
358
let maybeImportedConfig : ImportedConfigurationModule | undefined = undefined ;
353
359
354
360
try {
355
- // TODO: defer importing the command/config until later?
361
+ // TODO: Defer importing the command/config until later (will require
362
+ // TODO: major refactor)
356
363
// eslint-disable-next-line no-await-in-loop
357
- maybeImportedConfig = await import ( maybeConfigPath ) ;
364
+ maybeImportedConfig = await import ( maybeConfigFileURL ) ;
358
365
} catch ( error ) {
359
366
if (
360
367
isUnknownFileExtensionError ( error ) ||
@@ -375,7 +382,7 @@ export async function discoverCommands(
375
382
const meta = {
376
383
hasChildren : false ,
377
384
filename : path . basename ( maybeConfigPath ) ,
378
- filepath : maybeConfigPath ,
385
+ filepath : maybeConfigFileURL ,
379
386
parentDirName : path . basename ( path . dirname ( maybeConfigPath ) )
380
387
} as ProgramMetadata ;
381
388
@@ -407,7 +414,8 @@ export async function discoverCommands(
407
414
408
415
if ( typeof maybeImportedConfig === 'function' ) {
409
416
debug_ ( 'configuration returned a function' ) ;
410
- // TODO: defer calling the command() function until it is needed...
417
+ // TODO: Defer invoking default export until later (will require
418
+ // TODO: major refactor)
411
419
// eslint-disable-next-line no-await-in-loop
412
420
rawConfig = await maybeImportedConfig ( context ) ;
413
421
} else {
@@ -1321,10 +1329,10 @@ function defaultCommandHandler() {
1321
1329
}
1322
1330
1323
1331
/**
1324
- * Replace all the ASCII#32 space characters in a string with hyphens.
1332
+ * Replace all space characters in a string with hyphens.
1325
1333
*/
1326
1334
function replaceSpaces ( str : string ) {
1327
- return str . replaceAll ( ' ' , '-' ) ;
1335
+ return str . replaceAll ( / \s / g , '-' ) ;
1328
1336
}
1329
1337
1330
1338
/**
0 commit comments