import fs from "fs/promises";
import { extensions as folderExtensions } from "vscode-icons/src/iconsManifest/supportedFolders.ts";
import { extensions as fileExtensions } from "vscode-icons/src/iconsManifest/supportedExtensions.ts";
export interface FileNode {
export const sortAll = (a: FileNode, b: FileNode): number => {
if (a.isDirectory && !b.isDirectory) return -1;
if (!a.isDirectory && b.isDirectory) return 1;
return a.name.localeCompare(b.name);
export const sortChildren = (nodes: FileNode[]) => {
for (const node of nodes) {
if (node.isDirectory && node.children) {
node.children.sort(sortAll);
sortChildren(node.children);
return nodes.sort(sortAll);
export const buildFileTree = (files: any[]): FileNode[] => {
const root: FileNode[] = [];
for (const file of files) {
const parts = file.name.split('/');
for (let i = 0; i < parts.length; i++) {
const isLastPart = i === parts.length - 1;
const currentPath = parts.slice(0, i + 1).join('/');
let existingNode = currentLevel.find(node => node.name === part);
const newNode: FileNode = {
isDirectory: !isLastPart,
absolutePath: file.absolutePath,
currentLevel.push(newNode);
currentLevel = existingNode.children!;
export const checkFileExists = async (filePath: string) => {
return true; // File exists
return false; // File does not exist or cannot be accessed
export const resolveFolderIcon = (foldername: string) => {
for (const item of folderExtensions.supported) {
if (item.extensions?.includes(foldername)) {
return folderExtensions.default.folder?.icon;
export const resolveFileIcon = (filename: string, fileExt: string) => {
const baseName = filename.split('/').pop() || filename;
// First check for exact filename matches
for (const item of fileExtensions.supported) {
if (item.filename && item.extensions?.includes(baseName)) {
// Then check for extension matches (more specific than language extensions)
for (const item of fileExtensions.supported) {
if (item.extensions?.includes(fileExt)) {
// Check for language-specific extensions, prioritizing exact language ID matches
for (const item of fileExtensions.supported) {
for (const lang of item.languages ?? []) {
if (lang?.knownExtensions?.includes(fileExt)) {
const langIds = Array.isArray(lang.ids) ? lang.ids : [lang.ids];
if (langIds.includes(fileExt)) {
// Fallback to any language extension match
for (const item of fileExtensions.supported) {
for (const lang of item.languages ?? []) {
if (lang?.knownExtensions?.includes(fileExt)) {
return fileExtensions.default.file?.icon;