<commit_before>import express from 'express'
<%_ if (https) { _%>
import forceSSL from 'express-force-ssl'
<%_ } _%>
import cors from 'cors'
import compression from 'compression'
import morgan from 'morgan'
import bodyParser from 'body-parser'
import methodOverride from 'method-override'
import { errorHandler as queryErrorHandler } from 'querymen'
import { errorHandler as bodyErrorHandler } from 'bodymen'
import { env } from './'

export default (routes) => {
  const app = express()

  <%_ if (https) { _%>
  /* istanbul ignore next */
  if (env === 'production') {
    app.set('forceSSLOptions', {
      enable301Redirects: false,
      trustXFPHeader: true
    })
    app.use(forceSSL)
  }

  <%_ } _%>
  /* istanbul ignore next */
  if (env === 'production' || env === 'development') {
    app.use(cors())
    app.use(compression())
    app.use(morgan('dev'))
  }

  app.use(bodyParser.urlencoded({ extended: false }))
  app.use(bodyParser.json())
  app.use(methodOverride())
  app.use(routes)
  app.use(queryErrorHandler())
  app.use(bodyErrorHandler())

  return app
}
<commit_msg>Remove method-override<commit_after>import express from 'express'
<%_ if (https) { _%>
import forceSSL from 'express-force-ssl'
<%_ } _%>
import cors from 'cors'
import compression from 'compression'
import morgan from 'morgan'
import bodyParser from 'body-parser'
import { errorHandler as queryErrorHandler } from 'querymen'
import { errorHandler as bodyErrorHandler } from 'bodymen'
import { env } from './'

export default (routes) => {
  const app = express()

  <%_ if (https) { _%>
  /* istanbul ignore next */
  if (env === 'production') {
    app.set('forceSSLOptions', {
      enable301Redirects: false,
      trustXFPHeader: true
    })
    app.use(forceSSL)
  }

  <%_ } _%>
  /* istanbul ignore next */
  if (env === 'production' || env === 'development') {
    app.use(cors())
    app.use(compression())
    app.use(morgan('dev'))
  }

  app.use(bodyParser.urlencoded({ extended: false }))
  app.use(bodyParser.json())
  app.use(routes)
  app.use(queryErrorHandler())
  app.use(bodyErrorHandler())

  return app
}
<|endoftext|>


<commit_before>'use strict';

var exec = require('child_process').exec;
var Fs = require('fs');
var Path = require('path');
var Promise = require('promise');

var DocumentDownloader = require('./document-downloader');
var JsonHttpService = require('./json-http-service');
var Publisher = require('./publisher');
var SpecberusWrapper = require('../functions.js').SpecberusWrapper;
var ThirdPartyChecker = require('./third-party-resources-checker');
var TokenChecker = require('../functions.js').TokenChecker;

var STATUS_ERROR = 'error';
var STATUS_SUCCESS = 'success';

// Configuration file
require('../config.js');

var argTempLocation = process.argv[2] || global.DEFAULT_TEMP_LOCATION;
var argHttpLocation  = process.argv[3] || global.DEFAULT_HTTP_LOCATION;
var argResultLocation = process.argv[5] || global.DEFAULT_RESULT_LOCATION;

function Job() {
  if (typeof this !== 'object') {
    throw new TypeError('Job must be constructed via new');
  }

  this.status = '';
  this.errors = [];
}

function dumpJobResult(dest, result) {
  Fs.writeFile(dest, JSON.stringify(result, null, 2) + '\n', function (err) {
    if (err) return console.error(err);
  });
}

