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 }),
}))