// Config Class/Property initialisation --

var crypto  = require('crypto');
var i18n    = require('i18next');
var db      = require('../modules/database');

// -- Helper methods --

var hash = function(value) {
  return crypto.createHash('sha256').update(value).digest('base64');
};

var apply = function(objects, fn) {
  if(Array.isArray(objects)) {
    objects.forEach(function(object) {
      fn(object);
    });

    return objects;
  }
  else if(objects) {
    return fn(objects);
  }
  else {
    return null;
  }
};

// -- Config Class members --

exports.populateConfigClass = function(configClass) {

  // -- Methods --
  configClass.forEachProperty = function(fn) {
    for(var m of this.property)
      fn(m);
  };

  configClass.apply = apply;

  configClass.getLabel = function(req) {
    var ref = req || i18n;
    return ref.t('custom:'+ this.name +'.name');
  };

  configClass.populateObjectFromRecord = function(obj, record) {
    this.forEachProperty(function(property) {
      switch(property.type)
      {
        case 'text':
          obj[property.name] = record[property.name];
          break;
        case 'password':
          obj[property.name] = record[property.name];
          break;
        case 'date':
          obj[property.name] = record[property.name];
          break;
        case 'list':
          obj[property.name] = '';
          break;
        case 'reference':
          obj[property.name] = '';
          break;
        default:
          obj[property.name] = record[property.name];
          break;
      }
    });

    // Other properties --
    obj.rid = record['@rid'];

    return obj;
  };

  configClass.populateRecordFromObject = function(record, obj) {
    this.forEachProperty(function(property) {
      switch(property.type)
      {
        case 'text':
          record[property.name] = obj[property.name];
          break;
        case 'password':
          record[property.name] = hash(obj[property.name]);
          break;
        case 'date':
          record[property.name] = obj[property.name];
          break;
        case 'list':
          record[property.name] = '';
          break;
        case 'reference':
          record[property.name] = '';
          break;
        default:
          record[property.name] = obj[property.name];
          break;
      }
    });

    if(obj.hasOwnProperty('active')) {
      record.active = obj.active;
    } else {
      record.active = true;
    }

    return record;
  };

  configClass.populateRecordFromReq = function(record, body) {
    this.forEachProperty(function(property) {
      switch(property.type)
      {
        case 'text':
          record[property.name] = body[property.name];
          break;
        case 'password':
          record[property.name] = hash(body[property.name]);
          break;
        case 'date':
          record[property.name] = body[property.name];
          break;
        case 'list':
          record[property.name] = '';
          break;
        case 'reference':
          record[property.name] = '';
          break;
        default:
          record[property.name] = body[property.name];
          break;
      }
    });

    record.active = true;
    return record;
  };

  configClass.addMethodsToObject = function(obj) {

    obj.save = function() {
      var record = {};
      this.populateRecordFromObject(record, this);
      return db.helper.createRecords(this.name, this);
    };

  };

  configClass.constructObjectFromRecord = function(obj, record) {
    this.populateObjectFromRecord(obj, record);
    this.addMethodsToObject(obj);
    return obj;
  };

  configClass.transformRecordsIntoObjects = function(records) {

    if(Array.isArray(records)) {
      var list = [];
      records.forEach((record) => { list.push(this.constructObjectFromRecord({}, record)); });
      return list;
    }
    else if(records) {
      return this.constructObjectFromRecord({}, records);
    }
    else {
      return null;
    }
  };

  configClass.transformObjectsIntoRecords = function(objects) {

    if(Array.isArray(objects)) {
      var list = [];
      objects.forEach((object) => { list.push(this.populateRecordFromObject({}, object)); });
      return list;
    }
    else if(objects) {
      return this.populateRecordFromObject({}, objects);
    }
    else {
      return null;
    }
  };

  configClass.createRecordsInDb = function(records) {

    // Circular dependency fix --
    if(!db.helper) {
      delete require.cache[require.resolve('../modules/database')];
      db = require('../modules/database');
    }

    console.log(db);
    return db.helper.createRecords(this.name, records);
  };
};

// -- Property members --

exports.populateProperty = function(property, configClass) {

  // Add methods --
  property.getLabel = function(req) {
    var ref = req || i18n;
    return ref.t('custom:' + configClass.name + '.property.' + this.name);
  };

  // Generate hash on property name --
  property.hash = hash(property.name);
};
@@ -283,20 +283,31 @@
 ;%0A%0Avar a
-pply
+rrayifyFunction
  = funct
@@ -310,23 +310,21 @@
 unction(
-objects
+array
 , fn) %7B%0A
@@ -346,109 +346,41 @@
 ray(
-objects)) %7B%0A    objects.forEach(function(object) %7B%0A      fn(object);%0A    %7D);%0A%0A    return objects;%0A  %7D
+array))%0A    return array.map(fn);
 %0A  e
@@ -382,34 +382,30 @@
 ;%0A  else if(
-objects) %7B
+array)
 %0A    return 
@@ -411,30 +411,22 @@
  fn(
-objects
+array
 );%0A
-  %7D%0A
   else
- %7B
 %0A   
@@ -439,20 +439,16 @@
 n null;%0A
-  %7D%0A
 %7D;%0A%0A// -
@@ -669,20 +669,31 @@
 pply = a
-pply
+rrayifyFunction
 ;%0A%0A  con
@@ -3623,203 +3623,56 @@
 ) %7B%0A
-%0A
     
-if(Array.isArray(records)) %7B%0A      var list = %5B%5D;%0A      records.forEach((record) =%3E %7B list.push(this.constructObjectFromRecord(%7B%7D, record)); %7D);%0A      return list;%0A    %7D%0A    else if
+return arrayifyFunction(records, 
 (record
-s
 )
+ =%3E
  %7B%0A 
@@ -3724,25 +3724,24 @@
 , record
-s
 );%0A    %7D
 %0A    els
@@ -3736,44 +3736,10 @@
    %7D
-%0A    else %7B%0A      return null;%0A    %7D
+);
 %0A  %7D
@@ -3809,202 +3809,56 @@
 ) %7B%0A
-%0A
     
-if(Array.isArray(objects)) %7B%0A      var list = %5B%5D;%0A      objects.forEach((object) =%3E %7B list.push(this.populateRecordFromObject(%7B%7D, object)); %7D);%0A      return list;%0A    %7D%0A    else if
+return arrayifyFunction(objects, 
 (object
-s
 )
+ =%3E
  %7B%0A 
@@ -3909,25 +3909,24 @@
 , object
-s
 );%0A    %7D
 %0A    els
@@ -3921,44 +3921,10 @@
    %7D
-%0A    else %7B%0A      return null;%0A    %7D
+);
 %0A  %7D

Improve Schema-class definitions