function trInstaller(source, dest) {
  return new Promise(function (resolve, reject) {
    var cmd = global.TR_INSTALL_CMD + ' ' + source + ' ' + dest;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

function updateTrShortlink(uri) {
  return new Promise(function (resolve, reject) {
    var cmd = global.UPDATE_TR_SHORTLINK_CMD + ' ' + uri;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

var Orchestrator = function () {};

Orchestrator.prototype.runStep = function (step) {
  return function (state) {
    return step.then(function (obj) {
      state.jobs[obj.name].status = obj.status;

      if (obj.errors) state.jobs[obj.name].errors = obj.errors;
      if (obj.history) state.history = state.history.add(obj.history);
      if (obj.metadata) state.metadata = obj.metadata;

      return state;
    });
  };
};

Orchestrator.prototype.runDocumentDownloader = function (url, tempLocation) {
  // return function (state) {
  //   if (state.jobs['retrieve-resources'].status !== 'pending') return state;
  // };

  return DocumentDownloader.fetchAndInstall(url, tempLocation)
    .then(function () {
      return {
        name: 'retrieve-resources',
        status: 'ok',
        history: 'The file has been retrieved.'
      };
    }).catch(function (error) {
      return {
        name: 'retrieve-resources',
        status: 'error',
        errors: error.toString(),
        history: 'The document could not be retrieved.'
      };
    });
};

Orchestrator.prototype.runSpecberus = function (httpLocation) {
  // return function (state) {
  //   if (state.jobs['specberus'].status !== 'pending') {
  //     return Promise.resolve(state);
  //   }
  // };

  return SpecberusWrapper.validate(httpLocation).then(function (report) {
    if (report.errors.isEmpty()) {
      return {
        name: 'specberus',
        status: 'ok',
        history: 'The document passed specberus.',
        metadata: report.metadata
      };
    }
    else {
      return {
        name: 'specberus',
        status: 'failure',
        errors: report.errors,
        history: 'The document failed Specberus.'
      };
    }
  }).catch(function (error) {
    return {
      name: 'specberus',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while running Specberus.'
    };
  });
};

Orchestrator.prototype.runTokenChecker = function (latestVersion, url, token) {
  // return function (state) {
  //   if (state.jobs['token-checker'].status !== 'pending') {
  //     return Promise.resolve(state);
  //   }
  // };

  return TokenChecker.check(latestVersion, token).then(function (authReport) {
    var simpleSource1 = authReport.source.replace(/^https:/i, 'http:');
    var simpleSource2 = authReport.source.replace(/^http:/i, 'https:');
    var matchSource = (
      url.indexOf(simpleSource1) === 0 ||
      url.indexOf(simpleSource2) === 0
    );

    if (authReport.authorized && matchSource) {
      return {
        name: 'token-checker',
        status: 'ok',
        history: 'You are authorized to publish'
      };
    }
    else {
      return {
        name: 'token-checker',
        status: 'failure',
        errors: 'Not authorized',
        history: 'You are not authorized to publish'
      };
    }
  }).catch(function (error) {
    return {
      name: 'token-checker',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while running the Token Checker.'
    };
  });
};

Orchestrator.prototype.runThirdPartyChecker = function (httpLocation) {
  // return function (state) {
  //   if (state.jobs['third-party-checker'].status !== 'pending') return state;
  // };

  return ThirdPartyChecker.check(httpLocation).then(function (extResources) {
    if (extResources.length === 0) {
      return {
        name: 'third-party-checker',
        status: 'ok',
        history: 'The document passed the third party checker.'
      };
    }
    else {
      return {
        history: 'The document contains non-authorized resources',
        name: 'third-party-checker',
        status: 'failure',
        errors: extResources
      };
    }
  }).catch(function (error) {
    return {
      name: 'third-party-checker',
      status: 'error',
      errors: error.toString(),
      history:
        'An error occurred while running the Third Party Resources Checker.'
    };
  });
};

Orchestrator.prototype.runPublisher = function (metadata) {
  // return function (state) {
  //   if (state.jobs['publish'].status !== 'pending') return state;
  // };

  var pubsystemService = new JsonHttpService(
    global.W3C_PUBSYSTEM_URL,
    global.USERNAME,
    global.PASSWORD
  );

  return new Publisher(pubsystemService).publish(metadata)
    .then(function (errors) {
      if (errors.isEmpty()) {
        return {
          name: 'publish',
          status: 'ok'
        };
      }
      else {
        return {
          name: 'publish',
          status: 'failure',
          errors: errors,
          history: 'The document could not be published: ' +
            errors.map(function (e) { return e.message; })
        };
      }
    }).catch(function (error) {
      return {
        name: 'publish',
        status: 'error',
        errors: error.toString(),
        history: 'The document could not be published: ' + error.message
      };
    });
};

Orchestrator.prototype.runTrInstaller = function (thisVersion, tempLocation) {
  // return function (state) {
  //   if (state.jobs['tr-install'].status !== 'pending') return state;
  // };

  var finalTRpath = thisVersion.replace('http://www.w3.org', '');
  return trInstaller(tempLocation, finalTRpath).then(function () {
    return {
      name: 'tr-install',
      status: 'ok'
    };
  }).catch(function (error) {
    return {
      name: 'tr-install',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while installing the document in TR'
    };
  });
};

Orchestrator.prototype.runShortlink = function (thisVersion) {
  // return function (state) {
  //   if (state.jobs['update-tr-shortlink'].status !== 'pending') return state;
  // };

  return updateTrShortlink(thisVersion).then(function () {
    return {
      name: 'update-tr-shortlink',
      status: 'ok'
    };
  }).catch(function (error) {
    return {
      name: 'update-tr-shortlink',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while updating the shortlink.'
    };
  });
};

Orchestrator.prototype.finishTasks = function (thisVersion) { // , resultLocation) {
  // return function (state) {
  //   var cmd =
  //     global.SENDMAIL + ' SUCCESS ' + global.MAILING_LIST + ' ' + thisVersion;

  //   exec(cmd, function (err, stdout, stderr) {
  //     if (err) console.error(stderr);
  //   });

  //   dumpJobResult(resultLocation, state);
  // };

  return {
    status: STATUS_SUCCESS,
    history: 'The document has been published at ' +
      '' + thisVersion + '.'
  };
};

Orchestrator.prototype.markStarted = function (jobName, previousJobName) {
  return function (state) {
    if (previousJobName === undefined ||
        state.jobs[previousJobName].status === 'ok') {
      state.jobs[jobName].status = 'pending';
    }
    return state;
  };
};

Orchestrator.prototype.run = function (spec, token) {
  var self = this;

  spec.jobs['retrieve-resources'] = new Job();
  spec.jobs['specberus'] = new Job();
  spec.jobs['token-checker'] = new Job();
  spec.jobs['third-party-checker'] = new Job();
  spec.jobs['publish'] = new Job();
  spec.jobs['tr-install'] = new Job();
  spec.jobs['update-tr-shortlink'] = new Job();

  var tempLocation = argTempLocation + Path.sep + spec.id + Path.sep;
  var resultLocation = argResultLocation + Path.sep + spec.id + '.json';
  var httpLocation = argHttpLocation + '/' + spec.id + '/Overview.html';

  return Promise.resolve(self.markStarted('retrieve-resources')(spec))
    .then(self.runStep(self.runDocumentDownloader(spec.url, tempLocation)))
    .then(self.markStarted('specberus', 'retrieve-resources'))
    .then(self.runStep(self.runSpecberus(httpLocation)))
    .then(function (state) {
      var metadata = state.metadata;

      if (metadata === undefined) return state;

      return Promise.resolve(
        self.markStarted('token-checker', 'specberus')(state)
      )
        .then(self.runStep(
          self.runTokenChecker(metadata.get('latestVersion'), spec.url, token)
        )).then(self.markStarted('third-party-checker', 'token-checker'))
        .then(self.runStep(self.runThirdPartyChecker(httpLocation)))
        .then(self.markStarted('publish', 'third-party-checker'))
        .then(self.runStep(self.runPublisher(metadata)))
        .then(self.markStarted('tr-install', 'publish'))
        .then(self.runStep(
          self.runTrInstaller(metadata.get('thisVersion'), tempLocation)
        )).then(self.markStarted('update-tr-shortlink', 'tr-install'))
        .then(self.runStep(self.runShortlink(metadata.get('thisVersion'))))
        .then(function (state) {
          self.runStep(
            self.finishTasks(metadata.get('thisVersion'), resultLocation)
          );

          dumpJobResult(resultLocation, state);
        });
    })
    .catch(function (err) {
      console.log(err.stack);

      spec.status = STATUS_ERROR;
      var cmd =
        global.SENDMAIL + ' ERROR ' + global.MAILING_LIST + ' ' + spec.url +
        ' \'' + JSON.stringify(spec, null, 2) + '\'';

      exec(cmd, function (err, stdout, stderr) {
        if (err) console.error(stderr);
      });

      spec.history = spec.history.add(
        'A system error occurred during the process.'
      );

      dumpJobResult(resultLocation, spec);
      return Promise.reject(new Error('Orchestrator has failed.'));
    });
};

module.exports = Orchestrator;
<commit_msg>Make steps return a Map instead of an Object<commit_after>'use strict';

var exec = require('child_process').exec;
var Fs = require('fs');
var Map = require('immutable').Map;
var Path = require('path');
var Promise = require('promise');

var DocumentDownloader = require('./document-downloader');
var JsonHttpService = require('./json-http-service');
var Publisher = require('./publisher');
var SpecberusWrapper = require('../functions.js').SpecberusWrapper;
var ThirdPartyChecker = require('./third-party-resources-checker');
var TokenChecker = require('../functions.js').TokenChecker;

var STATUS_ERROR = 'error';
var STATUS_SUCCESS = 'success';

// Configuration file
require('../config.js');

var argTempLocation = process.argv[2] || global.DEFAULT_TEMP_LOCATION;
var argHttpLocation  = process.argv[3] || global.DEFAULT_HTTP_LOCATION;
var argResultLocation = process.argv[5] || global.DEFAULT_RESULT_LOCATION;

function Job() {
  if (typeof this !== 'object') {
    throw new TypeError('Job must be constructed via new');
  }

  this.status = '';
  this.errors = [];
}

function dumpJobResult(dest, result) {
  Fs.writeFile(dest, JSON.stringify(result, null, 2) + '\n', function (err) {
    if (err) return console.error(err);
  });
}

function trInstaller(source, dest) {
  return new Promise(function (resolve, reject) {
    var cmd = global.TR_INSTALL_CMD + ' ' + source + ' ' + dest;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

function updateTrShortlink(uri) {
  return new Promise(function (resolve, reject) {
    var cmd = global.UPDATE_TR_SHORTLINK_CMD + ' ' + uri;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

var Orchestrator = function () {};

Orchestrator.prototype.runStep = function (step) {
  return function (state) {
    return step.then(function (obj) {
      state.jobs[obj.name].status = obj.get('status');

      if (obj.has('errors')) state.jobs[obj.name].errors = obj.get('errors');
      if (obj.has('history')) {
        state.history = state.history.add(obj.get('history'));
      }
      if (obj.has('metadata')) state.metadata = obj.get('metadata');

      return state;
    });
  };
};

Orchestrator.prototype.runDocumentDownloader = function (url, tempLocation) {
  // return function (state) {
  //   if (state.jobs['retrieve-resources'].status !== 'pending') return state;
  // };

  return DocumentDownloader.fetchAndInstall(url, tempLocation)
    .then(function () {
      return new Map({
        name: 'retrieve-resources',
        status: 'ok',
        history: 'The file has been retrieved.'
      });
    }).catch(function (error) {
      return new Map({
        name: 'retrieve-resources',
        status: 'error',
        errors: error.toString(),
        history: 'The document could not be retrieved.'
      });
    });
};

Orchestrator.prototype.runSpecberus = function (httpLocation) {
  // return function (state) {
  //   if (state.jobs['specberus'].status !== 'pending') {
  //     return Promise.resolve(state);
  //   }
  // };

  return SpecberusWrapper.validate(httpLocation).then(function (report) {
    if (report.errors.isEmpty()) {
      return new Map({
        name: 'specberus',
        status: 'ok',
        history: 'The document passed specberus.',
        metadata: report.metadata
      });
    }
    else {
      return new Map({
        name: 'specberus',
        status: 'failure',
        errors: report.errors,
        history: 'The document failed Specberus.'
      });
    }
  }).catch(function (error) {
    return new Map({
      name: 'specberus',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while running Specberus.'
    });
  });
};

Orchestrator.prototype.runTokenChecker = function (latestVersion, url, token) {
  // return function (state) {
  //   if (state.jobs['token-checker'].status !== 'pending') {
  //     return Promise.resolve(state);
  //   }
  // };

  return TokenChecker.check(latestVersion, token).then(function (authReport) {
    var simpleSource1 = authReport.source.replace(/^https:/i, 'http:');
    var simpleSource2 = authReport.source.replace(/^http:/i, 'https:');
    var matchSource = (
      url.indexOf(simpleSource1) === 0 ||
      url.indexOf(simpleSource2) === 0
    );

    if (authReport.authorized && matchSource) {
      return new Map({
        name: 'token-checker',
        status: 'ok',
        history: 'You are authorized to publish'
      });
    }
    else {
      return new Map({
        name: 'token-checker',
        status: 'failure',
        errors: 'Not authorized',
        history: 'You are not authorized to publish'
      });
    }
  }).catch(function (error) {
    return new Map({
      name: 'token-checker',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while running the Token Checker.'
    });
  });
};

Orchestrator.prototype.runThirdPartyChecker = function (httpLocation) {
  // return function (state) {
  //   if (state.jobs['third-party-checker'].status !== 'pending') return state;
  // };

  return ThirdPartyChecker.check(httpLocation).then(function (extResources) {
    if (extResources.length === 0) {
      return new Map({
        name: 'third-party-checker',
        status: 'ok',
        history: 'The document passed the third party checker.'
      });
    }
    else {
      return new Map({
        history: 'The document contains non-authorized resources',
        name: 'third-party-checker',
        status: 'failure',
        errors: extResources
      });
    }
  }).catch(function (error) {
    return new Map({
      name: 'third-party-checker',
      status: 'error',
      errors: error.toString(),
      history:
        'An error occurred while running the Third Party Resources Checker.'
    });
  });
};

Orchestrator.prototype.runPublisher = function (metadata) {
  // return function (state) {
  //   if (state.jobs['publish'].status !== 'pending') return state;
  // };

  var pubsystemService = new JsonHttpService(
    global.W3C_PUBSYSTEM_URL,
    global.USERNAME,
    global.PASSWORD
  );

  return new Publisher(pubsystemService).publish(metadata)
    .then(function (errors) {
      if (errors.isEmpty()) {
        return new Map({
          name: 'publish',
          status: 'ok'
        });
      }
      else {
        return new Map({
          name: 'publish',
          status: 'failure',
          errors: errors,
          history: 'The document could not be published: ' +
            errors.map(function (e) { return e.message; })
        });
      }
    }).catch(function (error) {
      return new Map({
        name: 'publish',
        status: 'error',
        errors: error.toString(),
        history: 'The document could not be published: ' + error.message
      });
    });
};

Orchestrator.prototype.runTrInstaller = function (thisVersion, tempLocation) {
  // return function (state) {
  //   if (state.jobs['tr-install'].status !== 'pending') return state;
  // };

  var finalTRpath = thisVersion.replace('http://www.w3.org', '');
  return trInstaller(tempLocation, finalTRpath).then(function () {
    return new Map({
      name: 'tr-install',
      status: 'ok'
    });
  }).catch(function (error) {
    return new Map({
      name: 'tr-install',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while installing the document in TR'
    });
  });
};

Orchestrator.prototype.runShortlink = function (thisVersion) {
  // return function (state) {
  //   if (state.jobs['update-tr-shortlink'].status !== 'pending') return state;
  // };

  return updateTrShortlink(thisVersion).then(function () {
    return new Map({
      name: 'update-tr-shortlink',
      status: 'ok'
    });
  }).catch(function (error) {
    return new Map({
      name: 'update-tr-shortlink',
      status: 'error',
      errors: error.toString(),
      history: 'An error occurred while updating the shortlink.'
    });
  });
};

Orchestrator.prototype.finishTasks = function (thisVersion) { // , resultLocation) {
  // return function (state) {
  //   var cmd =
  //     global.SENDMAIL + ' SUCCESS ' + global.MAILING_LIST + ' ' + thisVersion;

  //   exec(cmd, function (err, stdout, stderr) {
  //     if (err) console.error(stderr);
  //   });

  //   dumpJobResult(resultLocation, state);
  // };

  return new Map({
    status: STATUS_SUCCESS,
    history: 'The document has been published at ' +
      '' + thisVersion + '.'
  });
};

Orchestrator.prototype.markStarted = function (jobName, previousJobName) {
  return function (state) {
    if (previousJobName === undefined ||
        state.jobs[previousJobName].status === 'ok') {
      state.jobs[jobName].status = 'pending';
    }
    return state;
  };
};

Orchestrator.prototype.run = function (spec, token) {
  var self = this;

  spec.jobs['retrieve-resources'] = new Job();
  spec.jobs['specberus'] = new Job();
  spec.jobs['token-checker'] = new Job();
  spec.jobs['third-party-checker'] = new Job();
  spec.jobs['publish'] = new Job();
  spec.jobs['tr-install'] = new Job();
  spec.jobs['update-tr-shortlink'] = new Job();

  var tempLocation = argTempLocation + Path.sep + spec.id + Path.sep;
  var resultLocation = argResultLocation + Path.sep + spec.id + '.json';
  var httpLocation = argHttpLocation + '/' + spec.id + '/Overview.html';

  return Promise.resolve(self.markStarted('retrieve-resources')(spec))
    .then(self.runStep(self.runDocumentDownloader(spec.url, tempLocation)))
    .then(self.markStarted('specberus', 'retrieve-resources'))
    .then(self.runStep(self.runSpecberus(httpLocation)))
    .then(function (state) {
      var metadata = state.metadata;

      if (metadata === undefined) return state;

      return Promise.resolve(
        self.markStarted('token-checker', 'specberus')(state)
      )
        .then(self.runStep(
          self.runTokenChecker(metadata.get('latestVersion'), spec.url, token)
        )).then(self.markStarted('third-party-checker', 'token-checker'))
        .then(self.runStep(self.runThirdPartyChecker(httpLocation)))
        .then(self.markStarted('publish', 'third-party-checker'))
        .then(self.runStep(self.runPublisher(metadata)))
        .then(self.markStarted('tr-install', 'publish'))
        .then(self.runStep(
          self.runTrInstaller(metadata.get('thisVersion'), tempLocation)
        )).then(self.markStarted('update-tr-shortlink', 'tr-install'))
        .then(self.runStep(self.runShortlink(metadata.get('thisVersion'))))
        .then(function (state) {
          self.runStep(
            self.finishTasks(metadata.get('thisVersion'), resultLocation)
          );

          dumpJobResult(resultLocation, state);
        });
    })
    .catch(function (err) {
      console.log(err.stack);

      spec.status = STATUS_ERROR;
      var cmd =
        global.SENDMAIL + ' ERROR ' + global.MAILING_LIST + ' ' + spec.url +
        ' \'' + JSON.stringify(spec, null, 2) + '\'';

      exec(cmd, function (err, stdout, stderr) {
        if (err) console.error(stderr);
      });

      spec.history = spec.history.add(
        'A system error occurred during the process.'
      );

      dumpJobResult(resultLocation, spec);
      return Promise.reject(new Error('Orchestrator has failed.'));
    });
};

module.exports = Orchestrator;
<|endoftext|>


<commit_before>
/**
 *
 * @param  {[type]} scope [description]
 * @return {[type]}       [description]
 */
module.exports = function dataForPackageJSON (scope) {

	scope.sailsPackageJSON = {
		version: '~0.10.0',
		dependencies: {
			'sails-disk': '~0.10.0',
			'ejs': '~0.8.4',
			'grunt': '*'
		}
	};

	// Override sails version temporarily
	var sailsVersionDependency = '~' + scope.sailsPackageJSON.version;

	return {
		name: scope.appName,
		'private': true,
		version: '0.0.0',
		description: 'a Sails application',
		dependencies: {
			'sails'			: sailsVersionDependency,
			'sails-disk'	: scope.sailsPackageJSON.dependencies['sails-disk'],
			'ejs'			: scope.sailsPackageJSON.dependencies['ejs'],
			'grunt'			: scope.sailsPackageJSON.dependencies['grunt']
		},
		scripts: {
			// TODO: Include this later when we have "sails test" ready.
			// test: './node_modules/mocha/bin/mocha -b',
			start: 'node app.js',
			debug: 'node debug app.js'
		},
		main: 'app.js',
		repository: '',
		author: scope.author,
		license: ''
	};
};
<commit_msg>Use jade-- need to figure out proper version when I have the internet.<commit_after>
/**
 *
 * @param  {[type]} scope [description]
 * @return {[type]}       [description]
 */
module.exports = function dataForPackageJSON (scope) {

	scope.sailsPackageJSON = {
		version: '~0.10.0',
		dependencies: {
			'sails-disk': '~0.10.0',
			'ejs': '~0.8.4',
			'grunt': '*'
		}
	};

	// Override sails version temporarily
	var sailsVersionDependency = '~' + scope.sailsPackageJSON.version;

	return {
		name: scope.appName,
		'private': true,
		version: '0.0.0',
		description: 'a Sails application',
		dependencies: {
			'sails'			: sailsVersionDependency,
			'sails-disk'	: scope.sailsPackageJSON.dependencies['sails-disk'],
			'jade'			: '*',
			'grunt'			: scope.sailsPackageJSON.dependencies['grunt']
		},
		scripts: {
			// TODO: Include this later when we have "sails test" ready.
			// test: './node_modules/mocha/bin/mocha -b',
			start: 'node app.js',
			debug: 'node debug app.js'
		},
		main: 'app.js',
		repository: '',
		author: scope.author,
		license: ''
	};
};
<|endoftext|>


<commit_before>// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js

function mahrioRun ($rootScope, $state, $ionicPlatform, localStorageService) {

  $ionicPlatform.ready(function(){
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
      cordova.plugins.Keyboard.disableScroll(true);

    }

    if (window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }

    if(window.analytics != undefined) {
      window.analytics.startTrackerWithId('UA-YOURCODE');
      window.analytics.trackView('Testing')
    } else {
      console.log("window.analytics is undefined");
    }
  });
}

mahrioRun.$inject=['$rootScope', '$state', '$ionicPlatform'];

angular.module('starter', [
  'ionic',
  'starter.controllers',
  'starter.services',
  'starter.directives',
  'angular-underscore'])
  .constant('APP_IP', 'http://192.168.0.4:8042')
  .constant('_', window._)
  .run(mahrioRun)
  .config(function($stateProvider, $urlRouterProvider) {

  // Ionic uses AngularUI Router which uses the concept of states
  // Learn more here: https://github.com/angular-ui/ui-router
  // Set up the various states which the app can be in.
  // Each state's controller can be found in controllers.js
  $stateProvider

  // setup an abstract state for the tabs directive
    .state('tab', {
      url: '/tab',
      abstract: true,
      templateUrl: 'templates/tabs.html'
    })

  // Each tab has its own nav history stack:

    .state('tab.dash', {
      url: '/dash',
      views: {
        'tab-dash': {
          templateUrl: 'templates/tab-dash.html',
          controller: 'DashCtrl'
        }
      }
    })
    .state('tab.articles', {
      url: '/articles?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-articles.html'
        }
      }
    })
    .state('tab.article', {
      url: '/article/:articleId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/article-detail.html',
          controller: 'ArticleDetailCtrl'
        }
      }
    })
    .state('tab.boards', {
      url: '/boards?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-boards.html'
        }
      }
    })
    .state('tab.board', {
      url: '/board/:boardId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/board-detail.html',
          controller: 'BoardDetailCtrl'
        }
      }
    })
    .state('tab.events', {
      url: '/events?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-events.html'
        }
      }
    })
    .state('tab.event', {
      url: '/event/:eventId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/event-detail.html',
          controller: 'EventDetailCtrl'
        }
      }
    })
    .state('tab.appliances', {
      url: '/appliances?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-hardware.html'
        }
      }
    })
    .state('tab.appliance', {
      url: '/appliance/:applianceId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/hardware-detail.html',
          controller: 'HardwareDetailCtrl'
        }
      }
    })
    .state('tab.members', {
      url: '/members?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-members.html'
        }
      }
    })
    .state('tab.member', {
      url: '/member/:memberId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/member-detail.html',
          controller: 'MemberDetailCtrl'
        }
      }
    })
    .state('tab.networks', {
      url: '/networks',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-network.html',
          controller: 'NetworksCtrl'
        }
      }
    })
    .state('tab.network', {
      url: '/network/:networkId',
      views: {
        'tab-networks': {
          templateUrl: 'templates/network-detail.html',
          controller: 'NetworkDetailCtrl'
        }
      }
    })
    .state('tab.chats', {
      url: '/chats',
      views: {
        'tab-chats': {
          templateUrl: 'templates/tab-chats.html',
          controller: 'ChatsCtrl'
        }
      }
    })
    .state('tab.chat-detail', {
      url: '/chats/:chatId',
      views: {
        'tab-chats': {
          templateUrl: 'templates/chat-detail.html',
          controller: 'ChatDetailCtrl'
        }
      }
    })
    .state('tab.search', {
      url: '/search',
      views: {
        'tab-search': {
          templateUrl: 'templates/tab-search.html',
          controller: 'SearchCtrl'
        }
      }
    })
    .state('tab.account', {
      url: '/account',
      views: {
        'tab-account': {
          templateUrl: 'templates/tab-account.html',
          controller: 'AccountCtrl'
        }
      }
    })
    .state('offline', {
      url: '/offline',
      templateUrl: 'templates/offline.html',
      controller: 'OfflineCtrl'
    });

  // if none of the above states are matched, use this as the fallback
  $urlRouterProvider.otherwise('/tab/dash');

});
<commit_msg>Final working commit in Android<commit_after>// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js

