Jump To …
nconf/common.html nconf/formats.html nconf/provider.html nconf/stores/file.html nconf/stores/memory.html nconf/stores/system.html nconf/stores.html nconf.html

# file.js

¶

    /*
     * file.js: Simple file storage engine for nconf files
     *
     * (C) 2011, Charlie Robbins
     *
     */

    var fs = require('fs'),
        path = require('path'),
        util = require('util'),
        formats = require('../formats'),
        Memory = require('./memory').Memory;

¶

### function File (options)

#### @options {Object} Options for this instance

Constructor function for the File nconf store, a simple abstraction around the Memory store that can persist configuration to disk.

    var File = exports.File = function (options) {
      if (!options || !options.file) {
        throw new Error ('Missing required option `files`');
      }

      Memory.call(this, options);

      this.type   = 'file';
      this.file   = options.file;
      this.dir    = options.dir    || process.cwd();
      this.format = options.format || formats.json;
    };

¶

Inherit from the Memory store

    util.inherits(File, Memory);

¶

### function save (value, callback)

#### @value {Object} Ignored Left here for consistency

#### @callback {function} Continuation to respond to when complete.

Saves the current configuration object to disk at `this.file` using the format specified by `this.format`.

    File.prototype.save = function (value, callback) {
      if (!callback) {
        callback = value;
        value = null;
      }

      fs.writeFile(this.file, this.format.stringify(this.store), function (err) {
        return err ? callback(err) : callback();
      });
    };

¶

### function saveSync (value, callback)

#### @value {Object} Ignored Left here for consistency

#### @callback {function} Optional Continuation to respond to when complete.

Saves the current configuration object to disk at `this.file` using the format specified by `this.format` synchronously.

    File.prototype.saveSync = function (value) {
      try {
        fs.writeFileSync(this.file, this.format.stringify(this.store));
      }
      catch (ex) {
        throw(ex);
      }
    };

¶

### function load (callback)

#### @callback {function} Continuation to respond to when complete.

Responds with an Object representing all keys associated in this instance.

    File.prototype.load = function (callback) {
      var self = this;

      path.exists(self.file, function (exists) {
        if (!exists) {

¶

If the path we are attempting to load doesn't exist, create it

          self.save({}, function (err) {
            self.store = {};
            return callback(err, self.store);
          });
        }
        else {

¶

Else, the path exists, read it from disk

          fs.readFile(self.file, function (err, data) {
            if (err) {
              return callback(err);
            }

            try {
              self.store = self.format.parse(data.toString());
            }
            catch (ex) {
              return callback(new Error("Error parsing your JSON configuration file."));
            }

            callback(null, self.store);
          });
        }
      });
    };

¶

### function load (callback)

#### @callback {function} Optional Continuation to respond to when complete.

Attempts to load the data stored in `this.file` synchronously and responds appropriately.

    File.prototype.loadSync = function () {
      var data, self = this;

      if (!path.existsSync(self.file)) {

¶

If the path we are attempting to load doesn't exist, create it

        self.saveSync({});
        self.store = {};
        data = {};
      }
      else {

¶

Else, the path exists, read it from disk

        try {
          data = this.format.parse(fs.readFileSync(this.file, 'utf8'));
          this.store = data;
        }
        catch (ex) {
          throw new Error("Error parsing your JSON configuration file.")
        }
      }

      return data;
    };

¶

### function search (base)

#### @base {string} Base directory (or file) to begin searching for the target file.

Attempts to find `this.file` by iteratively searching up the directory structure

    File.prototype.search = function (base) {
      var looking = true,
          fullpath,
          previous,
          stats;

      base = base || process.cwd();

      if (this.file[0] === '/') {

¶

If filename for this instance is a fully qualified path (i.e. it starts with a `'/'`) then check if it exists

        try {
          stats = fs.statSync(fs.realpathSync(this.file));
          if (stats.isFile()) {
            fullpath = this.file;
            looking = false;
          }
        }
        catch (ex) {

¶

Ignore errors

        }
      }

      if (looking && base) {

¶

Attempt to stat the realpath located at `base` if the directory does not exist then return false.

        try {
          var stat = fs.statSync(fs.realpathSync(base));
          looking = stat.isDirectory();
        }
        catch (ex) {
          return false;
        }
      }

      while (looking) {

¶

Iteratively look up the directory structure from `base`

        try {
          stats = fs.statSync(fs.realpathSync(fullpath = path.join(base, this.file)));
          looking = stats.isDirectory();
        }
        catch (ex) {
          previous = base;
          base = path.dirname(base);

          if (previous === base) {

¶

If we've reached the top of the directory structure then simply use the default file path.

            try {
              stats = fs.statSync(fs.realpathSync(fullpath = path.join(this.dir, this.file)));
              if (stats.isDirectory()) {
                fullpath = undefined;
              }
            }
            catch (ex) {

¶

Ignore errors

            }

            looking = false;
          }
        }
      }

¶

Set the file for this instance to the fullpath that we have found during the search. In the event that the search was unsuccessful use the original value for `this.file`.

      this.file = fullpath || this.file;

      return fullpath;
    };