0.4.2 • Published 7 months ago

fs-un v0.4.2

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

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

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: {
    /**
     * Called when an error occurs
     */
    (event: 'error', callback: (error: FsError) => void): void
    /**
     * Called when data is read
     */
    (event: 'data', callback: (data: Uint8Array) => void): void
    /**
     * Called when stream ends
     */
    (event: 'end', callback: (isAborted?: true) => void): void
  }
}

export type ReadableStreamOptions = {
  /**
   * Start position in the stream
   * @default 0
   */
  position?: number
  /**
   * Read length
   */
  length?: number
  /**
   * Abort signal
   */
  signal?: AbortSignal
}

export interface IReadonlyFS<RootType> {
  readonly root: RootType
  /**
   * Check file or directory
   */
  exists: (path: string) => Promise<PathType>

  /**
   * Get file attributes
   */
  fileAttr: (path: string) => Promise<FileAttr | undefined>

  /**
   * List directory
   * @throws no such dir
   */
  list: (path: string) => AsyncIterable<ListState>

  /**
   * Read file data as Uint8Array
   */
  readByte: (path: string) => Promise<Uint8Array | undefined>

  /**
   * Read file data as string
   */
  readText: (path: string) => Promise<string | undefined>
}

export interface IStreamFs {
  /**
   * Streamly read file content
   */
  readStream: (path: string, options?: ReadableStreamOptions) => ReadStreamEvent
}

export interface IFS<RootType = any> extends IReadonlyFS<RootType>, IStreamFs {
  /**
   * Ensure directory exists, auto create parent directory
   */
  mkdir: (path: string) => Promise<void>

  /**
   * Append data to file
   */
  appendFile: (path: string, data: string | Uint8Array) => Promise<void>

  /**
   * Write data to file
   */
  writeFile: (path: string, data: string | Uint8Array, options?: OverwriteOptions) => Promise<void>

  /**
   * Move or rename file or dir, in default, throw error when overwrite by default
   */
  move: (from: string, to: string, options?: MoveOptions) => Promise<void>

  /**
   * Copy file or dir, throw error when overwrite by default
   */
  copy: (from: string, to: string, options?: OverwriteOptions) => Promise<void>

  /**
   * Remove directory and file recursively
   */
  remove: (path: string) => Promise<void>
}

export type WalkOptions<T extends AnyFunction, N> = {
  /**
   * Whether to include directories
   */
  includeDirs?: boolean
  /**
   * Whether to prepend root dir path when transform
   */
  withRootPath?: boolean
  /**
   * Max directory depth
   */
  maxDepth?: number
  /**
   * Filter files or directories, executed before `transform`
   */
  filter?: (path: string, isDirectory: boolean) => boolean
  /**
   * Abort controller
   */
  signal?: AbortSignal
  /**
   * Transform result, `state` is undefined if `isDirectory` is `true`
   */
  transform?: T
  /**
   * Whether to filter `null` and `undefined` result from `transform`
   * @default true
   */
  notNullish?: N
}

Reference

0.4.2

7 months ago

0.4.1

7 months ago

0.4.0

7 months ago

0.3.0

11 months ago

0.3.2

10 months ago

0.3.1

10 months ago

0.2.0

1 year ago

0.1.0

1 year ago

0.0.1

2 years ago