Files
Kazier/mobile/services/safDirectory.ts
T
2026-09-09 22:31:20 +02:00

105 lines
2.9 KiB
TypeScript

import { Directory, File, Paths } from 'expo-file-system';
import type {
DirectoryEntry,
FileEntry,
Folder,
FolderInfo,
PickDirectoryOptions,
} from './safDirectory.types';
export async function pickDirectory(initialUri?: string): Promise<Folder | null> {
try {
const directory = await Directory.pickDirectoryAsync(initialUri);
if (!directory || !directory.uri) return null;
return toFolder({ uri: directory.uri, name: directory.name, exists: directory.exists });
} catch {
return null;
}
}
export function listDirectory(directoryUri: string): DirectoryEntry[] {
const directory = new Directory(directoryUri);
if (!directory.exists) return [];
try {
return directory.list().map(toEntry);
} catch {
return [];
}
}
export function listFolders(directoryUri: string, options: PickDirectoryOptions = {}): Folder[] {
const { recursive = false, includeRoot = false } = options;
if (!recursive) {
return listDirectory(directoryUri).filter((entry): entry is Folder => entry.isDirectory);
}
const result: Folder[] = [];
if (includeRoot) {
result.push({ ...getFolderInfo(directoryUri), isDirectory: true });
}
const visit = (uri: string) => {
for (const entry of listDirectory(uri)) {
if (entry.isDirectory) {
result.push(entry);
visit(entry.uri);
}
}
};
visit(directoryUri);
return result;
}
export function getFolderInfo(directoryUri: string): FolderInfo {
const directory = new Directory(directoryUri);
return {
uri: directory.uri,
name: directory.name,
exists: directory.exists,
};
}
export function createDirectory(directoryUri: string, name: string): Folder {
const directory = new Directory(Paths.join(directoryUri, name));
directory.create({ idempotent: true, intermediates: true });
return toFolder({ uri: directory.uri, name: directory.name, exists: directory.exists });
}
export function fileFromUri(uri: string): FileEntry {
const file = new File(uri);
return {
uri: file.uri,
name: file.name,
isDirectory: false,
extension: file.extension,
exists: file.exists,
size: file.size,
type: file.type,
lastModified: file.lastModified,
};
}
function toEntry(item: Directory | File): DirectoryEntry {
if (item instanceof Directory) {
return toFolder({ uri: item.uri, name: item.name, exists: item.exists });
}
return {
uri: item.uri,
name: item.name,
isDirectory: false,
extension: item.extension,
exists: item.exists,
size: item.size,
type: item.type,
lastModified: item.lastModified,
};
}
function toFolder({ uri, name, exists }: { uri: string; name?: string; exists?: boolean }): Folder {
const directory = exists === undefined ? new Directory(uri) : null;
return {
uri,
name: name ?? directory?.name ?? Paths.basename(uri),
isDirectory: true,
exists: exists ?? directory?.exists,
};
}