function mahrioRun ($rootScope, $state, $ionicPlatform, localStorageService) {

  $ionicPlatform.ready(function(){
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    console.log("ionicPlatform is ready");
    if(window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
      cordova.plugins.Keyboard.disableScroll(true);

    }

    if (window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }

    if(window.analytics != undefined) {
      console.log("windows.analytics loading...");
      window.analytics.startTrackerWithId('UA-YOURCODEHERE');
      window.analytics.trackView('Testing')
    } else {
      console.log("window.analytics is undefined");
    }
  });
}

mahrioRun.$inject=['$rootScope', '$state', '$ionicPlatform'];

angular.module('starter', [
  'ionic',
  'starter.controllers',
  'starter.services',
  'starter.directives',
  'angular-underscore'])
  .constant('APP_IP', 'http://192.168.0.4:8042')
  .constant('_', window._)
  .run(mahrioRun)
  .config(function($stateProvider, $urlRouterProvider) {

  // Ionic uses AngularUI Router which uses the concept of states
  // Learn more here: https://github.com/angular-ui/ui-router
  // Set up the various states which the app can be in.
  // Each state's controller can be found in controllers.js
  $stateProvider

  // setup an abstract state for the tabs directive
    .state('tab', {
      url: '/tab',
      abstract: true,
      templateUrl: 'templates/tabs.html'
    })

  // Each tab has its own nav history stack:

    .state('tab.dash', {
      url: '/dash',
      views: {
        'tab-dash': {
          templateUrl: 'templates/tab-dash.html',
          controller: 'DashCtrl'
        }
      }
    })
    .state('tab.articles', {
      url: '/articles?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-articles.html'
        }
      }
    })
    .state('tab.article', {
      url: '/article/:articleId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/article-detail.html',
          controller: 'ArticleDetailCtrl'
        }
      }
    })
    .state('tab.boards', {
      url: '/boards?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-boards.html'
        }
      }
    })
    .state('tab.board', {
      url: '/board/:boardId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/board-detail.html',
          controller: 'BoardDetailCtrl'
        }
      }
    })
    .state('tab.events', {
      url: '/events?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-events.html'
        }
      }
    })
    .state('tab.event', {
      url: '/event/:eventId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/event-detail.html',
          controller: 'EventDetailCtrl'
        }
      }
    })
    .state('tab.appliances', {
      url: '/appliances?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-hardware.html'
        }
      }
    })
    .state('tab.appliance', {
      url: '/appliance/:applianceId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/hardware-detail.html',
          controller: 'HardwareDetailCtrl'
        }
      }
    })
    .state('tab.members', {
      url: '/members?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-members.html'
        }
      }
    })
    .state('tab.member', {
      url: '/member/:memberId?network',
      views: {
        'tab-networks': {
          templateUrl: 'templates/member-detail.html',
          controller: 'MemberDetailCtrl'
        }
      }
    })
    .state('tab.networks', {
      url: '/networks',
      views: {
        'tab-networks': {
          templateUrl: 'templates/tab-network.html',
          controller: 'NetworksCtrl'
        }
      }
    })
    .state('tab.network', {
      url: '/network/:networkId',
      views: {
        'tab-networks': {
          templateUrl: 'templates/network-detail.html',
          controller: 'NetworkDetailCtrl'
        }
      }
    })
    .state('tab.chats', {
      url: '/chats',
      views: {
        'tab-chats': {
          templateUrl: 'templates/tab-chats.html',
          controller: 'ChatsCtrl'
        }
      }
    })
    .state('tab.chat-detail', {
      url: '/chats/:chatId',
      views: {
        'tab-chats': {
          templateUrl: 'templates/chat-detail.html',
          controller: 'ChatDetailCtrl'
        }
      }
    })
    .state('tab.search', {
      url: '/search',
      views: {
        'tab-search': {
          templateUrl: 'templates/tab-search.html',
          controller: 'SearchCtrl'
        }
      }
    })
    .state('tab.account', {
      url: '/account',
      views: {
        'tab-account': {
          templateUrl: 'templates/tab-account.html',
          controller: 'AccountCtrl'
        }
      }
    })
    .state('offline', {
      url: '/offline',
      templateUrl: 'templates/offline.html',
      controller: 'OfflineCtrl'
    });

  // if none of the above states are matched, use this as the fallback
  $urlRouterProvider.otherwise('/tab/dash');

});
<|endoftext|>


