<commit_before>/* SWM module for Express (Node.js) */

var crypto = require('crypto');

var fs   = require('fs');
var path = require('path');

var express = require('express');

function isObject(value) {
  return typeof value === 'object' && value !== null;
}

function isArray(value) {
  return Object.prototype.toString.call(value) === '[object Array]';
}

function hash(message, algorithm) {
  return crypto.Hash(algorithm).update(message).digest();
}

function md5(message) {
  return hash(message, 'md5');
}

function sha256(message) {
  return hash(message, 'sha256');
}

function hex(buffer) {
  return buffer.toString('hex');
}

function base64(buffer) {
  return buffer.toString('base64');
}

function fileHash(filename, algorithm, callback) {
  var hash = crypto.Hash(algorithm);

  var stream = fs.createReadStream(filename);

  stream.on('data', function (data) {
    hash.update(data);
  });

  stream.on('error', function (error) {
    callback(error);
  });

  stream.on('end', function () {
    callback(null, hex(hash.digest()));
  });
}

var _class = function (config) {
  this.config = config;
};

_class.prototype.router = function () {
  var self = this;

  if (self._router) {
    return self._router;
  }

  var router = express.Router();

  var cache = {};

  function contentHash(key, callback) {
    var obj = cache[key];

    if (obj && +new Date() <= obj.timestamp + 60000) {
      callback(obj.error, obj.digest);
      return;
    }

    var filename = path.join(self.config.root, key);

    fileHash(filename, 'md5', function (error, digest) {
      cache[key] = { timestamp: +new Date(), error: error, digest: digest };

      callback(error, digest);
    });
  }
<commit_msg>Validate config<commit_after>/* SWM module for Express (Node.js) */

var crypto = require('crypto');

var fs   = require('fs');
var path = require('path');

var express = require('express');

function isObject(value) {
  return typeof value === 'object' && value !== null;
}

function isArray(value) {
  return Object.prototype.toString.call(value) === '[object Array]';
}

function hash(message, algorithm) {
  return crypto.Hash(algorithm).update(message).digest();
}

function md5(message) {
  return hash(message, 'md5');
}

function sha256(message) {
  return hash(message, 'sha256');
}

function hex(buffer) {
  return buffer.toString('hex');
}

function base64(buffer) {
  return buffer.toString('base64');
}

function fileHash(filename, algorithm, callback) {
  var hash = crypto.Hash(algorithm);

  var stream = fs.createReadStream(filename);

  stream.on('data', function (data) {
    hash.update(data);
  });

  stream.on('error', function (error) {
    callback(error);
  });

  stream.on('end', function () {
    callback(null, hex(hash.digest()));
  });
}

var _class = function (config) {
  if (!config || !config.root || !config.working || !config.published
      || !config.content || !config.content.baseUri) {
    throw new Error('Invalid config');
  }

  var options = isArray(config.payment) ? config.payment
      : isObject(config.payment) ? [ config.payment ] : [];

  options.forEach(function (option) {
    if (!option.network || !option.address
        || option.amount % 1 !== 0 || option.amount < 0) {
      throw new Error('Invalid config');
    }
  });

  this.config = config;
};

_class.prototype.router = function () {
  var self = this;

  if (self._router) {
    return self._router;
  }

  var router = express.Router();

  var cache = {};

  function contentHash(key, callback) {
    var obj = cache[key];

    if (obj && +new Date() <= obj.timestamp + 60000) {
      callback(obj.error, obj.digest);
      return;
    }

    var filename = path.join(self.config.root, key);

    fileHash(filename, 'md5', function (error, digest) {
      cache[key] = { timestamp: +new Date(), error: error, digest: digest };

      callback(error, digest);
    });
  }

{'fraction_non_alphanumeric': 0.16790566521404768, 'fraction_numerical': 0.009997436554729556, 'mean_word_length': 3.634204275534442, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2285925', 'n_tokens_mistral': 1271, 'n_tokens_neox': 1215, 'n_words': 294}