diff --git a/.eslintrc.js b/.eslintrc.js index 8275d52..529fbc5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -12,6 +12,7 @@ module.exports = { 'react/jsx-props-no-spreading': 'off', 'react/require-default-props': 'off', 'no-await-in-loop': 'off', + 'no-restricted-syntax': 'off', // Allow unused vars if they are prefixed by an underscore '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], diff --git a/src/lib/fs/directory.ts b/src/lib/fs/directory.ts new file mode 100644 index 0000000..34170ca --- /dev/null +++ b/src/lib/fs/directory.ts @@ -0,0 +1,44 @@ +import fs from 'fs'; +import path from 'path'; + +interface Entry { + name: string; + isDirectory: boolean; +} + +/** + * Lists all files and directories in a directory, recursively. + * The base directory is omitted from the returned paths. + */ +export async function getFilesAndDirectories( + folderPath: string +): Promise { + const dirEnts = await fs.promises.readdir(folderPath, { + withFileTypes: true, + }); + + const entries = dirEnts.map((dirEnt) => { + return { + name: dirEnt.name, + isDirectory: dirEnt.isDirectory(), + }; + }); + + const folders = dirEnts.filter((dirEnt) => dirEnt.isDirectory()); + + for (const folder of folders) { + const folderEntries = await getFilesAndDirectories( + path.join(folderPath, folder.name) + ); + entries.push( + ...folderEntries.map((folderEntry) => { + return { + name: path.join(folder.name, folderEntry.name), + isDirectory: folderEntry.isDirectory, + }; + }) + ); + } + + return entries; +} diff --git a/src/lib/fs/index.ts b/src/lib/fs/index.ts new file mode 100644 index 0000000..207ff6c --- /dev/null +++ b/src/lib/fs/index.ts @@ -0,0 +1 @@ +export { getFilesAndDirectories } from './directory'; diff --git a/src/lib/fs/tests/directory.test.ts b/src/lib/fs/tests/directory.test.ts new file mode 100644 index 0000000..7778742 --- /dev/null +++ b/src/lib/fs/tests/directory.test.ts @@ -0,0 +1,22 @@ +import path from 'path'; +import { getFilesAndDirectories } from '../directory'; + +test('getFiles returns all files recursively', async () => { + const files = await getFilesAndDirectories( + path.join(__dirname, 'directoryTest') + ); + expect(files).toEqual([ + { + name: 'a.txt', + isDirectory: false, + }, + { + name: 'b', + isDirectory: true, + }, + { + name: 'b/c.txt', + isDirectory: false, + }, + ]); +}); diff --git a/src/lib/fs/tests/directoryTest/a.txt b/src/lib/fs/tests/directoryTest/a.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/fs/tests/directoryTest/b/c.txt b/src/lib/fs/tests/directoryTest/b/c.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/worker/services/vaults/vault.ts b/src/worker/services/vaults/vault.ts index 6fdc34f..6319d3a 100644 --- a/src/worker/services/vaults/vault.ts +++ b/src/worker/services/vaults/vault.ts @@ -1,3 +1,5 @@ +import { getFilesAndDirectories } from '@/lib/fs'; + export class Vault { private readonly path: string; @@ -6,11 +8,8 @@ export class Vault { } async getFiles(): Promise { - return [ - 'journals/day1.md', - 'pages/meetings/alex.md', - 'pages/meetings/fidji.md', - 'pages/how-to-take-nodes.md', - ]; + return (await getFilesAndDirectories(this.path)) + .filter((e) => !e.isDirectory) + .map((e) => e.name); } }