<commit_before>/**
 * @description creates a template
 * @author Jan Kaufmann <jan@moldjs.de>
 * @version 0.3.0
 * @example examples/simple_todo/Mold/Main.js#1
 */

Seed({
		name : "Mold.Lib.Template",
		dna : "class",
		test : "Mold.Test.Lib.Template",
		include : [
			{ Builder : "Mold.Lib.VDom.Builder" },
			{ Ajax : "Mold.Lib.Ajax" },
			{ MultiLineString :  "Mold.Lib.MultiLineString" },
			{ Path : "Mold.Lib.Path" },
			{ Promise : "Mold.Lib.Promise" },
			{ Event : "Mold.Lib.Event" }

		],

		browserInclude : [
			//load template components
			"Mold.Lib.VDom.Builder",
			[
				".VDom.Components.MoldEvent",
				".VDom.Components.MoldCaptureForms"
			]
		]
	},
	function(markup, config){

		config = config || {};

		var ajax = new Ajax();
		var _tree = false;
		var _that = this;
		var _parseAsString= config.parseAsString || false;
		var undefined;

		Mold.mixin(this, new Event(this));

		//load the
		var _template = new Promise(function(resolve, reject){
			var data = markup;
			if(typeof markup === "function"){
				data = MultiLineString(markup)
				resolve(data);
				return;
			}

			if(Path.is(markup)){
				ajax
					.get(markup)
					.then(function(data){
						resolve(data);
					})
					.fail(function(error){
						reject(error);
					});
			}else{
				resolve(data);
			}
		});

		var _templateTree = new Promise(function(resolve, reject){
			_template.then(function(data){

				_tree = new Builder(data, { template : _that });

				resolve(_tree);
				_that.trigger("ready");
			})
		});

		/**
		 * @method  _connector
		 * @private
		 * @description collection of methods to bind a model to the template
		 * @type {Object}
		 */
		var _connector = {
			renderTimer : false,
			reRender : function(tree){
				clearTimeout(_connector.renderTimer);
				_connector.renderTimer = setTimeout(function(){
					if(!_parseAsString){
						tree.reRender();
					}else{
						tree.renderString();
					}
					_that.trigger("renderd", { tree : _tree });
				}, 2);

			},
			updateChildren : function(children, data, tree){
				if(Mold.isObject(children)){
					for(var childName in children){
						_connector.updateChild(children[childName], data[childName], tree, childName)
					}
				}else{
					throw new Error("only object implemented in _connector.updateChildren")
				}
			},
			updateChild : function(child, data, tree, name){

				//if blocknode
				if(child.type === 2){
					var blockData = {};
					blockData[name] = (data[name] === undefined) ? data : data[name];
					child.setData(blockData);
				}else{
					child.setData(data);
				}
				_connector.reRender(tree);

			},
			watchObjectProp : function(model, subTree, properties, path, tree, name){

				model.off(path + ".changed");
				model.on(path + ".changed", function(e){

					switch(e.data.type){
						case "update":
							//if subtree is an array update all childnodes
							if(Mold.isArray(subTree)){
								var i = 0, len = subTree.length;
								for(; i < len; i++){
									_connector.updateChild(subTree[i], e.data.object, tree, name);
									_connect(model, subTree[i], properties, path, tree);
								}
							}else if(subTree.children && subTree.children[name]){
								_connector.updateChild(subTree, e.data.object, tree, name);
							}else if(subTree.name === name){
								_connector.updateChild(subTree, e.data.object, tree, name);
							}
							break;
						case "splice":
							if(!e.data.addedCount && e.data.removed.length){
								if(Mold.isArray(subTree)){
									for(var i = 0; i < subTree.length; i++){
										subTree[i].removeListItems(e.data.index, e.data.removed.length);
									}
								}else{
									subTree.removeListItems(e.data.index, e.data.removed.length);
								}

							}

							if(e.data.addedCount){
								var i = e.data.index, len = e.data.index + e.data.addedCount;
								for(; i < len; i++){
									if(Mold.isArray(subTree)){
										for(var y = 0; y < subTree.length; y++){
											subTree[y].changeListItem(i, e.data.object[i]);
										}
									}else{
										subTree.changeListItem(i, e.data.object[i]);
									}
								}

							}
							_connector.reRender(tree);

							break;
						default:
							throw new Error("type " + e.data.type + " for watchObjectProp is not implemented!");
					}

				});
			},
			watchArray : function(model, subTree, properties, path, tree){
				model.off(path + ".changed");
				model.on(path + ".changed", function(e){
					switch(e.data.type){
						case "update":
							if(Mold.isObject(e.data.object)){
								_connector.updateChildren(subTree, e.data.object, tree)
							}else{
								throw new Error("e.data.object is no Object, not Implemented");
							}
							break;
						case "splice":

							break;
						default:
							throw new Error("method " + e.data.type + " for watchArray is not implemented!");
					}
				});
			},
			parseArray : function(model, subTree, properties, path, tree){
				var i = 0, len = subTree.children.length;
				for(; i < len; i++){
					var newPath = path + "." + i;
					_connector.watchArray(model, subTree.children[i], properties[0], newPath, tree)
					_connect(model, subTree.children[i], properties[0], newPath, tree)
				}
			},
			parseObject : function(model, subTree, properties, path, tree){
				for(var prop in properties){

					var newPath = path + "." + prop;

					if(subTree.children){
						if(subTree.children[prop]){
							_connector.watchObjectProp(model, subTree.children[prop], properties[prop], newPath, tree, prop)
						}
					}else{

						_connector.watchObjectProp(model, subTree[prop], properties[prop], newPath, tree, prop)
						//throw new Error("subTree children is not defined, in _connector.parseObject!");
					}
				}
			}
		}

		var _connect = function(model, subTree, properties, path, tree){

			if(Mold.isArray(properties)){
				_connector.parseArray(model, subTree, properties, path, tree);
			}else if(Mold.isObject(properties)){
				_connector.parseObject(model, subTree, properties, path, tree);
			}
		}

		var _forms = {};

		Mold.mixin(_forms, new Event(_forms));

		_forms.setValue = function(name, value){
			this[name] = value;
			this.trigger(name + ".changed", value);
		}

		this.publics = {
			snatch : function(){

			},
			forms : _forms,
			connect : function(model){
				_templateTree.then(function(tree){
					_connect(model, tree.dom, model.getProperties(), "data", tree);
					setTimeout(function(){
						model.triggerUpdate();
					}, 50)

				});
			},

		/**
		 * @method setData
		 * @description set the template data
		 * @param {object} data expects the object data
		 */
			setData : function(data){
				_templateTree.then(function(tree){
					tree.dom.setData(data);
					if(!_parseAsString){
						tree.render();
					}else{
						tree.renderString();
					}
					_that.trigger("renderd", { tree : _tree });
				});
			},
			appendTo : function(element){
				_templateTree.then(function(tree){
					element.appendChild(tree.render())
					_that.trigger("renderd", { tree : _tree });
				})
			},
			getString : function(data){
				return new Promise(function(resolve, reject){
					_templateTree.then(function(tree){
						if(data){
							tree.dom.setData(data);
						}
						resolve(tree.renderString());
						_that.trigger("renderd", { tree : _tree });
					})
				});
			},
			get : _templateTree,
			tree : _templateTree
		}
	}
)<commit_msg>comments added, promise added<commit_after>/**
 * @description creates a template
 * @author Jan Kaufmann <jan@moldjs.de>
 * @version 0.3.0
 * @example examples/simple_todo/Mold/Main.js#1
 */

