import { join } from 'node:path' import { readdirSync, Dirent } from 'node:fs' export type Ressource = { id: number name: string path: string depth: number isDir: boolean isVisible?: boolean extension?: string isOpen?: boolean // Only valide for folder; childrenIds?: number[] } export type Ressources = Ressource[] export type ConfigT = { indent: number defaultDepth: number defaultRes: Ressource } export type StateT = { config: ConfigT ressources: Ressources } export const PIJUL_DIR = '.pijul' export function getExtension(name: string): string { const splitted = name.split('.') return splitted.at(-1)! } export function getParent(path: string): string { return path.split('/').at(-1) as string } export const cmpDirent = (a: Dirent, b: Dirent): 0 | 1 | -1 => !a.isDirectory() && b.isDirectory() ? -1 : a.isDirectory() && !b.isDirectory() ? 1 : 0 export const cmpRessources = (a: Ressource, b: Ressource): 0 | 1 | -1 => a.depth > b.depth ? 1 : a.depth < b.depth ? -1 : a.isDir && !b.isDir ? -1 : !a.isDir && b.isDir ? 1 : ((s1: string, s2: string) => (s1 === s2 ? 0 : s1 > s2 ? 1 : -1))( a.name, b.name ) export function getRessources(path = 'repo') { const ressources: Ressources = [] const collectRessources = (path: string, depth = 1, len = 0) => { const children = readdirSync(path, { withFileTypes: true }) .filter((dirent) => dirent.name !== PIJUL_DIR) .sort(cmpDirent) .map((dirent, index) => { return { id: len === 0 ? index + 1 : len + index, ...(dirent.isDirectory() ? { extension: getExtension(dirent.name) } : null), name: dirent.name, path: join(path, dirent.name), depth, isDir: dirent.isDirectory(), } }) if (len !== 0) { const childrenIds = children.map((ressource) => ressource.id) ressources.forEach((ressource, index, ressources) => { if (ressource.isDir && ressource.path === path) { ressources[index] = { ...ressource, childrenIds, } } }) } ressources.push(...children) children.forEach((ressource) => { if (ressource.isDir) { collectRessources(ressource.path, depth + 1, ressources.length) } }) } collectRessources(path) return ressources } export const transformRessources = (ressources: Ressources): Ressources => ressources.sort(cmpRessources).map((ressource) => ({ ...ressource, ...(ressource.depth > 1 ? { isVisible: false } : { isVisible: true }), ...(ressource.depth > 1 ? { isOpen: false } : { isVisible: true }), }))