diff --git a/src/core/cli.ts b/src/core/cli.ts index c3ecd1b..bb2d92e 100644 --- a/src/core/cli.ts +++ b/src/core/cli.ts @@ -282,32 +282,28 @@ instead of "${definition.name}"`); let targetPath: string | undefined; let targetModule: CommandModule | undefined; - let contexts: SubcommandSearchContext[] = await v.map( - this.roots, - async root => { - let path: string | undefined = Path.join(root.path, 'default.js'); - path = (await existsFile(path)) ? path : undefined; + let contexts: SubcommandSearchContext[] = this.roots.map(root => { + let path = existsFile(root.path); - let module: CommandModule | undefined; + let module: CommandModule | undefined; - if (path) { - module = require(path) as CommandModule; + if (path) { + module = require(path) as CommandModule; - if (module.default || !targetPath) { - targetPath = path; - targetModule = module; - } + if (module.default || !targetPath) { + targetPath = path; + targetModule = module; } + } - return { - label: root.label, - name: this.name, - searchBase: root.path, - path, - module, - }; - }, - ); + return { + label: root.label, + name: this.name, + searchBase: root.path, + path, + module, + }; + }); for (let i = argsIndex; i < argv.length && contexts.length; i++) { let possibleCommandName = argv[i]; @@ -415,18 +411,12 @@ instead of "${definition.name}"`); private static async findEntryBySearchBase( searchBase: string, ): Promise { - let possiblePaths = [ - `${searchBase}.js`, - Path.join(searchBase, 'default.js'), - ]; - - for (let possiblePath of possiblePaths) { - if (await existsFile(possiblePath)) { - return { - path: possiblePath, - module: require(possiblePath) as CommandModule, - }; - } + const srcFile = existsFile(searchBase); + if (srcFile !== undefined) { + return { + path: srcFile, + module: require(srcFile) as CommandModule, + }; } if (await existsDir(searchBase)) { diff --git a/src/core/command/help.ts b/src/core/command/help.ts index 04c61c2..42ed9bd 100644 --- a/src/core/command/help.ts +++ b/src/core/command/help.ts @@ -13,6 +13,7 @@ import {CLI, CommandModule} from '../cli'; import { buildTableOutput, existsDir, + existsFile, indent, safeStat, } from '../../internal-util'; @@ -102,18 +103,22 @@ export class HelpInfo implements Printable { let names = await v.call(FS.readdir, dir); for (let name of names) { - let path = Path.join(dir, name); + let path: string | undefined = Path.join(dir, name); let stats = await safeStat(path); if (stats!.isFile()) { - if (name === 'default.js' || Path.extname(path) !== '.js') { + const ext = Path.extname(path); + name = Path.basename(path).replace(ext, ''); + + if ( + name === 'default' || + (ext !== '.js' && ext !== '.ts') || + path.endsWith('.d.ts') + ) { continue; } - - name = Path.basename(name, '.js'); } else { - path = Path.join(path, 'default.js'); - stats = await safeStat(path); + path = await existsFile(path); } let existingItem = helpItemMap.get(name); @@ -130,7 +135,7 @@ export class HelpInfo implements Printable { let commandConstructor: CommandClass | undefined; let brief: string | undefined; - if (stats) { + if (path) { let module = require(path) as CommandModule; commandConstructor = module.default; brief = diff --git a/src/internal-util/fs.ts b/src/internal-util/fs.ts index f045d03..f71f5bb 100644 --- a/src/internal-util/fs.ts +++ b/src/internal-util/fs.ts @@ -1,4 +1,5 @@ import * as FS from 'fs'; +import * as Path from 'path'; import * as v from 'villa'; @@ -6,9 +7,25 @@ export async function safeStat(path: string): Promise { return v.call(FS.stat, path).catch(v.bear); } -export async function existsFile(path: string): Promise { - let stats = await safeStat(path); - return !!stats && stats.isFile(); +export function existsFile( + path: string, + filename: string = 'default', +): string | undefined { + const checkPaths = [Path.join(path, filename)]; + + if (filename === 'default') { + checkPaths.unshift(path); + } + + for (const check of checkPaths) { + try { + return require.resolve(check); + } catch { + continue; + } + } + + return undefined; } export async function existsDir(path: string): Promise {