Seed({
		name : "Mold.Lib.Template",
		dna : "class",
		test : "Mold.Test.Lib.Template",
		include : [
			{ Builder : "Mold.Lib.VDom.Builder" },
			{ Ajax : "Mold.Lib.Ajax" },
			{ MultiLineString :  "Mold.Lib.MultiLineString" },
			{ Path : "Mold.Lib.Path" },
			{ Promise : "Mold.Lib.Promise" },
			{ Event : "Mold.Lib.Event" }

		],

		browserInclude : [
			//load template components
			"Mold.Lib.VDom.Builder",
			[
				".VDom.Components.MoldEvent",
				".VDom.Components.MoldCaptureForms"
			]
		]
	},
	function(markup, config){

		config = config || {};

		var ajax = new Ajax();
		var _tree = false;
		var _that = this;
		var _parseAsString= config.parseAsString || false;
		var undefined;

		Mold.mixin(this, new Event(this));

		//load the
		var _template = new Promise(function(resolve, reject){
			var data = markup;
			if(typeof markup === "function"){
				data = MultiLineString(markup)
				resolve(data);
				return;
			}

			if(Path.is(markup)){
				ajax
					.get(markup)
					.then(function(data){
						resolve(data);
					})
					.fail(function(error){
						reject(error);
					});
			}else{
				resolve(data);
			}
		});

		var _templateTree = new Promise(function(resolve, reject){
			_template.then(function(data){

				_tree = new Builder(data, { template : _that });

				resolve(_tree);
				_that.trigger("ready");
			})
		});

		/**
		 * @method  _connector
		 * @private
		 * @description collection of methods to bind a model to the template
		 * @type {Object}
		 */
		var _connector = {
			renderTimer : false,
			reRender : function(tree){
				clearTimeout(_connector.renderTimer);
				_connector.renderTimer = setTimeout(function(){
					if(!_parseAsString){
						tree.reRender();
					}else{
						tree.renderString();
					}
					_that.trigger("renderd", { tree : _tree });
				}, 2);

			},
			updateChildren : function(children, data, tree){
				if(Mold.isObject(children)){
					for(var childName in children){
						_connector.updateChild(children[childName], data[childName], tree, childName)
					}
				}else{
					throw new Error("only object implemented in _connector.updateChildren")
				}
			},
			updateChild : function(child, data, tree, name){

				//if blocknode
				if(child.type === 2){
					var blockData = {};
					child.setData(data);
				}else{
					child.setData(data);
				}
				_connector.reRender(tree);

			},
			watchObjectProp : function(model, subTree, properties, path, tree, name){

				model.off(path + ".changed");
				model.on(path + ".changed", function(e){

					switch(e.data.type){
						case "update":
							//if subtree is an array update all childnodes
							if(Mold.isArray(subTree)){
								var i = 0, len = subTree.length;
								for(; i < len; i++){
									_connector.updateChild(subTree[i], e.data.object, tree, name);
									_connect(model, subTree[i], properties, path, tree);
								}
							}else if(subTree.children && subTree.children[name]){
								_connector.updateChild(subTree, e.data.object, tree, name);
							}else if(subTree.name === name){
								_connector.updateChild(subTree, e.data.object, tree, name);
							}
							break;
						case "splice":
							if(!e.data.addedCount && e.data.removed.length){
								if(Mold.isArray(subTree)){
									for(var i = 0; i < subTree.length; i++){
										subTree[i].deleteListeItems(e.data.index, e.data.removed.length);
									}
								}else{
									subTree.deleteListeItems(e.data.index, e.data.removed.length);
								}

							}

							if(e.data.addedCount){
								var i = e.data.index, len = e.data.index + e.data.addedCount;
								for(; i < len; i++){
									if(Mold.isArray(subTree)){
										for(var y = 0; y < subTree.length; y++){
											subTree[y].changeListItem(i, e.data.object[i]);
										}
									}else{
										subTree.changeListItem(i, e.data.object[i]);
									}
								}

							}
							_connector.reRender(tree);

							break;
						default:
							throw new Error("type " + e.data.type + " for watchObjectProp is not implemented!");
					}

				});
			},
			watchArray : function(model, subTree, properties, path, tree){
				model.off(path + ".changed");
				model.on(path + ".changed", function(e){
					switch(e.data.type){
						case "update":
							if(Mold.isObject(e.data.object)){
								_connector.updateChildren(subTree, e.data.object, tree)
							}else{
								throw new Error("e.data.object is no Object, not Implemented");
							}
							break;
						case "splice":

							break;
						default:
							throw new Error("method " + e.data.type + " for watchArray is not implemented!");
					}
				});
			},
			parseArray : function(model, subTree, properties, path, tree){
				var i = 0, len = subTree.children.length;
				for(; i < len; i++){
					var newPath = path + "." + i;
					_connector.watchArray(model, subTree.children[i], properties[0], newPath, tree)
					_connect(model, subTree.children[i], properties[0], newPath, tree)
				}
			},
			parseObject : function(model, subTree, properties, path, tree){
				for(var prop in properties){

					var newPath = path + "." + prop;

					if(subTree.children){
						if(subTree.children[prop]){
							_connector.watchObjectProp(model, subTree.children[prop], properties[prop], newPath, tree, prop)
						}
					}else{

						_connector.watchObjectProp(model, subTree[prop], properties[prop], newPath, tree, prop)
						//throw new Error("subTree children is not defined, in _connector.parseObject!");
					}
				}
			}
		}

		var _connect = function(model, subTree, properties, path, tree){

			if(Mold.isArray(properties)){
				_connector.parseArray(model, subTree, properties, path, tree);
			}else if(Mold.isObject(properties)){
				_connector.parseObject(model, subTree, properties, path, tree);
			}
		}

		var _forms = {};

		Mold.mixin(_forms, new Event(_forms));

		_forms.setValue = function(name, value){
			this[name] = value;
			this.trigger(name + ".changed", value);
		}

		this.publics = {

		/**
		 * @object forms
		 * @description an object with the collected forms
		 */
			forms : _forms,

		/**
		 * @method connect
		 * @description connects a model to the template
		 * @param  {Mold.Lib.Model} model
		 * @example Mold/Test/Lib/Template.js#connect
		 */
			connect : function(model){
				_templateTree.then(function(tree){
					_connect(model, tree.dom, model.getProperties(), "data", tree);
					setTimeout(function(){
						model.triggerUpdate();
					}, 50)

				});
			},

		/**
		 * @method setData
		 * @description set the template data
		 * @param {object} data expects the object data
		 * @event renderd triggers the renderd event when the template is rendert
		 * @example Mold/Test/Lib/Template.js#setData
		 * @return {promise} returns a promise
		 */
			setData : function(data){
				return new Promise(function(resolve, reject){
					_templateTree.then(function(tree){
						tree.dom.setData(data);
						if(!_parseAsString){
							tree.render();
						}else{
							tree.renderString();
						}
						resolve(tree);
						_that.trigger("renderd", { tree : _tree });
					});
				})
			},

		/**
		 * @method appendTo
		 * @description appends the template to an element and render the template
		 * @async
		 * @param {element} element the element where the template has to be appended
		 * @event renderd triggers the renderd event when the template is rendert
		 * @example Mold/Test/Lib/Template.js#appendTo
		 * @return {promise} returns a promise
		 */
			appendTo : function(element){
				return new Promise(function(resolve, reject){
					_templateTree.then(function(tree){
						element.appendChild(tree.render());
						resolve(tree);
						_that.trigger("renderd", { tree : _tree });
					})
				})
			},

		/**
		 * @method getString
		 * @description set data to the template and renders the template
		 * @async
		 * @param  {object} data the data has to set
		 * @return {promise} returns a promise
		 */
			getString : function(data){
				return new Promise(function(resolve, reject){
					_templateTree.then(function(tree){
						if(data){
							tree.dom.setData(data);
						}
						resolve(tree.renderString());
						_that.trigger("renderd", { tree : _tree });
					})
				});
			},
			get : _templateTree,
			tree : _templateTree
		}
	}
)<|endoftext|>


<commit_before>'use babel';
/** @jsx etch.dom */

import etch from 'etch';
import { prewalk, postwalk, prefor } from './tree.js';
import { Etch, Tip, Button, toView } from '../util/etch.js';

function clamp (x, min, max) {
  return Math.min(Math.max(x, min), max)
}

function maprange([x1, x2], [y1, y2], x) {
  return (x-x1)/(x2-x1)*(y2-y1)+y1;
}

function dims(tree) {
  [tree.height, tree.width] = [1, 1];
  [tree.top, tree.left] = [0, 0];
  prewalk(tree, (parent) => {
    let left = parent.left;
    parent.children.forEach(ch => {
      ch.width = ch.count / parent.count * parent.width;
      ch.height = maprange([0,1],[1/5,1],ch.count/parent.count)*parent.height;
      ch.left = left;
      ch.top = parent.top + parent.height;
      left += ch.width;
    });
    // Centre align children
    chwidth = parent.children.map(({width})=>width).reduce((a,b)=>a+b, 0);
    parent.children.forEach(ch => ch.left += (parent.width-chwidth)/2);
    return parent;
  });
  // Scale total height to 100%
  let max = postwalk(tree, ({height, children}) =>
    Math.max(height, ...children.map(x=>x+height)));
  prewalk(tree, (node) => {
    node.top /= max;
    node.height /= max;
    return node;
  });
  return tree;
}

class Clickable extends Etch {
  hypot([x1, x2], [y1, y2]) {
    return Math.sqrt(Math.pow(y1-x1,2)+Math.pow(y2-x2,2));
  }
  onclick(e) {
    if (!this.clickStart) return;
    if (this.hypot(this.clickStart, [e.clientX, e.clientY]) < 5)
      this.props.onclick(e);
    this.clickStart = null;
  }
  render() {
    return this.clickStart=[e.clientX,e.clientY]}
                 onclick={e=>this.onclick(e)}
                 onmouseleave={e=>this.clickStart=null}>{
      this.children
    };
  }
}

export class Pannable extends Etch {
  constructor (item, opts) {
    opts = Object.assign({}, {
      zoomstrategy: 'transform',
      minScale: 0.001,
      maxScale: 500
    }, opts)

    super()

    this.item = item
    this.zoomstrategy = opts.zoomstrategy
    this.minScale = opts.minScale
    this.maxScale = opts.maxScale
    this.left = 0
    this.top = 0

    // force update, so readAfterUpdate gets executed
    this.update()
    item.onload = () => this.setInitialScale(item)
  }

  setInitialScale (item) {
    this.initialScale = 1
    if (item.naturalHeight && item.naturalWidth && this.containerRect) {
      // only scale down, not up:
      this.initalScale = Math.min(this.containerRect.width/item.naturalWidth, 1)
    }
    this.update()
  }

  resetAll () {
    this.scale = this.initialScale
    this.left = 0
    this.top = 0
    this.update()
  }

  ondrag({movementX, movementY}) {
    if (!this.dragging) return;

    this.left += movementX
    this.top += movementY
    this.update();
  }

  zoom(e, amount) {
    const zoom = amount || Math.pow(0.99, e.deltaY)

    if (zoom*this.scale > this.maxScale || zoom*this.scale < this.minScale) return

    this.scale *= zoom

    if (this.containerRect) {
      let x, y
      if (amount) {
        x = this.containerRect.width/2
        y = this.containerRect.height/2
      } else {
        x = clamp(e.clientX - this.containerRect.left, 0, this.containerRect.width)
        y = clamp(e.clientY - this.containerRect.top, 0, this.containerRect.height)
      }

      this.left -= x*zoom - x
      this.top -= y*zoom - y
    }
    this.update();
  }

  toolbarView () {
    return

      <Button icon='plus' alt='Zoom In' onclick={() => this.zoom(null, 1.1)}/>
      <Button icon='dash' alt='Zoom Out' onclick={() => this.zoom(null, 0.9)}/>
      <Button icon='screen-normal' alt='Reset Plot' onclick={() => this.resetAll()}/>

  }

  render() {
    if (!this.scale) this.scale = this.initialScale
    const scale = this.scale*100+'%'

    this.toolbar = [this.toolbarView()]

    if (this.item && this.item.toolbar) {
      this.toolbar = this.toolbar.concat(this.item.toolbar)
    }

    let position = {position:'relative', height:'inherit', width:'inherit', transformOrigin: '0px 0px'}

    if (this.zoomstrategy == 'width') {
      position.transform = 'translate('+this.left+'px,'+this.top+'px)'
      position.height = scale
      position.width = scale
    } else if (this.zoomstrategy == 'transform') {
      position.transform = 'translate('+this.left+'px,'+this.top+'px) scale('+this.scale+')'
    }

    return
this.dragging=true}
                onmouseup={e=>this.dragging=false}
                onmouseleave={e=>this.dragging=false}
                onmousemove={e=>this.ondrag(e)}
                onmousewheel={e=>this.zoom(e)}
                ondblclick={e=>this.resetAll()}>

