import path from "path"; import type { TWebpackAsyncRequestResult } from "../../types/webpack"; type TModule> = M & { default?: Record; }; type TGetModuleFn = (props: { module: TModule; path: string; index: number; items: string[]; }) => Result; type TGetFilterFn = (path: string) => boolean; const getFilterFnDefault: TGetFilterFn = (_path) => true; const getModuleFnDefault: TGetModuleFn = ({ module }) => module; /** * Возвращает массив всех файлов из папки при помощи модуля `webpackAsyncContext` * @param requireFn{TWebpackAsyncRequestResult} функция, возвращаемая `import.meta.webpackContext` * @param getModuleFn{TGetModuleFn=} callback для найденного файла * @param getFilterFn{TGetFilterFn=} callback для фильтра найденных файлов * @returns {Promise} * @example * import { getFilesWithContext } from "@delement/ui/utils/webpack"; * * const modules = await getFilesWithContext(import.meta.webpackContext("./", { recursive: true })); */ export const getFilesWithContext = async ( requireFn: TWebpackAsyncRequestResult, getModuleFn: TGetModuleFn = getModuleFnDefault as TGetModuleFn, getFilterFn: TGetFilterFn = getFilterFnDefault ): Promise => { if (!requireFn?.keys) { return []; } // Фиксируем один и тот же порядок для загрузки и для items const requestPaths: string[] = requireFn .keys() .filter((requestPath: string) => getFilterFn(requestPath)) .sort((a: string, b: string) => a.localeCompare(b)); const items: string[] = requestPaths.map((requestPath: string) => path.normalize(requestPath)); const results = await Promise.all( requestPaths.map((requestPath: string) => requireFn(requestPath)) ); return results.map((item: TModule, index: number) => { const module = item?.default ?? item; return getModuleFn({ module, path: items[index], index, items, }); }); };