Skip to content

Instantly share code, notes, and snippets.

@khalidx
Last active November 22, 2023 19:55
Show Gist options
  • Save khalidx/4c0b47c630625991e97c1247e2eed3fb to your computer and use it in GitHub Desktop.
Save khalidx/4c0b47c630625991e97c1247e2eed3fb to your computer and use it in GitHub Desktop.
List or list and import all files in a directory without any node libraries.
import { join, basename, extname } from 'path'
import { readdir } from 'fs-extra'
/**
* Lists all files in the specified `directory`, without any external libraries.
*
* If `directory` is not specified, `process.cwd()` is used.
*
* Set `includeDirectories` to `true` to also include directory names in the output.
*
* Set `importModules` to `true` to also attempt to import the file as a Node.js module
* with `await import()`. If the file is a module, the `module` will be included in the
* result. Otherwise if the import failed, the `module` will be undefined. When
* `importModules` is specified, `includeDirectories` has no effect.
*
* If `recursive` is set to `true`, subdirectories will be traversed as well.
*
* This function works well for extremely large directories where all file names may not fit
* into memory. The recommended usage is with async iteration, like:
*
* ```typescript
* for await (const file of ls({ directory: __dirname })) {
* console.log(file.path)
* }
* ```
*
* Or, for one file at a time:
*
* ```typescript
* const file = await ls({ directory: __dirname }).next().then(item => item.value?.path)
* ```
*/
export async function* ls (params: { directory?: string, includeDirectories?: boolean, importModules?: boolean, recursive?: boolean }): AsyncGenerator<{ path: string, module?: any }, undefined, unknown> {
const directory = params.directory || process.cwd()
for (const item of await readdir(directory, { withFileTypes: true })) {
const path = join(directory, item.name)
if (item.isDirectory()) {
if (params.includeDirectories && !params.importModules) {
yield { path }
}
if (params.recursive) {
yield* ls({ ...params, directory: path })
}
continue
}
yield params.importModules
? { path, module: await import(join(directory, basename(item.name, extname(item.name)))) }
: { path }
}
return undefined
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment