Nonviolent Pirate Mobster

    fs-safe

    1.2.0 • Public • Published

    A simple fs wrapper that doesn't throw.

    Philosophy

    Throwing is bad. Instead, we should return a value correspondent to the success of an operation.

    • Read operations should return the expected value, or undefined if unable to read.
    • Write operations should return a boolean or undefined success value.
      • true: Successful or unnecessary (ex: failing to create a directory that already exists)
      • false: Unsuccessful
      • undefined: Unsuccessful, but the desired state may already exist (ex: failing to create a directory but not knowing if that directory already exists)

    Installation

    yarn add fs-safe
    npm install fs-safe

    API

    Exists

    Directories

    Files

    JSON

    fileExists

    import { fileExists, fileExistsSync, FileExistsOptions } from "fs-safe";
    
    function fileExists(path: string, options?: FileExistsOptions): Promise<boolean | undefined>;
    
    function fileExistsSync(path: string, options?: FileExistsOptions): boolean | undefined;
    
    type FileExistsOptions = {
        /**
         * Return true if path is directory. Default: `false`
         */
        includeDirectories?: boolean;
    };

    dirExists

    import { dirExists, dirExistsSync, DirExistsOptions } from "fs-safe";
    
    function dirExists(path: string, options?: DirExistsOptions): Promise<boolean | undefined>;
    
    function dirExistsSync(path: string, options?: DirExistsOptions): boolean | undefined;
    
    type DirExistsOptions = {
        /**
         * Return true if path is file. Default: `false`
         */
        includeFiles?: boolean;
    };

    readDir

    import { readDir, readDirSync, ReadDirOptions } from "fs-safe";
    
    function readDir(path: string, options: ReadDirOptions): Promise<string[] | undefined>;
    
    function readDirSync(path: string, options: ReadDirOptions): string[] | undefined;
    
    type ReadDirOptions = {
      /**
       * Recursively read child directories as well. Default: `true`
       */
      recursive?: boolean;
        /**
       * Whether to include directories in the results. Default: `false`
       */
      includeDirectories?: boolean;
    }

    writeDir

    import { writeDir, writeDirSync, WriteDirOptions } from "fs-safe";
    
    function writeDir(path: string, options: WriteDirOptions): Promise<boolean | undefined>;
    
    function writeDirSync(path: string, options: WriteDirOptions): boolean | undefined;
    
    type WriteDirOptions = {
      recursive?: boolean; // Default: true
    }

    removeDir

    import { removeDir, removeDirSync, RemoveDirOptions } from "fs-safe";
    
    function removeDir(path: string, options: RemoveDirOptions): Promise<boolean | undefined>;
    
    function removeDirSync(path: string, options: RemoveDirOptions): boolean | undefined;
    
    type RemoveDirOptions = {
      /**
       * If true, perform a recursive directory removal. Default: `true`
       */
      recursive?: boolean;
    }

    watchDir

    Usage

    import { watchDir } from "fs-safe";
    
    const watcher = watchDir("/path/to/dir");
    
    watcher.onReady(() => {
      console.log(`Ready`);
    }).onAdd((path: string) => {
      console.log(`Added ${path}`);
    }).onChange((path: string) => {
      console.log(`Changed ${path}`);
    }).onRemove((path: string) => {
      console.log(`Removed ${path}`);
    }).onAddDir((path: string) => {
      console.log(`Added dir ${path}`);
    }).onRemoveDir((path: string) => {
      console.log(`Added dir ${path}`);
    });
    
    // To stop watching:
    watcher.stop();

    Types

    import { watchDir, DirWatcher, EventCallback } from "fs-safe";
    
    function watchDir(path: string): DirWatcher;
    
    type EventCallback = (path: string) => void;
    
    type DirWatcher = {
      onAdd: (cb: EventCallback) => DirWatcher;
      onRemove: (cb: EventCallback) => DirWatcher;
      onChange: (cb: EventCallback) => DirWatcher;
      onAddDir: (cb: EventCallback) => DirWatcher;
      onRemoveDir: (cb: EventCallback) => DirWatcher;
      onReady: (cb: () => void) => DirWatcher;
      stop: () => Promise<boolean>;
    }

    readFile

    import { readFile, readFileSync } from "fs-safe";
    
    readFile(path: string) => Promise<string | undefined>;
    
    readFileSync(path: string) => string | undefined;

    writeFile

    import { writeFile, writeFileSync, WriteFileOptions } from "fs-safe";
    
    function writeFile(path: string, content?: string | Buffer): Promise<boolean>;
    
    function writeFileSync(path: string, content?: string | Buffer): boolean;
    
    type WriteFileOptions = {
      /**
       * Recursively create parent directories if needed. Default: `true`
       */
      recursive?: boolean;
      /**
       * Ensure file ends with a newline. Default: `true`
       */
      appendNewline?: boolean;
      /**
       * Write even if file already exists. Default: `true`
       */
      overwrite?: boolean;
    }

    removeFile

    import { removeFile, removeFileSync } from "fs-safe";
    
    function removeFile(path: string): Promise<boolean | undefined>;
    
    function removeFileSync(path: string): boolean | undefined;

    watchFile

    Usage

    import { watchFile } from "fs-safe";
    
    const watcher = watchFile("/path/to/file.txt");
    
    watcher.onReady(() => {
      console.log(`Ready`);
    }).onAdd((path: string) => {
      console.log(`Added ${path}`);
    }).onChange((path: string) => {
      console.log(`Changed ${path}`);
    }).onRemove((path: string) => {
      console.log(`Removed ${path}`);
    });
    
    // To stop watching:
    watcher.stop();

    Types

    import { watchFile, FileWatcher, EventCallback } from "fs-safe";
    
    function watchFile(path: string): FileWatcher;
    
    type EventCallback = (path: string) => void;
    
    type FileWatcher = {
      onAdd: (cb: EventCallback) => FileWatcher;
      onRemove: (cb: EventCallback) => FileWatcher;
      onChange: (cb: EventCallback) => FileWatcher;
      onReady: (cb: () => void) => FileWatcher;
      stop: () => Promise<boolean>;
    }

    makeExecutable

    import { makeExecutable, makeExecutableSync } from "make-executable";
    
    function makeExecutable(path: string): Promise<boolean | undefined>;
    
    function makeExecutableSync(path: string): boolean | undefined;

    readJSON

    Read a JSONValue:

    import { readJSON, readJSONSync, JSONValue } from "read-json-safe";
    
    function readJSON(path: string): Promise<JSONValue | undefined>;
    
    function readJSONSync(path: string): JSONValue | undefined;
    
    type JSONValue = string | number | boolean | JSONObject | JSONArray | null;

    Read a JSONObject:

    import { readJSONObject, readJSONObjectSync, JSONObject } from "read-json-safe";
    
    function readJSONObject(path: string): Promise<JSONObject| undefined>;
    
    function readJSONObjectSync(path: string): JSONObject| undefined;
    
    type JSONObject = {
        [key: string]: JSONValue;
    }

    Read a JSONArray:

    import { readJSONArray, readJSONArraySync, JSONArray } from "read-json-safe";
    
    function readJSONArray(path: string): Promise<JSONArray | undefined>;
    
    function readJSONArraySync(path: string): JSONArray | undefined;
    
    type JSONArray = Array<JSONValue>;

    writeJSON

    import { writeJSON, writeJSONSync, Options, JSONObject } from "write-json-safe";
    
    function writeJSON(path: string, content?: JSONObject, options?: Options): Promise<boolean>;
    
    function writeJSONSync(path: string, content?: JSONObject, options?: Options): boolean;
    
    type Options = {
      /**
       * Output formatted JSON. Default: `true`
       */
      pretty?: boolean;
      /**
       * Recursively create parent directories if needed. Default: `true`
       */
      recursive?: boolean;
      /**
       * Ensure file ends with a newline. Default: `true`
       */
      appendNewline?: boolean;
      /**
       * Write even if file already exists. Default: `true`
       */
      overwrite?: boolean;
    }

    mergeJSON

    Usage

    For existing files:
    import { mergeJSON } from "fs-safe";
    
    // old-file.json (before):
    // {
    //  "ok": true
    // }
    //
    mergeJSON("old-file.json", { test: 1 });
    
    // old-file.json (after):
    // {
    //   "ok": true,
    //   "test": 1
    // }
    //
    For new files:
    import { mergeJSON } from "fs-safe";
    
    mergeJSON("new-file.json", { test: 1 });
    
    // new-file.json:
    // {
    //   "test": 1
    // }
    //

    Types

    import { mergeJSON, mergeJSONSync, JSONObject } from "fs-safe";
    
    function mergeJSON(path: string, object: JSONObject, options?: Options): Promise<boolean>;
    
    function mergeJSONSync(path: string, object: JSONObject, options?: Options): boolean;
    
    type Options = {
      /**
       * Output formatted JSON. Default: `true`
       */
      pretty?: boolean;
      /**
       * Recursively create parent directories if needed. Default: `true`
       */
      recursive?: boolean;
      /**
       * Ensure file ends with a newline. Default: `true`
       */
      appendNewline?: boolean;
    }

    Dependenciesdependencies


    Dev DependenciesDavid


    License license

    MIT

    Install

    npm i fs-safe

    DownloadsWeekly Downloads

    396

    Version

    1.2.0

    License

    MIT

    Unpacked Size

    20.8 kB

    Total Files

    7

    Last publish

    Collaborators

    • bconnorwhite