UNPKG

28

Version:

Command line utility to download and upload 28.io queries.

205 lines (179 loc) 6.79 kB
'use strict'; var fs = require('fs'); var path = require('path'); var _ = require('lodash'); var Q = require('q'); var catSettings = require('cat-settings'); var $28API = require('./28.js').$28; var $28; var Config = (function(){ // Settings var defaultSettings = { 'access_token': '', 'refresh_token': '', 'project_tokens': {}, 'email': '', 'endpoint': 'http://portal.28.io/api', 'projectEndpoint': 'http://<%= projectName %>.28.io/v1', 'ignore': [] }; function Config() {} Config.prototype.load = function(){ this.settingFile = path.join(process.env.HOME || process.env.USERPROFILE || '', '.28.json'); var localSettingFile = process.cwd() + '/.28.json'; if(fs.existsSync(localSettingFile)) { this.settingFile = localSettingFile; } if(!fs.existsSync(this.settingFile)) { fs.writeFileSync(this.settingFile, JSON.stringify(defaultSettings, null, 4)); } this.config = catSettings.loadSync(this.settingFile); _.defaults(this.config, defaultSettings); return this; }; Config.prototype.save = function(session){ if(!this.config){ throw new Error('No config file loaded. Use load()'); } if(session) { if(session.email) { this.config.email = session.email; } this.config.expiration_date = session.expiration_date; this.config.access_token = session.access_token; this.config.refresh_token = session.refresh_token; this.config.project_tokens = session.project_tokens; } this.config.saveSync(this.settingFile); return this; }; Config.prototype.getAPIClient = function(){ if($28 === undefined) { $28 = new $28API(this.config.endpoint); } return $28; }; Config.prototype.getEmail = function(){ return this.config.email; }; Config.prototype.getDefaultProject = function(){ return this.config.default_project; }; Config.prototype.getRefreshToken = function(){ return this.config.refresh_token; }; Config.prototype.getAccessToken = function(){ return this.config.access_token; }; Config.prototype.getProjectToken = function(projectName){ var token = this.config.project_tokens['project_'+projectName]; if(!token) { throw new Error('Project not found: ' + projectName + '. Run "28 projects" to view the list of available projects.'); } return token; }; Config.prototype.getIgnoreList = function(){ return this.config.ignore; }; Config.prototype.filterQuery = function(path) { if(path.substring(path.length - 3) !== '.jq' && path.substring(path.length - 3) !== '.xq') { return false; } else { var matched = false; this.config.ignore.forEach(function(mask){ if(path.match(mask) !== null) { matched = true; return false; } }); if(matched === true) { return false; } return true; } }; Config.prototype.filterQueries = function(aList){ var that = this; var list = _.clone(aList); Object.keys(list).forEach(function(path){ if(!that.filterQuery(path)) { delete list[path]; } }); return list; }; Config.prototype.getAPIEndpoint = function(){ return this.config.endpoint; }; Config.prototype.getProjectEndpoint = function(projectName){ return _.template(this.config.projectEndpoint)({ projectName: projectName }); }; Config.prototype.getProjectList = function(){ return Object.keys(this.config.project_tokens).map(function(project){ return project.substring('project_'.length); }); }; Config.prototype.getProjects = function(){ var that = this; var $28 = this.getAPIClient(); return $28.api.Project.listProjects({ token: that.getAccessToken() }); }; Config.prototype.handleAPIAuthError = function(error){ if(error instanceof Error) { if(error.getCode() === 'ENOTFOUND') { console.error('Couldn\'t connect to API endpoint'.red); } else { throw error; } } console.error('Authentication failed. Server replied:'.red); console.error(error.response.body.red); process.exit(1); }; Config.prototype.handleAPIError = function(error){ if(error instanceof Error) { console.error(error.message.red); console.error((error.fileName + ':' + error.lineNumber).red); console.error(error.stack.toString().red); } else if(error && error.body) { console.error(error.body); } else if(error !== undefined) { console.error(error); } else { console.error('Command exited with errors.'.red); } process.exit(1); }; Config.prototype.refreshTokens = function (projectName) { var $28 = this.getAPIClient(); var that = this; var exp = new Date(this.config.expiration_date).getTime(); var now = new Date().getTime(); if(now + 60 * 60 < exp && projectName && this.config.project_tokens['project_'+projectName]) { return new Q(); } return $28.refreshTokens(this.getEmail(), this.getRefreshToken()).then(function (response) { console.log('Refreshing Tokens...'.grey); var session = response.body; that.save(session); var rem = new Date(session.expiration_date); rem.setHours(rem.getHours() - 12); var now = new Date(); if (Math.abs(now.getTime() - rem.getTime()) > 30 * 1000) { console.error('\nWarning: the local and remote clocks seems to be out of sync.'.yellow); console.error('Be careful if you plan on using synchronization features that rely on the files last modified date time.'.yellow); console.error(('Local time ' + now.toISOString()).yellow); console.error(('Remote time ' + rem.toISOString() + '\n').yellow); } console.log('API Tokens refreshed.'.grey); }) .catch(function (error) { console.error('\nUse the login command again.'.red); that.handleAPIAuthError(error); }); }; return Config; })(); exports.Config = new Config();