56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
import fs from 'node:fs';
|
|
import { createRequire } from 'node:module';
|
|
import path from 'node:path';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
|
|
export type DirectoryImportOptions = {
|
|
targetDirectoryPath: string;
|
|
importPattern?: RegExp;
|
|
includeSubdirectories?: boolean;
|
|
};
|
|
|
|
const VALID_IMPORT_EXTENSIONS = new Set(['.js', '.mjs', '.cjs', '.ts', '.tsx', '.json']);
|
|
|
|
const readDirectory = (targetDirectoryPath: string, includeSubdirectories: boolean): string[] => {
|
|
const entries = fs.readdirSync(targetDirectoryPath, { withFileTypes: true });
|
|
const files: string[] = [];
|
|
|
|
for (const entry of entries) {
|
|
const fullPath = path.join(targetDirectoryPath, entry.name);
|
|
if (entry.isDirectory()) {
|
|
if (includeSubdirectories) {
|
|
files.push(...readDirectory(fullPath, includeSubdirectories));
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (entry.isFile()) {
|
|
files.push(fullPath);
|
|
}
|
|
}
|
|
|
|
return files;
|
|
};
|
|
|
|
export const directoryImport = ({ targetDirectoryPath, importPattern = /.*/, includeSubdirectories = true }: DirectoryImportOptions) => {
|
|
const modules: Record<string, unknown> = {};
|
|
const filesPaths = readDirectory(targetDirectoryPath, includeSubdirectories);
|
|
|
|
for (const filePath of filesPaths) {
|
|
const { ext: fileExtension } = path.parse(filePath);
|
|
const isValidModuleExtension = VALID_IMPORT_EXTENSIONS.has(fileExtension);
|
|
const isDeclarationFile = filePath.endsWith('.d.ts') || filePath.endsWith('.d.tsx');
|
|
const isValidFilePath = importPattern.test(filePath);
|
|
|
|
if (!isValidModuleExtension || isDeclarationFile || !isValidFilePath) {
|
|
continue;
|
|
}
|
|
|
|
const relativeModulePath = filePath.slice(targetDirectoryPath.length);
|
|
modules[relativeModulePath] = require(filePath);
|
|
}
|
|
|
|
return modules;
|
|
};
|