Nitrogenous Polymorphic Molecule

    @blinkmobile/json-as-files

    1.2.1 • Public • Published

    json-as-files Travis CI Status npm AppVeyor Status

    convert between files and JSON strings, maintaining certain values as separate files

    Why?

    We have a use case where we wish to serialise JSON data to files, but certain values within that JSON would be more convenient to keep separate. This project keeps all values in the same JSON file by default, but allows you to split certain values out into their own files.

    For example, if you have Markdown content within a JSON structure, this project allows you to maintain it as a separate ".md" file. That way, your editor can help you with Markdown-specific highlighting, etc.

    How?

    Just replace a value in your JSON Object with a "$file" reference: { "$file": "foo.txt" }. Make sure you keep a "foo.txt" file with the desired contents.

    During JSON file reads, we find these references, and replace them with the contents of the referenced file.

    Usage

    basic examples

    const { readData, writeData } = require('@blinkmobile/json-as-files');
     
    readData({ filePath: '/path/to/object.json' })
    .then((object) => { /* ... */ });
     
    writeData({ filePath: '/path/to/object.json', data: { /* ... */ } })
    .then(() => { /* ... */ });

    read example with "$file"

    object.json:

    {
      "title": "short and sweet",
      "content": { "$file": "content.txt"}
    }

    content.txt:

    Too long / inconvenient to include in the primary JSON file.

    JavaScript:

    readData({ filePath: '/path/to/object.json' })
    .then((data) => {
      console.assert(data.title === 'short and sweet');
      console.assert(data.content === 'Too long / inconvenient to include in the primary JSON file.');
    });

    write example with "$file"

    object.json (already on disk):

    {
      "title": "short and sweet",
      "content": { "$file": "content.txt"}
    }

    content.txt may or may not exist beforehand

    JavaScript:

    writeData({
      data: {
        title: 'new title',
        content: 'new content'
      },
      filePath: '/path/to/object.json'
    })
    .then(() => {
      // avoid ...Sync() methods in production, please!
      console.assert(fs.existsSync('/path/to/object.json'));
      console.assert(fs.existsSync('/path/to/content.txt'));
     
      return readData({ filePath: '/path/to/object.json' })
    })
    .then((data) => {
      console.assert(data.title === 'new title');
      console.assert(data.content === 'new content');
    });

    write example with "$file" template

    object.json and content.txt may or may not exist beforehand

    JavaScript:

    writeData({
      data: {
        title: 'new title',
        content: 'new content'
      },
      filePath: '/path/to/object.json',
      template: {
        title: 'short and sweet',
        content: { $file: 'content.txt' }
      }
    })
    .then(() => {
      // avoid ...Sync() methods in production, please!
      console.assert(fs.existsSync('/path/to/object.json'));
      console.assert(fs.existsSync('/path/to/content.txt'));
     
      return readData({ filePath: '/path/to/object.json' })
    })
    .then((data) => {
      console.assert(data.title === 'new title');
      console.assert(data.content === 'new content');
    });

    API

    findReferences()

    findReferences (data: Object) => Promise[FoundReference[]]
    

    Scan a data structure to locate references. Used internally.

    FoundReference

    interface FoundReference {
      path: String[], // property path to the reference within the parent structure
      target: String, // for "$file" references, this is a filename or path
      type: String, // only "$file" has been implemented so far
    }
    

    isFileInReferences()

    isFileReference (refs: FoundReference[], dataPath: String, filePath: String)
      => Boolean
    

    We scanned a data structure for references (see findReferences()). Is this file included in those references?

    isFileReference()

    isFileReference (value: Any) => Boolean
    

    Does this value conform to our definition of a "file reference"?

    readData()

    readData (options: ReadOptions, callback?: Function)
      => Promise[Object|Array]
    

    Read data from the provided filePath and other files relative to it.

    ReadOptions

    interface ReadOptions {
      filePath: String
    }
    

    writeData()

    writeData (options: WriteOptions, callback?: Function)
      => Promise
    

    Write data to the provided filePath and other files relative to it. Internal uses planWriteData() and writePlan().

    Reads pre-existing destination file (if any) to preserve past references (if any). If "template" option is provided, then bypass this check.

    WriteOptions

    interface WriteOptions {
      filePath: String,
      data?: Any,
      template?: Any
    }
    

    planWriteData()

    planWriteData (options: WriteOptions, callback?: Function)
      => Promise[PlannedWrite[]]
    

    Like writeData(), but do not perform actual writes. Prepare a list of planned write operations instead.

    PlannedWrite

    interface PlannedWrite {
      targetPath: String,
      value: Any
    }
    

    writePlan()

    writePlan (options: WritePlanOptions)
      => Promise
    

    Execute a list of planned write operations, writing to target files. If plannedWrite.value is not already a String, then JSON.stringify() first.

    WritePlanOptions

    interface WritePlanOptions {
      plan: PlannedWrite[]
    }
    

    Install

    npm i @blinkmobile/json-as-files

    DownloadsWeekly Downloads

    0

    Version

    1.2.1

    License

    BSD-3-Clause

    Last publish

    Collaborators

    • aaronroworth
    • mymattcarroll
    • kizaonline
    • blinkmobile-admin
    • simon_marklar