        {toView(this.item)}

;
  }

  readAfterUpdate () {
    this.containerRect =
      this.element.getElementsByClassName('ink-pannable')[0].getBoundingClientRect()
  }

  teardown () {
    if (this.item && this.item.teardown) this.item.teardown()
    etch.update(this)
  }

  build () {
    if (this.item && this.item.build) this.item.build()
    etch.update(this)
  }
}

class NodeView extends Etch {
  render() {
    let {height, width, top, left, onclick, onmouseover, onmouseout} = this.props;
    return <Clickable onclick={onclick}>

</Clickable>;
  }
}

export default class Canopy extends Etch {
  update({data}) {}
  render() {
    let nodes = [];
    prefor(dims(this.props.data), node => nodes.push(<NodeView {...node} />));
    return

      {nodes}

;
  }
}
<commit_msg>fix plot scaling again<commit_after>'use babel';
/** @jsx etch.dom */

import etch from 'etch';
import { prewalk, postwalk, prefor } from './tree.js';
import { Etch, Tip, Button, toView } from '../util/etch.js';

function clamp (x, min, max) {
  return Math.min(Math.max(x, min), max)
}

function maprange([x1, x2], [y1, y2], x) {
  return (x-x1)/(x2-x1)*(y2-y1)+y1;
}

function dims(tree) {
  [tree.height, tree.width] = [1, 1];
  [tree.top, tree.left] = [0, 0];
  prewalk(tree, (parent) => {
    let left = parent.left;
    parent.children.forEach(ch => {
      ch.width = ch.count / parent.count * parent.width;
      ch.height = maprange([0,1],[1/5,1],ch.count/parent.count)*parent.height;
      ch.left = left;
      ch.top = parent.top + parent.height;
      left += ch.width;
    });
    // Centre align children
    chwidth = parent.children.map(({width})=>width).reduce((a,b)=>a+b, 0);
    parent.children.forEach(ch => ch.left += (parent.width-chwidth)/2);
    return parent;
  });
  // Scale total height to 100%
  let max = postwalk(tree, ({height, children}) =>
    Math.max(height, ...children.map(x=>x+height)));
  prewalk(tree, (node) => {
    node.top /= max;
    node.height /= max;
    return node;
  });
  return tree;
}

class Clickable extends Etch {
  hypot([x1, x2], [y1, y2]) {
    return Math.sqrt(Math.pow(y1-x1,2)+Math.pow(y2-x2,2));
  }
  onclick(e) {
    if (!this.clickStart) return;
    if (this.hypot(this.clickStart, [e.clientX, e.clientY]) < 5)
      this.props.onclick(e);
    this.clickStart = null;
  }
  render() {
    return this.clickStart=[e.clientX,e.clientY]}
                 onclick={e=>this.onclick(e)}
                 onmouseleave={e=>this.clickStart=null}>{
      this.children
    };
  }
}

export class Pannable extends Etch {
  constructor (item, opts) {
    opts = Object.assign({}, {
      zoomstrategy: 'transform',
      minScale: 0.001,
      maxScale: 500
    }, opts)

    super()

    this.item = item
    this.zoomstrategy = opts.zoomstrategy
    this.minScale = opts.minScale
    this.maxScale = opts.maxScale
    this.left = 0
    this.top = 0

    // force update, so readAfterUpdate gets executed
    this.update()
    item.onload = () => this.setInitialScale(item)
  }

  setInitialScale (item) {
    this.initialScale = 1
    if (item.naturalHeight && item.naturalWidth && this.containerRect) {
      // only scale down, not up:
      this.initialScale = Math.min(
        this.containerRect.width/item.naturalWidth,
        this.containerRect.height/item.naturalHeight,
        1
      )
    }
    this.update()
  }

  resetAll () {
    this.scale = this.initialScale
    this.left = 0
    this.top = 0
    this.update()
  }

  ondrag({movementX, movementY}) {
    if (!this.dragging) return;

    this.left += movementX
    this.top += movementY
    this.update();
  }

  zoom(e, amount) {
    const zoom = amount || Math.pow(0.99, e.deltaY)

    if (zoom*this.scale > this.maxScale || zoom*this.scale < this.minScale) return

    this.scale *= zoom

    if (this.containerRect) {
      let x, y
      if (amount) {
        x = this.containerRect.width/2
        y = this.containerRect.height/2
      } else {
        x = clamp(e.clientX - this.containerRect.left, 0, this.containerRect.width)
        y = clamp(e.clientY - this.containerRect.top, 0, this.containerRect.height)
      }

      this.left -= x*zoom - x
      this.top -= y*zoom - y
    }
    this.update();
  }

  toolbarView () {
    return

      <Button icon='plus' alt='Zoom In' onclick={() => this.zoom(null, 1.1)}/>
      <Button icon='dash' alt='Zoom Out' onclick={() => this.zoom(null, 0.9)}/>
      <Button icon='screen-normal' alt='Reset Plot' onclick={() => this.resetAll()}/>

  }

  render() {
    if (!this.scale) this.scale = this.initialScale
    const scale = this.scale*100+'%'

    this.toolbar = [this.toolbarView()]

    if (this.item && this.item.toolbar) {
      this.toolbar = this.toolbar.concat(this.item.toolbar)
    }

    let position = {position:'relative', height:'inherit', width:'inherit', transformOrigin: '0px 0px'}

    if (this.zoomstrategy == 'width') {
      position.transform = 'translate('+this.left+'px,'+this.top+'px)'
      position.height = scale
      position.width = scale
    } else if (this.zoomstrategy == 'transform') {
      position.transform = 'translate('+this.left+'px,'+this.top+'px) scale('+this.scale+')'
    }

    return
this.dragging=true}
                onmouseup={e=>this.dragging=false}
                onmouseleave={e=>this.dragging=false}
                onmousemove={e=>this.ondrag(e)}
                onmousewheel={e=>this.zoom(e)}
                ondblclick={e=>this.resetAll()}>

        {toView(this.item)}

;
  }

  readAfterUpdate () {
    this.containerRect =
      this.element.getElementsByClassName('ink-pannable')[0].getBoundingClientRect()
  }

  teardown () {
    if (this.item && this.item.teardown) this.item.teardown()
    etch.update(this)
  }

  build () {
    if (this.item && this.item.build) this.item.build()
    etch.update(this)
  }
}

class NodeView extends Etch {
  render() {
    let {height, width, top, left, onclick, onmouseover, onmouseout} = this.props;
    return <Clickable onclick={onclick}>

</Clickable>;
  }
}

