fs-un
Unified util to manage files and directories inside a directory on different platforms
WIP, breaking changes expected between patch versions!!
Install
npm install fs-un
yarn add fs-un
pnpm add fs-un
Usage
Node
Using nodejs fs
module. nodejs@^16
import { NodeFS, walk } from 'fs-un'
const ifs = new NodeFS('/path/to/dir')
for await (const path of walk(ifs.root, { includeDirs: true, transform: (path, isDirectory) => path })) {
console.log(path)
}
Web
Using File Systen Access API
- In Safari,
writeFile
or appendFile
only can be used in Web Worker, due to createWritable()
api missing
import { getOpfsRoot, getUserRoot, isSupportOpfsRoot, isSupportUserRoot, walk, WebFS } from 'fs-un/web'
let root
if (isSupportUserRoot()) {
root = await getUserRoot()
} else if (isSupportOpfsRoot()) {
root = await getOpfsRoot()
} else {
throw new Error('not support')
}
const ifs = new WebFS(root)
for await (const path of walk(ifs.root, { includeDirs: true, transform: (path, fileHandle) => path })) {
console.log(path)
}
Types
See more in types.ts
export type ReadStreamEvent = {
on: {
(event: 'error', callback: (error: FsError) => void): void
(event: 'data', callback: (data: Uint8Array) => void): void
(event: 'end', callback: (isAborted?: true) => void): void
}
}
export type ReadableStreamOptions = {
position?: number
length?: number
signal?: AbortSignal
}
export interface IReadonlyFS<RootType> {
readonly root: RootType
exists: (path: string) => Promise<PathType>
fileAttr: (path: string) => Promise<FileAttr | undefined>
list: (path: string) => AsyncIterable<ListState>
readByte: (path: string) => Promise<Uint8Array | undefined>
readText: (path: string) => Promise<string | undefined>
}
export interface IStreamFs {
readStream: (path: string, options?: ReadableStreamOptions) => ReadStreamEvent
}
export interface IFS<RootType = any> extends IReadonlyFS<RootType>, IStreamFs {
mkdir: (path: string) => Promise<void>
appendFile: (path: string, data: string | Uint8Array) => Promise<void>
writeFile: (path: string, data: string | Uint8Array, options?: OverwriteOptions) => Promise<void>
move: (from: string, to: string, options?: MoveOptions) => Promise<void>
copy: (from: string, to: string, options?: OverwriteOptions) => Promise<void>
remove: (path: string) => Promise<void>
}
export type WalkOptions<T extends AnyFunction, N> = {
includeDirs?: boolean
withRootPath?: boolean
maxDepth?: number
filter?: (path: string, isDirectory: boolean) => boolean
signal?: AbortSignal
transform?: T
notNullish?: N
}
Reference