export default class Canopy extends Etch {
  update({data}) {}
  render() {
    let nodes = [];
    prefor(dims(this.props.data), node => nodes.push(<NodeView {...node} />));
    return

      {nodes}

;
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
;(function() {
  'use strict';

  /** Load Node.js modules */
  var fs = require('fs'),
      vm = require('vm');

  /** The minimal license/copyright template */
  var licenseTemplate = [
    '/**',
    ' * @license',
    ' * Lo-Dash <%= VERSION %> lodash.com/license | Underscore.js 1.5.1 underscorejs.org/LICENSE',
    ' */'
  ].join('\n');

  /*--------------------------------------------------------------------------*/

  /**
   * Post-process a given minified Lo-Dash `source`, preparing it for
   * deployment.
   *
   * @param {string} source The source to process.
   * @returns {string} Returns the processed source.
   */
  function postprocess(source) {
    // correct overly aggressive Closure Compiler advanced optimization
    source = source
      .replace(/(document[^&]+&&)\s*(?:\w+|!\d)/, '$1!({toString:0}+"")')
      .replace(/"\t"/g, '"\\t"')
      .replace(/"[^"]*?\\f[^"]*?"/g,
        '" \\t\\x0B\\f\\xa0\\ufeff' +
        '\\n\\r\\u2028\\u2029' +
        '\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000"'
      );

    try {
      var context = vm.createContext({});
      vm.runInContext(source, context);
    } catch(e) { }

    ['forEach', 'forIn', 'forOwn'].forEach(function(methodName) {
      var pairs = /[!=]==\s*([a-zA-Z]+)(?!\()|([a-zA-Z]+)\s*[!=]==/.exec((context._ || {})[methodName]),
          varName = pairs && (pairs[1] || pairs[2]),
          value = (value = varName && RegExp('\\b' + varName + '\\s*=\\s*!([01])\\b').exec(source)) && !+value[1];

      if (typeof value == 'boolean') {
        // replace vars for `false` and `true` with boolean literals
        source = source.replace(RegExp('([!=]==\\s*)' + varName + '\\b(?!\\()|\\b' + varName + '(\\s*[!=]==)', 'g'), function(match, prelude, postlude, at) {
          // avoid replacing local variables with the same name
          return RegExp('\\b' + varName + '\\s*(?:,|=[^=])').test(source.slice(at - 10, at))
            ? match
            : (prelude || '') + value + (postlude || '');
        });
      }
    });

    // replace `!1` and `!0` in expressions with `false` and `true` values
    [/([!=]==)\s*!1\b|(.)!1\s*([!=]==)/g, /([!=]==)\s*!0\b|(.)!0\s*([!=]==)/g].forEach(function(regexp, index) {
      source = source.replace(regexp, function(match, prelude, chr, postlude) {
        return (prelude || chr + (/\w/.test(chr) ? ' ' : '')) + !!index + (postlude || '');
      });
    });

    // flip `typeof` expressions to help optimize Safari and
    // correct the AMD module definition for AMD build optimizers
    // (e.g. from `"number" == typeof x` to `typeof x == "number")
    source = source.replace(/(\w)?("[^"]+")\s*([!=]=)\s*(typeof(?:\s*\([^)]+\)|\s+[.\w]+(?!\[)))/g, function(match, other, type, equality, expression) {
      return (other ? other + ' ' : '') + expression + equality + type;
    });

    // add a space so `define` is detected by the Dojo builder
    source = source.replace(/(.)(define\()/, function(match, prelude, define) {
      return prelude + (/^\S/.test(prelude) ? ' ' : '') +  define;
    });

    // add trailing semicolon
    if (source) {
      source = source.replace(/[\s;]*?(\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)*$/, ';$1');
    }
    // exit early if version snippet isn't found
    var snippet = /VERSION\s*[=:]\s*([\'"])(.*?)\1/.exec(source);
    if (!snippet) {
      return source;
    }
    // remove copyright header
    source = source.replace(/^\/\**[\s\S]+?\*\/\n/, '');

    // add new copyright header
    var version = snippet[2];
    source = licenseTemplate.replace('<%= VERSION %>', version) + '\n;' + source;

    return source;
  }

  /*--------------------------------------------------------------------------*/

  // expose `postprocess`
  if (module != require.main) {
    module.exports = postprocess;
  }
  else {
    // read the Lo-Dash source file from the first argument if the script
    // was invoked directly (e.g. `node post-compile.js source.js`) and write to
    // the same file
    (function() {
      var options = process.argv;
      if (options.length < 3) {
        return;
      }
      var filePath = options[options.length - 1],
          source = fs.readFileSync(filePath, 'utf8');

      fs.writeFileSync(filePath, postprocess(source), 'utf8');
    }());
  }
}());
<commit_msg>Update Underscore version in minified copyright header.<commit_after>#!/usr/bin/env node
;(function() {
  'use strict';

  /** Load Node.js modules */
  var fs = require('fs'),
      vm = require('vm');

  /** The minimal license/copyright template */
  var licenseTemplate = [
    '/**',
    ' * @license',
    ' * Lo-Dash <%= VERSION %> lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE',
    ' */'
  ].join('\n');

  /*--------------------------------------------------------------------------*/

  /**
   * Post-process a given minified Lo-Dash `source`, preparing it for
   * deployment.
   *
   * @param {string} source The source to process.
   * @returns {string} Returns the processed source.
   */
  function postprocess(source) {
    // correct overly aggressive Closure Compiler advanced optimization
    source = source
      .replace(/(document[^&]+&&)\s*(?:\w+|!\d)/, '$1!({toString:0}+"")')
      .replace(/"\t"/g, '"\\t"')
      .replace(/"[^"]*?\\f[^"]*?"/g,
        '" \\t\\x0B\\f\\xa0\\ufeff' +
        '\\n\\r\\u2028\\u2029' +
        '\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000"'
      );

    try {
      var context = vm.createContext({});
      vm.runInContext(source, context);
    } catch(e) { }

    ['forEach', 'forIn', 'forOwn'].forEach(function(methodName) {
      var pairs = /[!=]==\s*([a-zA-Z]+)(?!\()|([a-zA-Z]+)\s*[!=]==/.exec((context._ || {})[methodName]),
          varName = pairs && (pairs[1] || pairs[2]),
          value = (value = varName && RegExp('\\b' + varName + '\\s*=\\s*!([01])\\b').exec(source)) && !+value[1];

      if (typeof value == 'boolean') {
        // replace vars for `false` and `true` with boolean literals
        source = source.replace(RegExp('([!=]==\\s*)' + varName + '\\b(?!\\()|\\b' + varName + '(\\s*[!=]==)', 'g'), function(match, prelude, postlude, at) {
          // avoid replacing local variables with the same name
          return RegExp('\\b' + varName + '\\s*(?:,|=[^=])').test(source.slice(at - 10, at))
            ? match
            : (prelude || '') + value + (postlude || '');
        });
      }
    });

    // replace `!1` and `!0` in expressions with `false` and `true` values
    [/([!=]==)\s*!1\b|(.)!1\s*([!=]==)/g, /([!=]==)\s*!0\b|(.)!0\s*([!=]==)/g].forEach(function(regexp, index) {
      source = source.replace(regexp, function(match, prelude, chr, postlude) {
        return (prelude || chr + (/\w/.test(chr) ? ' ' : '')) + !!index + (postlude || '');
      });
    });

    // flip `typeof` expressions to help optimize Safari and
    // correct the AMD module definition for AMD build optimizers
    // (e.g. from `"number" == typeof x` to `typeof x == "number")
    source = source.replace(/(\w)?("[^"]+")\s*([!=]=)\s*(typeof(?:\s*\([^)]+\)|\s+[.\w]+(?!\[)))/g, function(match, other, type, equality, expression) {
      return (other ? other + ' ' : '') + expression + equality + type;
    });

    // add a space so `define` is detected by the Dojo builder
    source = source.replace(/(.)(define\()/, function(match, prelude, define) {
      return prelude + (/^\S/.test(prelude) ? ' ' : '') +  define;
    });

    // add trailing semicolon
    if (source) {
      source = source.replace(/[\s;]*?(\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)*$/, ';$1');
    }
    // exit early if version snippet isn't found
    var snippet = /VERSION\s*[=:]\s*([\'"])(.*?)\1/.exec(source);
    if (!snippet) {
      return source;
    }
    // remove copyright header
    source = source.replace(/^\/\**[\s\S]+?\*\/\n/, '');

    // add new copyright header
    var version = snippet[2];
    source = licenseTemplate.replace('<%= VERSION %>', version) + '\n;' + source;

    return source;
  }

  /*--------------------------------------------------------------------------*/

  // expose `postprocess`
  if (module != require.main) {
    module.exports = postprocess;
  }
  else {
    // read the Lo-Dash source file from the first argument if the script
    // was invoked directly (e.g. `node post-compile.js source.js`) and write to
    // the same file
    (function() {
      var options = process.argv;
      if (options.length < 3) {
        return;
      }
      var filePath = options[options.length - 1],
          source = fs.readFileSync(filePath, 'utf8');

      fs.writeFileSync(filePath, postprocess(source), 'utf8');
    }());
  }
}());
<|endoftext|>


<commit_before>"use strict";

/**
 * @license
 * Copyright SOAJS All Rights Reserved.
 *
 * Use of this source code is governed by an Apache license that can be
 * found in the LICENSE file at the root of this repository
 */

const get = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);

const colName = "tokens";
const core = require("soajs");
const Mongo = core.mongo;
const {v4: uuidv4} = require('uuid');

let indexing = {};

let build_options = (data) => {
    let options = {
        "skip": 0,
        "limit": 100
    };
    options.sort = {"ts": 1};
    if (data.limit) {
        options.limit = data.limit;
    }
    if (data.start) {
        options.skip = data.start;
    }
    return options;
};

function Token(soajs, localConfig, mongoCore) {
    let __self = this;
    __self.keepConnectionAlive = false;
    if (mongoCore) {
        __self.mongoCore = mongoCore;
        __self.mongoCoreExternal = true;
    }
    if (!__self.mongoCore) {
        __self.mongoCoreExternal = false;
        let tCode = soajs.tenant.code;
        if (soajs.tenant.main && soajs.tenant.main.code) {
            tCode = soajs.tenant.main.code;
        }
        let masterCode = get(["registry", "custom", "urac", "value", "masterCode"], soajs);
        if (masterCode) {
            tCode = masterCode;
        } else {
            let dbCodes = get(["registry", "custom", "urac", "value", "dbCodes"], soajs);
            if (dbCodes) {
                for (let c in dbCodes) {
                    if (dbCodes.hasOwnProperty(c)) {
                        if (dbCodes[c].includes(tCode)) {
                            tCode = c;
                            break;
                        }
                    }
                }
            }
        }
        __self.mongoCore = new Mongo(soajs.meta.tenantDB(soajs.registry.tenantMetaDB, localConfig.serviceName, tCode));

        __self.indexCount = 0;
        __self.counter = 0;
        if (indexing && tCode && !indexing[tCode]) {
            indexing[tCode] = true;

            let indexes = [
                {
                    "col": colName, "i": {
                        'userId': 1,
                        'service': 1,
                        'status': 1
                    }, "o": {unique: true}
                },
                {
                    "col": colName, "i": {
                        'token': 1,
                        'service': 1,
                        'status': 1
                    }, "o": {unique: true}
                }
            ];
            __self.indexCount = indexes.length;
            indexing._len = indexes.length;

            for (let i = 0; i < indexes.length; i++) {
                __self.mongoCore.createIndex(indexes[i].col, indexes[i].i, indexes[i].o, (err, index) => {
                    soajs.log.debug("Index: " + index + " created with error: " + err);
                    __self.counter++;
                });
            }

            soajs.log.debug("Token: Indexes for " + tCode + " Updated!");
        }
    }
}

Token.prototype.updateStatus = function (data, cb) {
    let __self = this;
    if (!data || !data.token || !data.status) {
        let error = new Error("Token: status and token are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {
            'status': data.status
        }
    };
    let condition = {
        'token': data.token
    };
    let extraOptions = {
        'upsert': false,
        'safe': true
    };

    __self.mongoCore.updateOne(colName, condition, s, extraOptions, (err, record) => {
        if (!record || (record && !record.nModified)) {
            let error = new Error("Token: status for token [" + data.token + "] was not update.");
            return cb(error);
        }
        return cb(err, record.nModified);
    });
};

Token.prototype.addInvite = function (data, cb) {
    let __self = this;
    if (!data || !data.email || !data.phone || !data.service || !data.tokenExpiryTTL) {
        let error = new Error("Token: tokenExpiryTTL, email, phone, and what service are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {
            'userId': data.email,
            'email': data.email,
            'phone': data.phone,
            'confirmation': data.confirmation,
            'expires': new Date(new Date().getTime() + data.tokenExpiryTTL),
            'status': 'active',
            'ts': new Date().getTime(),
            'service': data.service,
        }
    };
    if (data.code) {
        s.$set.token = "" + Math.floor(100000 + Math.random() * 900000);
    } else {
        const token = uuidv4();
        s.$set.token = token;
    }
    if (data.firstName) {
        s.$set.firstName = data.firstName;
    }
    if (data.lastName) {
        s.$set.lastName = data.lastName;
    }
    if (data.inviteToken) {
        s.$set.inviteToken = data.inviteToken;
    }

    let condition = {
        'userId': data.email,
        'service': data.service,
        'status': data.status
    };
    let extraOptions = {
        'upsert': true,
        'safe': true
    };
    __self.mongoCore.updateOne(colName, condition, s, extraOptions, (err, record) => {
        if (!record || (record && !(record.nModified || record.upsertedCount))) {
            let error = new Error("Token: token for [" + data.service + "] was not created.");
            return cb(error);
        }
        if (data.code) {
            return cb(err, {'code': s.$set.token, 'ttl': data.tokenExpiryTTL});
        } else {
            return cb(err, {'token': s.$set.token, 'ttl': data.tokenExpiryTTL});
        }
    });
};

Token.prototype.add = function (data, cb) {
    let __self = this;
    if (!data || !data.userId || !data.username || !data.service || !data.tokenExpiryTTL) {
        let error = new Error("Token: tokenExpiryTTL, userId, username, and what service are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {
            'userId': data.userId,
            'username': data.username,
            'expires': new Date(new Date().getTime() + data.tokenExpiryTTL),
            'status': 'active',
            'ts': new Date().getTime(),
            'service': data.service,
        }
    };
    if (data.code) {
        s.$set.token = Math.floor(100000 + Math.random() * 900000);
        s.$set.token = "" + s.$set.token;
    } else {
        const token = uuidv4();
        s.$set.token = token;
    }
    if (data.email) {
        s.$set.email = data.email;
    }

    let condition = {
        'userId': data.userId,
        'service': data.service,
        'status': data.status
    };
    let extraOptions = {
        'upsert': true,
        'safe': true
    };
    __self.mongoCore.updateOne(colName, condition, s, extraOptions, (err, record) => {
        if (!record || (record && !(record.nModified || record.upsertedCount))) {
            let error = new Error("Token: token for [" + data.service + "] was not created.");
            return cb(error);
        }
        if (data.code) {
            return cb(err, {'code': s.$set.token, 'ttl': data.tokenExpiryTTL});
        } else {
            return cb(err, {'token': s.$set.token, 'ttl': data.tokenExpiryTTL});
        }
    });
};

Token.prototype.get = function (data, cb) {
    let __self = this;
    if (!data || !data.token || !(data.service || (data.services && Array.isArray(data.services)))) {
        let error = new Error("Token: token, and what service(s) are required.");
        return cb(error, null);
    }
    let condition = {
        'token': data.token,
        'status': data.status
    };

    //At this point service or services are available
    if (data.service) {
        condition.service = data.service;
    } else {
        condition.service = {'$in': data.services};
    }

    __self.mongoCore.findOne(colName, condition, null, (err, record) => {
        return cb(err, record);
    });
};

Token.prototype.list = function (data, cb) {
    let __self = this;

    __self.mongoCore.find(colName, null, null, (err, record) => {
        return cb(err, record);
    });
};

Token.prototype.search = function (data, cb) {
    let __self = this;
    if (!data || !data.service) {
        let error = new Error("Token: service is required.");
        return cb(error, null);
    }
    let options = build_options(data);
    let condition = {
        "service": data.service
    };
    __self.mongoCore.find(colName, condition, options, (error, response) => {
        if (error) {
            return cb(error);
        } else {
            __self.count(data, condition, colName, (error, count) => {
                if (error) {
                    return cb(error);
                } else {
                    return cb(null, {
                        "count": count,
                        "limit": options.limit,
                        "start": options.skip,
                        "items": response
                    });
                }
            });
        }
    });
};

Token.prototype.count = function (data, condition, col, cb) {
    let __self = this;

    let options = {};
    __self.mongoCore.countDocuments(col, condition, options, cb);

};

Token.prototype.closeConnection = function (count) {
    let __self = this;
    count = count || 1;
    if (!__self.mongoCoreExternal) {
        if (__self.mongoCore) {
            if (__self.counter >= __self.indexCount || count > indexing._len) {
                if (!__self.keepConnectionAlive) {
                    __self.mongoCore.closeDb();
                }
            } else {
                count++;
                __self.closeConnection(count);
            }
        }
    }
};

module.exports = Token;<commit_msg>removed unique from token index<commit_after>"use strict";

/**
 * @license
 * Copyright SOAJS All Rights Reserved.
 *
 * Use of this source code is governed by an Apache license that can be
 * found in the LICENSE file at the root of this repository
 */

const get = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);

const colName = "tokens";
const core = require("soajs");
const Mongo = core.mongo;
const {v4: uuidv4} = require('uuid');

let indexing = {};

let build_options = (data) => {
    let options = {
        "skip": 0,
        "limit": 100
    };
    options.sort = {"ts": 1};
    if (data.limit) {
        options.limit = data.limit;
    }
    if (data.start) {
        options.skip = data.start;
    }
    return options;
};

function Token(soajs, localConfig, mongoCore) {
    let __self = this;
    __self.keepConnectionAlive = false;
    if (mongoCore) {
        __self.mongoCore = mongoCore;
        __self.mongoCoreExternal = true;
    }
    if (!__self.mongoCore) {
        __self.mongoCoreExternal = false;
        let tCode = soajs.tenant.code;
        if (soajs.tenant.main && soajs.tenant.main.code) {
            tCode = soajs.tenant.main.code;
        }
        let masterCode = get(["registry", "custom", "urac", "value", "masterCode"], soajs);
        if (masterCode) {
            tCode = masterCode;
        } else {
            let dbCodes = get(["registry", "custom", "urac", "value", "dbCodes"], soajs);
            if (dbCodes) {
                for (let c in dbCodes) {
                    if (dbCodes.hasOwnProperty(c)) {
                        if (dbCodes[c].includes(tCode)) {
                            tCode = c;
                            break;
                        }
                    }
                }
            }
        }
        __self.mongoCore = new Mongo(soajs.meta.tenantDB(soajs.registry.tenantMetaDB, localConfig.serviceName, tCode));

        __self.indexCount = 0;
        __self.counter = 0;
        if (indexing && tCode && !indexing[tCode]) {
            indexing[tCode] = true;

            let indexes = [
                {
                    "col": colName, "i": {
                        'userId': 1,
                        'service': 1,
                        'status': 1
                    }, "o": {}
                },
                {
                    "col": colName, "i": {
                        'token': 1,
                        'service': 1,
                        'status': 1
                    }, "o": {}
                }
            ];
            __self.indexCount = indexes.length;
            indexing._len = indexes.length;

            for (let i = 0; i < indexes.length; i++) {
                __self.mongoCore.createIndex(indexes[i].col, indexes[i].i, indexes[i].o, (err, index) => {
                    soajs.log.debug("Index: " + index + " created with error: " + err);
                    __self.counter++;
                });
            }

            soajs.log.debug("Token: Indexes for " + tCode + " Updated!");
        }
    }
}

Token.prototype.updateStatus = function (data, cb) {
    let __self = this;
    if (!data || !data.token || !data.status) {
        let error = new Error("Token: status and token are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {
            'status': data.status
        }
    };
    let condition = {
        'token': data.token
    };
    let extraOptions = {
        'upsert': false,
        'safe': true
    };

    __self.mongoCore.updateOne(colName, condition, s, extraOptions, (err, record) => {
        if (!record || (record && !record.nModified)) {
            let error = new Error("Token: status for token [" + data.token + "] was not update.");
            return cb(error);
        }
        return cb(err, record.nModified);
    });
};

Token.prototype.addInvite = function (data, cb) {
    let __self = this;
    if (!data || !data.email || !data.phone || !data.service || !data.tokenExpiryTTL) {
        let error = new Error("Token: tokenExpiryTTL, email, phone, and what service are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {
            'userId': data.email,
            'email': data.email,
            'phone': data.phone,
            'confirmation': data.confirmation,
            'expires': new Date(new Date().getTime() + data.tokenExpiryTTL),
            'status': 'active',
            'ts': new Date().getTime(),
            'service': data.service,
        }
    };
    if (data.code) {
        s.$set.token = "" + Math.floor(100000 + Math.random() * 900000);
    } else {
        const token = uuidv4();
        s.$set.token = token;
    }
    if (data.firstName) {
        s.$set.firstName = data.firstName;
    }
    if (data.lastName) {
        s.$set.lastName = data.lastName;
    }
    if (data.inviteToken) {
        s.$set.inviteToken = data.inviteToken;
    }

    let condition = {
        'userId': data.email,
        'service': data.service,
        'status': data.status
    };
    let extraOptions = {
        'upsert': true,
        'safe': true
    };
    __self.mongoCore.updateOne(colName, condition, s, extraOptions, (err, record) => {
        if (!record || (record && !(record.nModified || record.upsertedCount))) {
            let error = new Error("Token: token for [" + data.service + "] was not created.");
            return cb(error);
        }
        if (data.code) {
            return cb(err, {'code': s.$set.token, 'ttl': data.tokenExpiryTTL});
        } else {
            return cb(err, {'token': s.$set.token, 'ttl': data.tokenExpiryTTL});
        }
    });
};

Token.prototype.add = function (data, cb) {
    let __self = this;
    if (!data || !data.userId || !data.username || !data.service || !data.tokenExpiryTTL) {
        let error = new Error("Token: tokenExpiryTTL, userId, username, and what service are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {
            'userId': data.userId,
            'username': data.username,
            'expires': new Date(new Date().getTime() + data.tokenExpiryTTL),
            'status': 'active',
            'ts': new Date().getTime(),
            'service': data.service,
        }
    };
    if (data.code) {
        s.$set.token = Math.floor(100000 + Math.random() * 900000);
        s.$set.token = "" + s.$set.token;
    } else {
        const token = uuidv4();
        s.$set.token = token;
    }
    if (data.email) {
        s.$set.email = data.email;
    }

    let condition = {
        'userId': data.userId,
        'service': data.service,
        'status': data.status
    };
    let extraOptions = {
        'upsert': true,
        'safe': true
    };
    __self.mongoCore.updateOne(colName, condition, s, extraOptions, (err, record) => {
        if (!record || (record && !(record.nModified || record.upsertedCount))) {
            let error = new Error("Token: token for [" + data.service + "] was not created.");
            return cb(error);
        }
        if (data.code) {
            return cb(err, {'code': s.$set.token, 'ttl': data.tokenExpiryTTL});
        } else {
            return cb(err, {'token': s.$set.token, 'ttl': data.tokenExpiryTTL});
        }
    });
};

Token.prototype.get = function (data, cb) {
    let __self = this;
    if (!data || !data.token || !(data.service || (data.services && Array.isArray(data.services)))) {
        let error = new Error("Token: token, and what service(s) are required.");
        return cb(error, null);
    }
    let condition = {
        'token': data.token,
        'status': data.status
    };

    //At this point service or services are available
    if (data.service) {
        condition.service = data.service;
    } else {
        condition.service = {'$in': data.services};
    }

    __self.mongoCore.findOne(colName, condition, null, (err, record) => {
        return cb(err, record);
    });
};

Token.prototype.list = function (data, cb) {
    let __self = this;

    __self.mongoCore.find(colName, null, null, (err, record) => {
        return cb(err, record);
    });
};

Token.prototype.search = function (data, cb) {
    let __self = this;
    if (!data || !data.service) {
        let error = new Error("Token: service is required.");
        return cb(error, null);
    }
    let options = build_options(data);
    let condition = {
        "service": data.service
    };
    __self.mongoCore.find(colName, condition, options, (error, response) => {
        if (error) {
            return cb(error);
        } else {
            __self.count(data, condition, colName, (error, count) => {
                if (error) {
                    return cb(error);
                } else {
                    return cb(null, {
                        "count": count,
                        "limit": options.limit,
                        "start": options.skip,
                        "items": response
                    });
                }
            });
        }
    });
};

Token.prototype.count = function (data, condition, col, cb) {
    let __self = this;

    let options = {};
    __self.mongoCore.countDocuments(col, condition, options, cb);

};

Token.prototype.closeConnection = function (count) {
    let __self = this;
    count = count || 1;
    if (!__self.mongoCoreExternal) {
        if (__self.mongoCore) {
            if (__self.counter >= __self.indexCount || count > indexing._len) {
                if (!__self.keepConnectionAlive) {
                    __self.mongoCore.closeDb();
                }
            } else {
                count++;
                __self.closeConnection(count);
            }
        }
    }
};

module.exports = Token;<|endoftext|>