<commit_before>var Able = require('./lib/able');

var util = require('util');
var debug = require('debug')('BleAncs');
var events = require('events');

var AblePrimaryService = require('./lib/primary-service.js');
var GenericCharacteristic = require('./generic-characteristic');
var Notification = require('./ancs-notification');

var SERVICE_UUID                = '7905f431b5ce4e99a40f4b1e122d00d0';
var NOTIFICATION_SOURCE_UUID    = '9fbf120d630142d98c5825e699a21dbd';
var CONTROL_POINT_UUID          = '69d1d8f345e149a898219bbdfdaad9d9';
var DATA_SOURCE_UUID            = '22eac6e924d64bb5be44b36ace7c7bfb';

function AttributeRequest(uid, attributeId) {
  this.uid = uid;
  this.attributeId = attributeId;
};

function BleAncs() {
	this._able = new Able();

	this._characteristics = {};
	this._notifications = {};
	this._lastUid = null;
  this._requestQueue = [];
  this._requestTimeout = null;
  this._pendingRequest = false;

	this._able.on('stateChange', this.onStateChange.bind(this));
	this._able.on('accept', this.onAccept.bind(this));
	this._able.on('mtuChange', this.onMtuChange.bind(this));
	this._able.on('advertisingStart', this.onAdvertisingStart.bind(this));
	this._able.on('encryptChange', this.onEncryptChange.bind(this));
	this._able.on('encryptFail', this.onEncryptFail.bind(this));
	this._able.on('connect', this.onConnect.bind(this));
	this._able.on('disconnect', this.onDisconnect.bind(this));
};

util.inherits(BleAncs, events.EventEmitter);

BleAncs.prototype.discoverServicesAndCharacteristics = function(callback) {
  this._peripheral.findServiceAndCharacteristics(SERVICE_UUID, [], function(error, services, characteristics) {
    for (var i in characteristics) {
/*      console.log("CHARECTERISTIC: "+characteristics[i]);
      if (characteristics[i].uuid == NOTIFICATION_SOURCE_UUID) {
        console.log("NOTIFICATION_SOURCE_UUID");
      }
     if (characteristics[i].uuid == DATA_SOURCE_UUID) {
        console.log("DATA_SOURCE_UUID");
      }*/
      this._characteristics[characteristics[i].uuid] = characteristics[i];
    }

    this._characteristics[NOTIFICATION_SOURCE_UUID].on('read', this.onNotification.bind(this));
    this._characteristics[DATA_SOURCE_UUID].on('read', this.onData.bind(this));

    this._characteristics[NOTIFICATION_SOURCE_UUID].notify(true);
    this._characteristics[DATA_SOURCE_UUID].notify(true);

    callback();
  }.bind(this));
};

BleAncs.prototype.onNotification = function(data) {
  var notification = new Notification(this, data);

  if (notification.event == 'removed') {
    debug('Notification Removed: ' + notification);
  } else if (notification.event == 'added') {
    debug('Notification Added: ' + notification);
  } else if (notification.event == 'added') {
    debug('Notification Modified: ' + notification);
  }

  if (notification.uid in this._notifications) {

    if (notification.event != 'added') {
      var old_notification = this._notifications[notification.uid];

      notification.versions = old_notification.versions;
      old_notification.versions = undefined;
      notification.versions.push(old_notification);
      this._notifications[notification.uid] = notification;
    }
  } else {
    this._notifications[notification.uid] = notification;
  }

  this.emit('notification', notification);

};

BleAncs.prototype.onData = function(data) {
  var commandId = data.readUInt8(0);

  if (commandId === 0x00) {
    var uid = data.readUInt32LE(1);
    var notificationData = data.slice(5);

    this._lastUid = uid;

    this._notifications[uid].emit('data', notificationData);
  } else {
    if (this._lastUid) {
      this._notifications[this._lastUid].emit('data',data);
    }
  }
  clearTimeout(this._requestTimeout);
  this._pendingRequest = false;
  this.unqueueAttributeRequest();
};

BleAncs.prototype.requestNotificationAttribute = function(uid, attributeId, maxLength) {
  var buffer = new Buffer(maxLength ? 8 : 6);

  buffer.writeUInt8(0x00, 0);
  buffer.writeUInt32LE(uid, 1);
  buffer.writeUInt8(attributeId, 5);
  if (maxLength) {
    buffer.writeUInt16LE(maxLength, 6);
  }

  this._characteristics[CONTROL_POINT_UUID].write(buffer, false);
};

BleAncs.prototype.unqueueAttributeRequest = function() {
  var request = this._requestQueue.shift();
  console.log("Unqueing req, length: " + this._requestQueue.length);

  if (request) {
    this._pendingRequest = true;
    if ((request.attributeId == 0) || (request.attributeId == 4) || (request.attributeId == 5)) {
      this.requestNotificationAttribute(request.uid, request.attributeId);
    } else {
      this.requestNotificationAttribute(request.uid, request.attributeId, 255);
    }
    this._requestTimeout = setTimeout(this.unqueueAttributeRequest,1000000);
  }

};

BleAncs.prototype.queueAttributeRequest = function(uid,attributeId) {

    console.log("Adding to the queue: " + uid + " attributeId: " + attributeId + " queue: " + this._requestQueue.length);
    var request = new AttributeRequest(uid, attributeId);
    this._requestQueue.push(request);
    this._requestTimeout = setTimeout(this.unqueueAttributeRequest,1000000);
  if (this._pendingRequest == false ) {
    this.unqueueAttributeRequest();
  }

};

BleAncs.prototype.onStateChange = function(state) {
  console.log('on -> stateChange: ' + state);

  if (state === 'poweredOn') {
    if (this._able.startAdvertisingWithEIRData) {
      /*var ad = new Buffer([
        // flags
        0x02, 0x01, 0x02,

        // ANCS solicitation
        0x11, 0x15, 0xd0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F,
        0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79
      ]);*/

     var ad = new Buffer([
        // flags
        0x02, 0x01, 0x05,

        //device name
        0x0a, 0x09, 0x41, 0x4e, 0x42, 0x52, 0x21, 0x54, 0x75, 0x73, 0x6b,

        // Appearence
        0x03, 0x19, 0x40, 0x02

        ]);

      //var scan = new Buffer([0x05, 0x08, 0x74, 0x65, 0x73, 0x74]); // name
      var scan = new Buffer([0x11, 0x15, 0xd0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F,
        0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79]);
      this._able.startAdvertisingWithEIRData(ad, scan);
    } else {
      this._able.startAdvertising('ancs-test', ['7905f431b5ce4e99a40f4b1e122d00d0']);
    }

  } else {
    this._able.stopAdvertising();
  }
};

BleAncs.prototype.onAccept = function(peripheral) {

   console.log('on -> accept: ' );
	  this._peripheral = peripheral;

  	this.uuid = peripheral.uuid;

  	this._peripheral.on('disconnect', this.onDisconnect.bind(this));
};

BleAncs.prototype.onAdvertisingStart = function(error) {

  console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'));

    this._able.setServices(  [    new AblePrimaryService({
        uuid: '13333333333333333333333333333337',            //'7905f431b5ce4e99a40f4b1e122d00d0',
        characteristics: [new GenericCharacteristic()]
      })
    ]);
};

BleAncs.prototype.onMtuChange = function() {

};

BleAncs.prototype.onEncryptChange = function() {
  console.log("able encryptChange!!!");
      this.discoverServicesAndCharacteristics(function() {
    });
};

BleAncs.prototype.onEncryptFail = function() {
  console.log("able -> encryptFail");
};

BleAncs.prototype.onConnect = function() {
    console.log('able -> connect');
};

BleAncs.prototype.onDisconnect = function() {
  console.log('Got a disconnect');

  this.emit('disconnect');
};

module.exports = BleAncs;
<commit_msg>try again<commit_after>var Able = require('./lib/able');

var util = require('util');
var debug = require('debug')('BleAncs');
var events = require('events');

var AblePrimaryService = require('./lib/primary-service.js');
var GenericCharacteristic = require('./generic-characteristic');
var Notification = require('./ancs-notification');

var SERVICE_UUID                = '7905f431b5ce4e99a40f4b1e122d00d0';
var NOTIFICATION_SOURCE_UUID    = '9fbf120d630142d98c5825e699a21dbd';
var CONTROL_POINT_UUID          = '69d1d8f345e149a898219bbdfdaad9d9';
var DATA_SOURCE_UUID            = '22eac6e924d64bb5be44b36ace7c7bfb';

function AttributeRequest(uid, attributeId) {
  this.uid = uid;
  this.attributeId = attributeId;
};

function BleAncs() {
	this._able = new Able();

	this._characteristics = {};
	this._notifications = {};
	this._lastUid = null;
  this._requestQueue = [];
  this._requestTimeout = null;
  this._pendingRequest = false;

	this._able.on('stateChange', this.onStateChange.bind(this));
	this._able.on('accept', this.onAccept.bind(this));
	this._able.on('mtuChange', this.onMtuChange.bind(this));
	this._able.on('advertisingStart', this.onAdvertisingStart.bind(this));
	this._able.on('encryptChange', this.onEncryptChange.bind(this));
	this._able.on('encryptFail', this.onEncryptFail.bind(this));
	this._able.on('connect', this.onConnect.bind(this));
	this._able.on('disconnect', this.onDisconnect.bind(this));
};

util.inherits(BleAncs, events.EventEmitter);

BleAncs.prototype.discoverServicesAndCharacteristics = function(callback) {
  this._peripheral.findServiceAndCharacteristics(SERVICE_UUID, [], function(error, services, characteristics) {
    for (var i in characteristics) {
/*      console.log("CHARECTERISTIC: "+characteristics[i]);
      if (characteristics[i].uuid == NOTIFICATION_SOURCE_UUID) {
        console.log("NOTIFICATION_SOURCE_UUID");
      }
     if (characteristics[i].uuid == DATA_SOURCE_UUID) {
        console.log("DATA_SOURCE_UUID");
      }*/
      this._characteristics[characteristics[i].uuid] = characteristics[i];
    }

    this._characteristics[NOTIFICATION_SOURCE_UUID].on('read', this.onNotification.bind(this));
    this._characteristics[DATA_SOURCE_UUID].on('read', this.onData.bind(this));

    this._characteristics[NOTIFICATION_SOURCE_UUID].notify(true);
    this._characteristics[DATA_SOURCE_UUID].notify(true);

    callback();
  }.bind(this));
};

BleAncs.prototype.onNotification = function(data) {
  var notification = new Notification(this, data);

  if (notification.event == 'removed') {
    debug('Notification Removed: ' + notification);
  } else if (notification.event == 'added') {
    debug('Notification Added: ' + notification);
  } else if (notification.event == 'added') {
    debug('Notification Modified: ' + notification);
  }

  if (notification.uid in this._notifications) {

    if (notification.event != 'added') {
      var old_notification = this._notifications[notification.uid];

      notification.versions = old_notification.versions;
      old_notification.versions = undefined;
      notification.versions.push(old_notification);
      this._notifications[notification.uid] = notification;
    }
  } else {
    this._notifications[notification.uid] = notification;
  }

  this.emit('notification', notification);

};

BleAncs.prototype.onData = function(data) {
  var commandId = data.readUInt8(0);

  if (commandId === 0x00) {
    var uid = data.readUInt32LE(1);
    var notificationData = data.slice(5);

    this._lastUid = uid;

    this._notifications[uid].emit('data', notificationData);
  } else {
    if (this._lastUid) {
      this._notifications[this._lastUid].emit('data',data);
    }
  }
  clearTimeout(this._requestTimeout);
  this._pendingRequest = false;
  this.unqueueAttributeRequest();
};

BleAncs.prototype.requestNotificationAttribute = function(uid, attributeId, maxLength) {
  var buffer = new Buffer(maxLength ? 8 : 6);

  buffer.writeUInt8(0x00, 0);
  buffer.writeUInt32LE(uid, 1);
  buffer.writeUInt8(attributeId, 5);
  if (maxLength) {
    buffer.writeUInt16LE(maxLength, 6);
  }

  this._characteristics[CONTROL_POINT_UUID].write(buffer, false);
};

BleAncs.prototype.unqueueAttributeRequest = function() {
  if (this._requestQueue.length) {
    var request = this._requestQueue.shift();
    console.log("Unqueing req, length: " + this._requestQueue.length);

    if (request) {
      this._pendingRequest = true;
      if ((request.attributeId == 0) || (request.attributeId == 4) || (request.attributeId == 5)) {
        this.requestNotificationAttribute(request.uid, request.attributeId);
      } else {
        this.requestNotificationAttribute(request.uid, request.attributeId, 255);
      }
      this._requestTimeout = setTimeout(this.unqueueAttributeRequest,1000000);
    }
  }
};

BleAncs.prototype.queueAttributeRequest = function(uid,attributeId) {

    console.log("Adding to the queue: " + uid + " attributeId: " + attributeId + " queue: " + this._requestQueue.length);
    var request = new AttributeRequest(uid, attributeId);
    this._requestQueue.push(request);
    this._requestTimeout = setTimeout(this.unqueueAttributeRequest,1000000);
  if (this._pendingRequest == false ) {
    this.unqueueAttributeRequest();
  }

};

BleAncs.prototype.onStateChange = function(state) {
  console.log('on -> stateChange: ' + state);

  if (state === 'poweredOn') {
    if (this._able.startAdvertisingWithEIRData) {
      /*var ad = new Buffer([
        // flags
        0x02, 0x01, 0x02,

        // ANCS solicitation
        0x11, 0x15, 0xd0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F,
        0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79
      ]);*/

     var ad = new Buffer([
        // flags
        0x02, 0x01, 0x05,

        //device name
        0x0a, 0x09, 0x41, 0x4e, 0x42, 0x52, 0x21, 0x54, 0x75, 0x73, 0x6b,

        // Appearence
        0x03, 0x19, 0x40, 0x02

        ]);

      //var scan = new Buffer([0x05, 0x08, 0x74, 0x65, 0x73, 0x74]); // name
      var scan = new Buffer([0x11, 0x15, 0xd0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F,
        0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79]);
      this._able.startAdvertisingWithEIRData(ad, scan);
    } else {
      this._able.startAdvertising('ancs-test', ['7905f431b5ce4e99a40f4b1e122d00d0']);
    }

  } else {
    this._able.stopAdvertising();
  }
};

BleAncs.prototype.onAccept = function(peripheral) {

   console.log('on -> accept: ' );
	  this._peripheral = peripheral;

  	this.uuid = peripheral.uuid;

  	this._peripheral.on('disconnect', this.onDisconnect.bind(this));
};

BleAncs.prototype.onAdvertisingStart = function(error) {

  console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'));

    this._able.setServices(  [    new AblePrimaryService({
        uuid: '13333333333333333333333333333337',            //'7905f431b5ce4e99a40f4b1e122d00d0',
        characteristics: [new GenericCharacteristic()]
      })
    ]);
};

BleAncs.prototype.onMtuChange = function() {

};

BleAncs.prototype.onEncryptChange = function() {
  console.log("able encryptChange!!!");
      this.discoverServicesAndCharacteristics(function() {
    });
};

BleAncs.prototype.onEncryptFail = function() {
  console.log("able -> encryptFail");
};

BleAncs.prototype.onConnect = function() {
    console.log('able -> connect');
};

BleAncs.prototype.onDisconnect = function() {
  console.log('Got a disconnect');

  this.emit('disconnect');
};

module.exports = BleAncs;
<|endoftext|>


<commit_before>'use strict'

function build (schema) {
  /*eslint no-new-func: "off"*/
  var code = `
    'use strict'

    ${$asString.toString()}
    ${$asStringSmall.toString()}
    ${$asStringLong.toString()}
    ${$asNumber.toString()}
    ${$asNull.toString()}
    ${$asBoolean.toString()}
    ${$asRegExp.toString()}
  `
  var main

  switch (schema.type) {
    case 'object':
      main = '$main'
      code = buildObject(schema, code, main)
      break
    case 'string':
      main = $asString.name
      break
    case 'integer':
    case 'number':
      main = $asNumber.name
      break
    case 'boolean':
      main = $asBoolean.name
      break
    case 'null':
      main = $asNull.name
      break
    case 'array':
      main = '$main'
      code = buildArray(schema, code, main)
      break
    default:
      throw new Error(`${schema.type} unsupported`)
  }

  code += `
    ;
    return ${main}
  `

  return (new Function(code))()
}

function $asNull () {
  return 'null'
}

function $asNumber (i) {
  var num = Number(i)
  if (isNaN(num)) {
    return 'null'
  } else {
    return '' + i
  }
}

function $asBoolean (bool) {
  return bool && 'true' || 'false'
}

function $asString (str) {
  if (str instanceof Date) {
    return '"' + str.toISOString() + '"'
  } else if (str instanceof RegExp) {
    return $asRegExp(str)
  } else if (typeof str !== 'string') {
    str = str.toString()
  }

  if (str.length < 42) {
    return $asStringSmall(str)
  } else {
    return $asStringLong(str)
  }
}

function $asStringLong (str) {
  var result = ''
  var l = str.length
  var i

  for (;(i = str.indexOf('"')) >= 0 && i < l;) {
    result += str.slice(0, i) + '\\"'
    str = str.slice(i + 1)
    l = str.length
  }

  if (l > 0) {
    result += str
  }

  return '"' + result + '"'
}

function $asStringSmall (str) {
  var result = ''
  var last = 0
  var l = str.length
  for (var i = 0; i < l; i++) {
    if (str[i] === '"') {
      result += str.slice(last, i) + '\\"'
      last = i + 1
    }
  }
  if (last === 0) {
    result = str
  } else {
    result += str.slice(last)
  }
  return '"' + result + '"'
}

function $asRegExp (reg) {
  reg = reg.source

  for (var i = 0, len = reg.length; i < len; i++) {
    if (reg[i] === '\\' || reg[i] === '"') {
      reg = reg.substring(0, i) + '\\' + reg.substring(i++)
      len += 2
    }
  }

  return '"' + reg + '"'
}

function buildObject (schema, code, name) {
  code += `
    function ${name} (obj) {
      var json = '{'
  `

  var laterCode = ''

  Object.keys(schema.properties).forEach((key, i, a) => {
    // Using obj.key !== undefined instead of obj.hasOwnProperty(prop) for perf reasons,
    // see https://github.com/mcollina/fast-json-stringify/pull/3 for discussion.
    code += `
      if (obj.${key} !== undefined) {
        json += '${$asString(key)}:'
      `

    const result = nested(laterCode, name, '.' + key, schema.properties[key])

    code += result.code
    laterCode = result.laterCode

    if (i < a.length - 1) {
      code += `
        json += \',\'
      `
    }

    if (schema.required && schema.required.indexOf(key) !== -1) {
      code += `
      } else {
        throw new Error('${key} is required!')
      `
    }

    code += `
      }
    `
  })

  code += `
      json += '}'
      return json
    }
  `

  code += laterCode

  return code
}

function buildArray (schema, code, name) {
  code += `
    function ${name} (obj) {
      var json = '['
  `

  var laterCode = ''

  const result = nested(laterCode, name, '[i]', schema.items)

  code += `
    const l = obj.length
    const w = l - 1
    for (var i = 0; i < l; i++) {
      ${result.code}
      if (i < w) {
        json += ','
      }
    }
  `

  laterCode = result.laterCode

  code += `
      json += ']'
      return json
    }
  `

  code += laterCode

  return code
}

function nested (laterCode, name, key, schema) {
  var code = ''
  var funcName
  const type = schema.type
  switch (type) {
    case 'null':
      code += `
        json += $asNull()
      `
      break
    case 'string':
      code += `
        json += $asString(obj${key})
      `
      break
    case 'number':
    case 'integer':
      code += `
        json += $asNumber(obj${key})
      `
      break
    case 'boolean':
      code += `
        json += $asBoolean(obj${key})
      `
      break
    case 'object':
      funcName = (name + key).replace(/[-.\[\]]/g, '')
      laterCode = buildObject(schema, laterCode, funcName)
      code += `
        json += ${funcName}(obj${key})
      `
      break
    case 'array':
      funcName = (name + key).replace(/[-.\[\]]/g, '')
      laterCode = buildArray(schema, laterCode, funcName)
      code += `
        json += ${funcName}(obj${key})
      `
      break
    default:
      throw new Error(`${type} unsupported`)
  }

  return {
    code,
    laterCode
  }
}

module.exports = build
<commit_msg>Added patternProperties support<commit_after>'use strict'

function build (schema) {
  /*eslint no-new-func: "off"*/
  var code = `
    'use strict'
    const properties = ${JSON.stringify(schema.properties)}
    ${$asString.toString()}
    ${$asStringSmall.toString()}
    ${$asStringLong.toString()}
    ${$asNumber.toString()}
    ${$asNull.toString()}
    ${$asBoolean.toString()}
    ${$asRegExp.toString()}
    ${$coerce.toString()}
  `
  var main

  switch (schema.type) {
    case 'object':
      main = '$main'
      code = buildObject(schema, code, main)
      break
    case 'string':
      main = $asString.name
      break
    case 'integer':
    case 'number':
      main = $asNumber.name
      break
    case 'boolean':
      main = $asBoolean.name
      break
    case 'null':
      main = $asNull.name
      break
    case 'array':
      main = '$main'
      code = buildArray(schema, code, main)
      break
    default:
      throw new Error(`${schema.type} unsupported`)
  }

  code += `
    ;
    return ${main}
  `

  return (new Function(code))()
}

function $asNull () {
  return 'null'
}

function $asNumber (i) {
  var num = Number(i)
  if (isNaN(num)) {
    return 'null'
  } else {
    return '' + i
  }
}

function $asBoolean (bool) {
  return bool && 'true' || 'false'
}

function $asString (str) {
  if (str instanceof Date) {
    return '"' + str.toISOString() + '"'
  } else if (str instanceof RegExp) {
    return $asRegExp(str)
  } else if (typeof str !== 'string') {
    str = str.toString()
  }

  if (str.length < 42) {
    return $asStringSmall(str)
  } else {
    return $asStringLong(str)
  }
}

function $asStringLong (str) {
  var result = ''
  var l = str.length
  var i

  for (;(i = str.indexOf('"')) >= 0 && i < l;) {
    result += str.slice(0, i) + '\\"'
    str = str.slice(i + 1)
    l = str.length
  }

  if (l > 0) {
    result += str
  }

  return '"' + result + '"'
}

function $asStringSmall (str) {
  var result = ''
  var last = 0
  var l = str.length
  for (var i = 0; i < l; i++) {
    if (str[i] === '"') {
      result += str.slice(last, i) + '\\"'
      last = i + 1
    }
  }
  if (last === 0) {
    result = str
  } else {
    result += str.slice(last)
  }
  return '"' + result + '"'
}

function $asRegExp (reg) {
  reg = reg.source

  for (var i = 0, len = reg.length; i < len; i++) {
    if (reg[i] === '\\' || reg[i] === '"') {
      reg = reg.substring(0, i) + '\\' + reg.substring(i++)
      len += 2
    }
  }

  return '"' + reg + '"'
}

function $coerce (value, type) {
  if (type === 'string') {
    return String(value)
  } else if (type === 'number') {
    return Number(value)
  } else if (type === 'boolean') {
    return Boolean(value)
  } else if (type === 'object') {
    return {}
  } else if (type === 'array') {
    return []
  } else {
    throw new Error('Cannot coerce ' + value + ' to ' + type)
  }
}

function addPatternProperties (pp) {
  let code = `
      var keys = Object.keys(obj)
      for (var i = 0; i < keys.length; i++) {
        if (properties[keys[i]]) continue
  `
  Object.keys(pp).forEach(regex => {
    var type = pp[regex].type
    if (type === 'integer') type = 'number'
    code += `
        if (/${regex}/.test(keys[i])) {
    `
    if (type === 'object') {
      code += `
          json += $asString(keys[i]) + ':{},'
      `
    } else if (type === 'array') {
      code += `
          json += $asString(keys[i]) + ':[],'
      `
    } else {
      code += `
            json += $asString(keys[i]) + ':' + $as${type[0].toUpperCase() + type.slice(1)}($coerce(obj[keys[i]], '${type}')) + ','
      `
    }
    code += `
        }
    `
  })
  code += `
      }
      if (Object.keys(properties).length === 0) json = json.substring(0, json.length - 1)
  `
  return code
}

function buildObject (schema, code, name) {
  code += `
    function ${name} (obj) {
      var json = '{'
  `
  if (schema.patternProperties) {
    code += addPatternProperties(schema.patternProperties)
  }

  var laterCode = ''

  Object.keys(schema.properties).forEach((key, i, a) => {
    // Using obj.key !== undefined instead of obj.hasOwnProperty(prop) for perf reasons,
    // see https://github.com/mcollina/fast-json-stringify/pull/3 for discussion.
    code += `
      if (obj.${key} !== undefined) {
        json += '${$asString(key)}:'
      `

    const result = nested(laterCode, name, '.' + key, schema.properties[key])

    code += result.code
    laterCode = result.laterCode

    if (i < a.length - 1) {
      code += `
        json += \',\'
      `
    }

    if (schema.required && schema.required.indexOf(key) !== -1) {
      code += `
      } else {
        throw new Error('${key} is required!')
      `
    }

    code += `
      }
    `
  })

  code += `
      json += '}'
      return json
    }
  `

  code += laterCode

  return code
}

function buildArray (schema, code, name) {
  code += `
    function ${name} (obj) {
      var json = '['
  `

  var laterCode = ''

  const result = nested(laterCode, name, '[i]', schema.items)

  code += `
    const l = obj.length
    const w = l - 1
    for (var i = 0; i < l; i++) {
      ${result.code}
      if (i < w) {
        json += ','
      }
    }
  `

  laterCode = result.laterCode

  code += `
      json += ']'
      return json
    }
  `

  code += laterCode

  return code
}

function nested (laterCode, name, key, schema) {
  var code = ''
  var funcName
  const type = schema.type
  switch (type) {
    case 'null':
      code += `
        json += $asNull()
      `
      break
    case 'string':
      code += `
        json += $asString(obj${key})
      `
      break
    case 'number':
    case 'integer':
      code += `
        json += $asNumber(obj${key})
      `
      break
    case 'boolean':
      code += `
        json += $asBoolean(obj${key})
      `
      break
    case 'object':
      funcName = (name + key).replace(/[-.\[\]]/g, '')
      laterCode = buildObject(schema, laterCode, funcName)
      code += `
        json += ${funcName}(obj${key})
      `
      break
    case 'array':
      funcName = (name + key).replace(/[-.\[\]]/g, '')
      laterCode = buildArray(schema, laterCode, funcName)
      code += `
        json += ${funcName}(obj${key})
      `
      break
    default:
      throw new Error(`${type} unsupported`)
  }

  return {
    code,
    laterCode
  }
}

module.exports = build
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var React = require('react');
var dom = React.createElement;
var merge = require('utils-merge');

/**
 * Load the function initializers
 */

var createRenderFn = require('./lib/render-fn');
var createDomFn = require('./lib/dom-fn');
var loadingStatus = require('./lib/loading-status');

/**
 * noop
 */

function noop(a) { return a; }

/**
 * save React types
 */

var PropTypes = React.PropTypes;
var ReactObj = PropTypes.object;
var ReactFunc = PropTypes.func;

/**
 * expose component creation
 */

exports['default'] = exports = module.exports = createComponent;

/**
 * Lifecylce methods
 */

var lifecycle = [
  'componentDidMount',
  'componentWillReceiveProps',
  'shouldComponentUpdate',
  'componentWillUpdate',
  'componentDidUpdate',
  'componentWillUnmount'
];

var nextComponentId = 0;

/**
 * Create an Onus component
 */

function createComponent(conf, filename) {
  // create a mixin with the defined lifecycle events
  var events = {};
  for (var i = 0, event; i < lifecycle.length; i++) {
    event = lifecycle[i];
    if (conf[event]) events[event] = conf[event];
  }

  // load the standard mixins
  var mixins = [
    loadingStatus,
    events
  ].concat(conf.mixins || []);

  var component = {
    displayName: conf.displayName,

    mixins: mixins,

    contextTypes: merge({
      store: ReactObj.isRequired,
      forms: ReactObj,
      translate: ReactObj,
      errorHandler: ReactFunc,
      format: ReactObj,
      events: ReactFunc,
      router: ReactObj
    }, conf.contextTypes),

    __onus_onStoreChange: function(href) {
      var self = this;
      self.isMounted() && self.forceUpdate();
    },

    componentWillMount: function() {
      var self = this;
      var context = self.context;

      var store = self._store = context.store.context(self.__onus_onStoreChange);
      if (context.store.getAsync) self.getAsync = context.store.getAsync.bind(context.store);
      self._t = self._t || context.translate ? context.translate.context(store) : noop;
      if (context.canary) self.canary = context.canary.context(self.__onus_onStoreChange);

      Object.defineProperties(self, {
        forms: {
          get: function() {
            return context.forms;
          }
        },
        router: {
          get: function() {
            return context.router;
          }
        },
        location: {
          get: function() {
            return context.router.location;
          }
        }
      });

      self._error_handler = self._error_handler || context.errorHandler || noop;

      if (module.hot) {
        self.__onusComponentId = nextComponentId++;
        (conf.__subs = conf.__subs || {})[self.__onusComponentId] = function() {
          self.forceUpdate();
        };
      }

      if (conf.componentWillMount) conf.componentWillMount.call(this);
    },

    componentWillUnmount: function() {
      var self = this;
      if (module.hot) delete conf.__subs[self.__onusComponentId];
      self._store.destroy();
      if (self.canary) self.canary.destroy();
    },

    statics: conf.statics,

    _DOM: conf._DOM || createDomFn(conf, dom),

    _yield: conf._yield || _yield,

    _render: conf._render || createRenderFn(conf, dom),

    // TODO
    _error: function(DOM,
      get,
      props,
      state,
      _yield,
      params,
      query,
      forms,
      t,
      err) {
      if (err) console.error(err.stack || err);
      return false;
    },

    equalPairs: function() {
      var a = arguments;
      for (var i = 0; i < a.length; i+=2) {
        if (!this.isEqual(a[i], a[i + 1])) return false;
      }
      return true;
    },

    isEqual: function(a, b) {
      var typeA = typeof a;
      var typeB = typeof b
      // the types have changed
      if (typeA !== typeB) return false;
      // scalars
      if (a === b) return true;
      // defined values
      if (a && b) {
        if (typeof a.__hash !== 'undefined' && typeof b.__hash !== 'undefined') return a.__hash === b.__hash;
        if (typeof a.hashCode === 'function' && typeof b.hashCode === 'function') return a.hashCode() === b.hashCode();
      }
      // TODO add other comparisons
      return false;
    },

    loadedClassName: conf.loadedClassName || 'is-loaded',

    loadingClassName: conf.loadingClassName || 'is-loading',

    componentClassName: conf.componentClassName || conf.displayName + '-component',

    render: function() {
      // TODO see if we can cache this
      // TODO detect any recursive re-renders
      if (process.env.NODE_ENV === 'development') {
        if (typeof window !== 'undefined') {
          onus.renderCounts[conf.displayName] |= 0;
          onus.renderCounts[conf.displayName]++;
          onus.renderTotal++;
        }
      }

      return this._render();
    }
  };

  if (conf.initialState) component.getInitialState = function() {
    var state = {};
    for (var k in conf.initialState) {
      state[k] = conf.initialState[k];
    }
    return state;
  };

  for (var k in conf) {
    if (component[k] || !conf.hasOwnProperty(k) || events[k]) continue;
    component[k] = conf[k];
  }

  return React.createClass(component);
}

if (process.env.NODE_ENV === 'development') {
  if (typeof window !== 'undefined') {
    window.onus = {
      renderCounts: {},
      renderTotal: 0,
      reset: function() {
        onus.renderCounts = {};
        onus.renderTotal = 0;
      }
    };
  }
}

/**
 * Wrap the yield function
 */

function _yield(name, context) {
  var prop = this.props[name || 'children'];
  if (typeof prop !== 'function') return prop;

  var args = Array.prototype.slice.call(arguments, 2);
  return prop.apply(context, args);
}
<commit_msg>add canary back to contextTypes<commit_after>/**
 * Module dependencies
 */

var React = require('react');
var dom = React.createElement;
var merge = require('utils-merge');

/**
 * Load the function initializers
 */

var createRenderFn = require('./lib/render-fn');
var createDomFn = require('./lib/dom-fn');
var loadingStatus = require('./lib/loading-status');

/**
 * noop
 */

function noop(a) { return a; }

/**
 * save React types
 */

var PropTypes = React.PropTypes;
var ReactObj = PropTypes.object;
var ReactFunc = PropTypes.func;

/**
 * expose component creation
 */

exports['default'] = exports = module.exports = createComponent;

/**
 * Lifecylce methods
 */

var lifecycle = [
  'componentDidMount',
  'componentWillReceiveProps',
  'shouldComponentUpdate',
  'componentWillUpdate',
  'componentDidUpdate',
  'componentWillUnmount'
];

var nextComponentId = 0;

/**
 * Create an Onus component
 */

function createComponent(conf, filename) {
  // create a mixin with the defined lifecycle events
  var events = {};
  for (var i = 0, event; i < lifecycle.length; i++) {
    event = lifecycle[i];
    if (conf[event]) events[event] = conf[event];
  }

  // load the standard mixins
  var mixins = [
    loadingStatus,
    events
  ].concat(conf.mixins || []);

  var component = {
    displayName: conf.displayName,

    mixins: mixins,

    contextTypes: merge({
      canary: ReactObj,
      errorHandler: ReactFunc,
      events: ReactFunc,
      format: ReactObj,
      forms: ReactObj,
      router: ReactObj,
      store: ReactObj.isRequired,
      translate: ReactObj,
    }, conf.contextTypes),

    __onus_onStoreChange: function(href) {
      var self = this;
      self.isMounted() && self.forceUpdate();
    },

    componentWillMount: function() {
      var self = this;
      var context = self.context;

      var store = self._store = context.store.context(self.__onus_onStoreChange);
      if (context.store.getAsync) self.getAsync = context.store.getAsync.bind(context.store);
      self._t = self._t || context.translate ? context.translate.context(store) : noop;
      if (context.canary) self.canary = context.canary.context(self.__onus_onStoreChange);

      Object.defineProperties(self, {
        forms: {
          get: function() {
            return context.forms;
          }
        },
        router: {
          get: function() {
            return context.router;
          }
        },
        location: {
          get: function() {
            return context.router.location;
          }
        }
      });

      self._error_handler = self._error_handler || context.errorHandler || noop;

      if (module.hot) {
        self.__onusComponentId = nextComponentId++;
        (conf.__subs = conf.__subs || {})[self.__onusComponentId] = function() {
          self.forceUpdate();
        };
      }

      if (conf.componentWillMount) conf.componentWillMount.call(this);
    },

    componentWillUnmount: function() {
      var self = this;
      if (module.hot) delete conf.__subs[self.__onusComponentId];
      self._store.destroy();
      if (self.canary) self.canary.destroy();
    },

    statics: conf.statics,

    _DOM: conf._DOM || createDomFn(conf, dom),

    _yield: conf._yield || _yield,

    _render: conf._render || createRenderFn(conf, dom),

    // TODO
    _error: function(DOM,
      get,
      props,
      state,
      _yield,
      params,
      query,
      forms,
      t,
      err) {
      if (err) console.error(err.stack || err);
      return false;
    },

    equalPairs: function() {
      var a = arguments;
      for (var i = 0; i < a.length; i+=2) {
        if (!this.isEqual(a[i], a[i + 1])) return false;
      }
      return true;
    },

    isEqual: function(a, b) {
      var typeA = typeof a;
      var typeB = typeof b
      // the types have changed
      if (typeA !== typeB) return false;
      // scalars
      if (a === b) return true;
      // defined values
      if (a && b) {
        if (typeof a.__hash !== 'undefined' && typeof b.__hash !== 'undefined') return a.__hash === b.__hash;
        if (typeof a.hashCode === 'function' && typeof b.hashCode === 'function') return a.hashCode() === b.hashCode();
      }
      // TODO add other comparisons
      return false;
    },

    loadedClassName: conf.loadedClassName || 'is-loaded',

    loadingClassName: conf.loadingClassName || 'is-loading',

    componentClassName: conf.componentClassName || conf.displayName + '-component',

    render: function() {
      // TODO see if we can cache this
      // TODO detect any recursive re-renders
      if (process.env.NODE_ENV === 'development') {
        if (typeof window !== 'undefined') {
          onus.renderCounts[conf.displayName] |= 0;
          onus.renderCounts[conf.displayName]++;
          onus.renderTotal++;
        }
      }

      return this._render();
    }
  };

  if (conf.initialState) component.getInitialState = function() {
    var state = {};
    for (var k in conf.initialState) {
      state[k] = conf.initialState[k];
    }
    return state;
  };

  for (var k in conf) {
    if (component[k] || !conf.hasOwnProperty(k) || events[k]) continue;
    component[k] = conf[k];
  }

  return React.createClass(component);
}

if (process.env.NODE_ENV === 'development') {
  if (typeof window !== 'undefined') {
    window.onus = {
      renderCounts: {},
      renderTotal: 0,
      reset: function() {
        onus.renderCounts = {};
        onus.renderTotal = 0;
      }
    };
  }
}

/**
 * Wrap the yield function
 */

function _yield(name, context) {
  var prop = this.props[name || 'children'];
  if (typeof prop !== 'function') return prop;

  var args = Array.prototype.slice.call(arguments, 2);
  return prop.apply(context, args);
}
<|endoftext|>


<commit_before>var lodash = require('lodash');
var util = require('util');
var path = require('path');
var log = require('./lib/log.js')();

function Scaffold (options) {
    if (!(this instanceof Scaffold)) return new Scaffold(options);
    this._options = lodash.merge({}, options);
    this.util = require('./lib/util.js');
}

Scaffold.prototype._roadmap = function (roadmap) {
    var self = this;
    if (!this.isArray(roadmap)) {
        log.warn('roadmap must be a Array.');
        return [];
    }
    var map = {};
    roadmap.forEach(function (raw) {
        if (raw.reg && raw.release) {
            if (!self.isRegExp(raw.reg)) {
                return;
            }
            map[raw.release] = raw.reg;
        }
    });
    return map;
};

Scaffold.prototype.download = function (id, cb) {
    log.notice('will download component id: ' + id);
    if (!id) {
        log.error(new Error('invalid, '));
    }
    var supports = ['github', 'gitlab', 'lights'];
    var type = this._options['type'];
    if (!~supports.indexOf(type)) {
        type = 'lights';
    }
    var request = new (require('./lib/'+type))(this._options);
    log.notice(type + ': download start');
    request.download(id, cb || function(){});
};

Scaffold.prototype.prompt = function (id) {
};

Scaffold.prototype.deliver = function (files, root, to, roadmap) {
    if (!this.isArray(files)) {
        return;
    }
    to = to || '';
    var map = this._roadmap(roadmap);

    function _replaceDefine(match, release) {
            return release.replace(/\$(\d+|&)/g, function (m, $1) {
                var val = match[$1 == '&' ? 0 : $1];
                return typeof val == 'undefined' ? '' : val;
            });
    }

    for (var i = 0, len = files.length; i < len; i++) {
        var file = files[i];
        var release;
        var isMatch = false;
        for (release in map) {
            if (map.hasOwnProperty(release)) {
                var reg = map[release];
                file.replace(root, '').replace(reg, function () {
                    release = _replaceDefine(arguments, release);
                    isMatch = true;
                });
                if (isMatch) break;
            }
        }
        if (!isMatch) {
            release = file.replace(root, '');
        }
        log.notice(path.join(to, release));
        this.util.move(file, path.join(to, release)); //copy
    }
};

lodash.extend(Scaffold.prototype, lodash);

module.exports = Scaffold;<commit_msg>update<commit_after>var lodash = require('lodash');
var util = require('util');
var path = require('path');
var log = require('./lib/log.js')();

function Scaffold (options) {
    if (!(this instanceof Scaffold)) return new Scaffold(options);
    this._options = lodash.merge({}, options);
    this.util = require('./lib/util.js');
}

Scaffold.prototype._roadmap = function (roadmap) {
    var self = this;
    if (!this.isArray(roadmap)) {
        log.warn('roadmap must be a Array.');
        return [];
    }
    var map = {};
    roadmap.forEach(function (raw) {
        if (raw.reg && raw.release) {
            if (!self.isRegExp(raw.reg)) {
                return;
            }
            map[raw.release] = raw.reg;
        }
    });
    return map;
};

Scaffold.prototype.download = function (id, cb) {
    log.notice('will download component id: ' + id);
    if (!id) {
        log.error(new Error('invalid, '));
    }
    var supports = ['github', 'gitlab', 'lights'];
    var type = this._options['type'];
    if (!~supports.indexOf(type)) {
        type = 'lights';
    }
    var request = new (require('./lib/'+type))(this._options);
    log.notice(type + ': download start');
    request.download(id, cb || function(){});
};

Scaffold.prototype.prompt = function (id) {
};

Scaffold.prototype.deliver = function (files, root, to, roadmap) {
    if (!this.isArray(files)) {
        return;
    }
    to = to || '';
    var map = this._roadmap(roadmap);

    function _replaceDefine(match, release) {
            return release.replace(/\$(\d+|&)/g, function (m, $1) {
                var val = match[$1 == '&' ? 0 : $1];
                return typeof val == 'undefined' ? '' : val;
            });
    }

    for (var i = 0, len = files.length; i < len; i++) {
        var file = files[i];
        var release;
        var isMatch = false;
        for (release in map) {
            if (map.hasOwnProperty(release)) {
                var reg = map[release];
                file.replace(root, '').replace(reg, function () {
                    release = _replaceDefine(arguments, release);
                    isMatch = true;
                });
                if (isMatch) break;
            }
        }
        if (!isMatch) {
            release = file.replace(root, '');
        }
        log.notice(path.join(to, release));
        this.util.move(file, path.join(to, release)); //copy
    }
};

lodash.extend(Scaffold.prototype, lodash);

module.exports = Scaffold;<|endoftext|>


<commit_before>'use strict';
import React from 'react';
import {
  StyleSheet,
  Modal,
  Text,
  Dimensions,
  TouchableHighlight,
  PickerIOS,
  TouchableWithoutFeedback,
  Platform,
  Picker,
  View
} from 'react-native';
const PickerItemIOS = PickerIOS.Item;

export default class Select extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      modalVisible: false,
      selectedKey: props.selectedKey
    };
  }

  _setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  _onChange(key) {
    this.setState({selectedKey: key});
    this.props.onChange(key);
  }

  _close() {
    this.setState({modalVisible: false});
  }

  _renderAndroid() {
    const { models, selectedKey, onChange, style, labelStyle, ...other } = this.props;
    let textHeight = 20;
    if(style && style.height) {
      textHeight = style.height;
    } else if(labelStyle && labelStyle.height) {
      textHeight = labelStyle.height;
    } else if(labelStyle && labelStyle.fontSize) {
      textHeight = labelStyle.fontSize;
    } else {

    }
    return (
      <View style={[styles.selectContainer, style]} {...other}>
        <Text style={labelStyle} >
          {models[this.state.selectedKey] ? models[this.state.selectedKey].label : ""}
        </Text>
        <Picker
          selectedValue={this.state.selectedKey ? this.state.selectedKey : ""}
          onValueChange={this._onChange.bind(this)}
          style={[styles.androidPicker, {height: textHeight}]}
        >
          {Object.keys(models).map((key) => (
            <Picker.Item
              key={key}
              value={key}
              label={models[key].label}
            />
          ))}
        </Picker>
      </View>

    );
  }

  _renderIOS() {
    const { models, selectedKey, onChange, style, labelStyle, ...other } = this.props;
    var modalBackgroundStyle = {
      backgroundColor: 'transparent',
    };
    var innerContainerTransparentStyle = null;
    return (
      <View style={[styles.selectContainer, style]} {...other}>
        <Text style={labelStyle} onPress={this._setModalVisible.bind(this, true)}>
          {models[this.state.selectedKey] ? models[this.state.selectedKey].label : ""}
        </Text>
        <Modal
          animated={true}
          transparent={true}
          visible={this.state.modalVisible}
        >
          <TouchableWithoutFeedback onPress={this._setModalVisible.bind(this, false)}>
            <View style={[styles.container, modalBackgroundStyle]}>
              <View style={styles.pickerBar}>
                <Text onPress={this._close.bind(this)}>完成</Text>
              </View>
              <View onStartShouldSetResponder={ (evt) => true }
                    onResponderReject={ (evt) => {} }
                    style={[styles.innerContainer, innerContainerTransparentStyle]}>
                    <PickerIOS selectedValue={this.state.selectedKey}
                               onValueChange={this._onChange.bind(this)}
                               style={styles.pickerIOS}
                    >
                      {Object.keys(models).map((key) => (
                        <PickerItemIOS
                          key={key}
                          value={key}
                          label={models[key].label}
                        />
                      ))}
                    </PickerIOS>
              </View>
            </View>
          </TouchableWithoutFeedback>
        </Modal>
      </View>
    );
  }

  render() {
    return Platform.OS === 'ios' ? this._renderIOS() : this._renderAndroid();
  }

}

Select.propTypes = {
  models: React.PropTypes.object,
  selectedKey: React.PropTypes.string,
  style: React.PropTypes.object,
  labelStyle: React.PropTypes.object,
  onChange: React.PropTypes.func
};

var styles = StyleSheet.create({
  selectContainer: {
    flex: 1,
    alignItems: 'flex-end',
    padding: 0
  },
  container: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  innerContainer: {
    width: Dimensions.get('window').width,
    alignItems: 'center',
    paddingVertical: 0,
    backgroundColor: '#ccc'
  },
  pickerBar: {
    width: Dimensions.get('window').width,
    justifyContent: 'flex-end',
    flexDirection: 'row',
    padding: 7,
    backgroundColor: '#ececec'
  },
  pickerIOS: {
    marginTop: 0,
    width: Dimensions.get('window').width,
  },
  androidLabel: {
    alignSelf: 'center',
    justifyContent: 'center'
  },
  androidPicker: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    opacity: 0
  }
});
<commit_msg>patch for rn 0.27 modal<commit_after>'use strict';
import React from 'react';
import {
  StyleSheet,
  Modal,
  Text,
  Dimensions,
  TouchableHighlight,
  PickerIOS,
  TouchableWithoutFeedback,
  Platform,
  Picker,
  View
} from 'react-native';
const PickerItemIOS = PickerIOS.Item;

export default class Select extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      modalVisible: false,
      selectedKey: props.selectedKey
    };
  }

  _setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  _onChange(key) {
    this.setState({selectedKey: key});
    this.props.onChange(key);
  }

  _close() {
    this.setState({modalVisible: false});
  }

  _renderAndroid() {
    const { models, selectedKey, onChange, style, labelStyle, ...other } = this.props;
    let textHeight = 20;
    if(style && style.height) {
      textHeight = style.height;
    } else if(labelStyle && labelStyle.height) {
      textHeight = labelStyle.height;
    } else if(labelStyle && labelStyle.fontSize) {
      textHeight = labelStyle.fontSize;
    } else {

    }
    return (
      <View style={[styles.selectContainer, style]} {...other}>
        <Text style={labelStyle} >
          {models[this.state.selectedKey] ? models[this.state.selectedKey].label : ""}
        </Text>
        <Picker
          selectedValue={this.state.selectedKey ? this.state.selectedKey : ""}
          onValueChange={this._onChange.bind(this)}
          style={[styles.androidPicker, {height: textHeight}]}
        >
          {Object.keys(models).map((key) => (
            <Picker.Item
              key={key}
              value={key}
              label={models[key].label}
            />
          ))}
        </Picker>
      </View>

    );
  }

  _renderIOS() {
    const { models, selectedKey, onChange, style, labelStyle, ...other } = this.props;
    var modalBackgroundStyle = {
      backgroundColor: 'transparent',
    };
    var innerContainerTransparentStyle = null;
    return (
      <View style={[styles.selectContainer, style]} {...other}>
        <Text style={labelStyle} onPress={this._setModalVisible.bind(this, true)}>
          {models[this.state.selectedKey] ? models[this.state.selectedKey].label : ""}
        </Text>
        <Modal
          animationType="slide"
          transparent={true}
          visible={this.state.modalVisible}
        >
          <TouchableWithoutFeedback onPress={this._setModalVisible.bind(this, false)}>
            <View style={[styles.container, modalBackgroundStyle]}>
              <View style={styles.pickerBar}>
                <Text onPress={this._close.bind(this)}>完成</Text>
              </View>
              <View onStartShouldSetResponder={ (evt) => true }
                    onResponderReject={ (evt) => {} }
                    style={[styles.innerContainer, innerContainerTransparentStyle]}>
                    <PickerIOS selectedValue={this.state.selectedKey}
                               onValueChange={this._onChange.bind(this)}
                               style={styles.pickerIOS}
                    >
                      {Object.keys(models).map((key) => (
                        <PickerItemIOS
                          key={key}
                          value={key}
                          label={models[key].label}
                        />
                      ))}
                    </PickerIOS>
              </View>
            </View>
          </TouchableWithoutFeedback>
        </Modal>
      </View>
    );
  }

  render() {
    return Platform.OS === 'ios' ? this._renderIOS() : this._renderAndroid();
  }

}

Select.propTypes = {
  models: React.PropTypes.object,
  selectedKey: React.PropTypes.string,
  style: React.PropTypes.object,
  labelStyle: React.PropTypes.object,
  onChange: React.PropTypes.func
};

var styles = StyleSheet.create({
  selectContainer: {
    flex: 1,
    alignItems: 'flex-end',
    padding: 0
  },
  container: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  innerContainer: {
    width: Dimensions.get('window').width,
    alignItems: 'center',
    paddingVertical: 0,
    backgroundColor: '#ccc'
  },
  pickerBar: {
    width: Dimensions.get('window').width,
    justifyContent: 'flex-end',
    flexDirection: 'row',
    padding: 7,
    backgroundColor: '#ececec'
  },
  pickerIOS: {
    marginTop: 0,
    width: Dimensions.get('window').width,
  },
  androidLabel: {
    alignSelf: 'center',
    justifyContent: 'center'
  },
  androidPicker: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    opacity: 0
  }
});
<|endoftext|>


<commit_before>'use strict';

/**
 * serverless-mocha-plugin
 * - a plugin for TDD with serverless
 */

const path  = require('path'),
  fs        = require('fs'),
  lambdaWrapper = require('lambda-wrapper'),
  Mocha = require('mocha'),
  chai = require('chai'),
  Path = require('path'),
  BbPromise = require('bluebird'); // Serverless uses Bluebird Promises and we recommend you do to because they provide more than your average Promise :)

const testFolder = 'test'; // Folder used my mocha for tests

module.exports = function(S) { // Always pass in the ServerlessPlugin Class

  /**
   * Adding/Manipulating Serverless classes
   * - You can add or manipulate Serverless classes like this
   */

  S.classes.Project.newStaticMethod     = function() { console.log("A new method!"); };
  S.classes.Project.prototype.newMethod = function() { S.classes.Project.newStaticMethod(); };

  /**
   * Extending the Plugin Class
   * - Here is how you can add custom Actions and Hooks to Serverless.
   * - This class is only required if you want to add Actions and Hooks.
   */

  class PluginBoilerplate extends S.classes.Plugin {

    /**
     * Constructor
     * - Keep this and don't touch it unless you know what you're doing.
     */

    constructor() {
      super();
      this.name = 'io.sc5.mocha';
    }

    /**
     * Register Actions
     * - function mocha-create
     */

    registerActions() {

      S.addAction(this._createAction.bind(this), {
        handler:       '_createAction',
        description:   'Create mocha test for function',
        context:       'function',
        contextAction: 'mocha-create',
        options:       [{ // These must be specified in the CLI like this "-option true" or "-o true"
        }],
        parameters: [ // Use paths when you multiple values need to be input (like an array).  Input looks like this: "serverless custom run module1/function1 module1/function2 module1/function3.  Serverless will automatically turn this into an array and attach it to evt.options within your plugin
          {
            parameter: 'paths',
            description: 'Path to function to test. If not defined, test all functions.',
            position: '0->' // Can be: 0, 0-2, 0->  This tells Serverless which params are which.  3-> Means that number and infinite values after it.
          }
        ]
      });

      S.addAction(this._runAction.bind(this), {
        handler:       '_runAction',
        description:   'Create mocha test for function',
        context:       'function',
        contextAction: 'mocha-run',
        options:       [          {
            option:      'region',
            shortcut:    'r',
            description: 'region you want to run your function in'
          },
          {
            option:      'stage',
            shortcut:    's',
            description: 'stage you want to run your function in'
          },
          {
            option:      'reporter',
            shortcut:    'R',
            description: 'specify the reporter to use'
          },
          {
            option:      'reporter-options',
            shortcut:    'O',
            description: 'reporter-specific options'
          }],
        parameters: [ // Use paths when you multiple values need to be input (like an array).  Input looks like this: "serverless custom run module1/function1 module1/function2 module1/function3.  Serverless will automatically turn this into an array and attach it to evt.options within your plugin
          {
            parameter: 'paths',
            description: 'Path to function to test. If not defined, test all functions.',
            position: '0->' // Can be: 0, 0-2, 0->  This tells Serverless which params are which.  3-> Means that number and infinite values after it.
          }
        ]
      });

      return BbPromise.resolve();
    }

    /**
     * Register Hooks
     * -  function create (post) creates mocha test file
     */

    registerHooks() {
      S.addHook(this._hookPostFuncCreate.bind(this), {
        action: 'functionCreate',
        event:  'post'
      });

      return BbPromise.resolve();
    }

    /**
     * Custom action serverless function mocha-create functioName
     */

    _createAction(evt) {
      if (S.getProject().getFunction(evt.options.paths[0]) === undefined) {
        return new BbPromise(function(resolve, reject) {
          reject(`MochaPluginError: Function ${evt.options.paths[0]} does not exist in your project`);
        });
      }

      return createTest(evt.options.paths[0]);
    }

    /**
     * Custom action serverless function mocha-create functioName
     */

    _runAction(evt) {
      return new BbPromise(function(resolve, reject) {
          let funcName = evt.options.paths;
          let mocha = new Mocha();
          //This could pose as an issue if several functions share a common ENV name but different values.

          let stage = evt.options.stage || S.getProject().getAllStages()[0].name;
          let region = evt.options.region || S.getProject().getAllRegions(stage)[0].name;

          SetEnvVars(evt.options.paths, {
            stage: stage,
            region: region
          });

          getFilePaths(evt.options.paths)
          .then(function(paths) {
              paths.forEach(function(path,idx) {
                mocha.addFile(path);
              })
              var reporter = evt.options.reporter;
              if ( reporter !== null) {
                var reporterOptions = {};
                if (evt.options["reporter-options"] !== null) {
                  evt.options["reporter-options"].split(",").forEach(function(opt) {
                    var L = opt.split("=");
                    if (L.length > 2 || L.length === 0) {
                      throw new Error("invalid reporter option '" + opt + "'");
                    } else if (L.length === 2) {
                      reporterOptions[L[0]] = L[1];
                    } else {
                      reporterOptions[L[0]] = true;
                    }
                  });
                }
                mocha.reporter(reporter, reporterOptions)
              }
              mocha.run(function(failures){
                process.on('exit', function () {
                  process.exit(failures);  // exit with non-zero status if there were failures
                });
              });
          }, function(error) {

            return reject(error);
          });
      });
    }
    /**
     * Hook for creating the mocha test placeholder after function creation
     */

    _hookPostFuncCreate(evt) {
      // TODO: only run with runtime node4.3
      if (evt.options.runtime != 'nodejs4.3') {
        console.log(evt.options.runtime);
        return;
      }
      let parsedPath = path.parse(evt.options.path);
      let funcName = parsedPath.base;

      return createTest(funcName);
    }
  }

  //Set environment variables
  function SetEnvVars(paths, config) {
    paths.forEach(function(path, idx){
      var funcName = Path.basename(path, '.js');
      var func = S.getProject().getFunction(funcName).toObjectPopulated(config);
      var envVars = func.environment;
      var fields = Object.keys(envVars);

      for (var key in fields) {
        process.env[fields[key]] = envVars[fields[key]];
      }
    });
  }

  // Create the test folder
  function createTestFolder() {
      return new BbPromise(function(resolve, reject) {

        fs.exists(testFolder, function(exists) {
            if (exists) {
                return resolve(testFolder);
            }
            fs.mkdir(testFolder, function(err) {
                if (err) {
                    return reject(err);
                }
                return resolve(testFolder);
            })
        })
      });
  }

  // Create the test file (and test folder)

  function createTest(funcName) {
    return createTestFolder().then(function(testFolder) {
      return new BbPromise(function(resolve, reject) {
        let funcFilePath = testFilePath(funcName);
        let projectPath = S.getProject().getRootPath();
        let funcFullPath = S.getProject().getFunction(funcName).getRootPath();
        let funcPath = path.relative(projectPath, funcFullPath).replace(/\\/g, "/");

        fs.exists(funcFilePath, function (exists) {
           if (exists) {
               return reject(new Error(`File ${funcFilePath} already exists`));
           }
           fs.writeFile(funcFilePath, newTestFile(funcName, funcPath), function(err) {
               if (err) {
                   return reject(new Error(`Creating file ${funcFilePath} failed: ${err}`));
               }
               console.log(`serverless-mocha-plugin: created ${funcFilePath}`);
               return resolve(funcFilePath);
           })
        });
      });
    });
  }

  // getTestFiles. If no functions provided, returns all files
  function getFilePaths(funcs) {
    return new BbPromise(function(resolve, reject) {
        var paths = [];

        if (funcs && (funcs.length > 0)) {
            funcs.forEach(function(val, idx) {
                paths.push(testFilePath(val));
            });
            return resolve(paths);
        }
        // No funcs provided, list all test files
        fs.readdirSync(testFolder).filter(function(file){
          // Only keep the .js files
          return file.substr(-3) === '.js';
        }).forEach(function(file) {
            paths.push(path.join(testFolder, file));
        });
        return resolve(paths);
    });
  };

  // Returns the path to a function's test file
  function testFilePath(funcName) {
      return path.join(testFolder, `${funcName.replace(/.*\//g, '')}.js`);
  }

  function newTestFile(funcName, funcPath) {
      return `'use strict';
// tests for ${funcName}
// Generated by serverless-mocha-plugin

const mod         = require('../${funcPath}/handler.js');
const mochaPlugin = require('serverless-mocha-plugin');
const wrapper     = mochaPlugin.lambdaWrapper;
const expect      = mochaPlugin.chai.expect;

describe('${funcName}', () => {
  before(function (done) {
    wrapper.init(mod);

    done()
  })

  it('implement tests here', (done) => {
    wrapper.init(mod);
    wrapper.run({}, (err, response) => {
      done('no tests implemented');
    });
  });
});
`;

  }
  // Export Plugin Class
  return PluginBoilerplate;
};

module.exports.lambdaWrapper = lambdaWrapper;
module.exports.chai = chai;
<commit_msg>Fix setting of env vars when running all tests<commit_after>'use strict';

/**
 * serverless-mocha-plugin
 * - a plugin for TDD with serverless
 */

const path  = require('path'),
  fs        = require('fs'),
  lambdaWrapper = require('lambda-wrapper'),
  Mocha = require('mocha'),
  chai = require('chai'),
  Path = require('path'),
  BbPromise = require('bluebird'); // Serverless uses Bluebird Promises and we recommend you do to because they provide more than your average Promise :)

const testFolder = 'test'; // Folder used my mocha for tests

module.exports = function(S) { // Always pass in the ServerlessPlugin Class

  /**
   * Adding/Manipulating Serverless classes
   * - You can add or manipulate Serverless classes like this
   */

  S.classes.Project.newStaticMethod     = function() { console.log("A new method!"); };
  S.classes.Project.prototype.newMethod = function() { S.classes.Project.newStaticMethod(); };

  /**
   * Extending the Plugin Class
   * - Here is how you can add custom Actions and Hooks to Serverless.
   * - This class is only required if you want to add Actions and Hooks.
   */

  class PluginBoilerplate extends S.classes.Plugin {

    /**
     * Constructor
     * - Keep this and don't touch it unless you know what you're doing.
     */

    constructor() {
      super();
      this.name = 'io.sc5.mocha';
    }

    /**
     * Register Actions
     * - function mocha-create
     */

    registerActions() {

      S.addAction(this._createAction.bind(this), {
        handler:       '_createAction',
        description:   'Create mocha test for function',
        context:       'function',
        contextAction: 'mocha-create',
        options:       [{ // These must be specified in the CLI like this "-option true" or "-o true"
        }],
        parameters: [ // Use paths when you multiple values need to be input (like an array).  Input looks like this: "serverless custom run module1/function1 module1/function2 module1/function3.  Serverless will automatically turn this into an array and attach it to evt.options within your plugin
          {
            parameter: 'paths',
            description: 'Path to function to test. If not defined, test all functions.',
            position: '0->' // Can be: 0, 0-2, 0->  This tells Serverless which params are which.  3-> Means that number and infinite values after it.
          }
        ]
      });

      S.addAction(this._runAction.bind(this), {
        handler:       '_runAction',
        description:   'Create mocha test for function',
        context:       'function',
        contextAction: 'mocha-run',
        options:       [          {
            option:      'region',
            shortcut:    'r',
            description: 'region you want to run your function in'
          },
          {
            option:      'stage',
            shortcut:    's',
            description: 'stage you want to run your function in'
          },
          {
            option:      'reporter',
            shortcut:    'R',
            description: 'specify the reporter to use'
          },
          {
            option:      'reporter-options',
            shortcut:    'O',
            description: 'reporter-specific options'
          }],
        parameters: [ // Use paths when you multiple values need to be input (like an array).  Input looks like this: "serverless custom run module1/function1 module1/function2 module1/function3.  Serverless will automatically turn this into an array and attach it to evt.options within your plugin
          {
            parameter: 'paths',
            description: 'Path to function to test. If not defined, test all functions.',
            position: '0->' // Can be: 0, 0-2, 0->  This tells Serverless which params are which.  3-> Means that number and infinite values after it.
          }
        ]
      });

      return BbPromise.resolve();
    }

    /**
     * Register Hooks
     * -  function create (post) creates mocha test file
     */

    registerHooks() {
      S.addHook(this._hookPostFuncCreate.bind(this), {
        action: 'functionCreate',
        event:  'post'
      });

      return BbPromise.resolve();
    }

    /**
     * Custom action serverless function mocha-create functioName
     */

    _createAction(evt) {
      if (S.getProject().getFunction(evt.options.paths[0]) === undefined) {
        return new BbPromise(function(resolve, reject) {
          reject(`MochaPluginError: Function ${evt.options.paths[0]} does not exist in your project`);
        });
      }

      return createTest(evt.options.paths[0]);
    }

    /**
     * Custom action serverless function mocha-create functioName
     */

    _runAction(evt) {
      return new BbPromise(function(resolve, reject) {
          let functions = evt.options.paths;
          let mocha = new Mocha();
          //This could pose as an issue if several functions share a common ENV name but different values.

          let stage = evt.options.stage || S.getProject().getAllStages()[0].name;
          let region = evt.options.region || S.getProject().getAllRegions(stage)[0].name;

          getFunctions(functions)
          .then(getFilePaths)
          .then(function(paths) {
            if (paths.length === 0) {
              return reject('No tests to run.');
            }
            paths.forEach(function(func,idx) {
              SetEnvVars(func, {
                stage: stage,
                region: region
              });
              mocha.addFile(func.mochaPlugin.testPath);
            })
            var reporter = evt.options.reporter;
            if ( reporter !== null) {
              var reporterOptions = {};
              if (evt.options["reporter-options"] !== null) {
                evt.options["reporter-options"].split(",").forEach(function(opt) {
                  var L = opt.split("=");
                  if (L.length > 2 || L.length === 0) {
                    throw new Error("invalid reporter option '" + opt + "'");
                  } else if (L.length === 2) {
                    reporterOptions[L[0]] = L[1];
                  } else {
                    reporterOptions[L[0]] = true;
                  }
                });
              }
              mocha.reporter(reporter, reporterOptions)
            }
            mocha.run(function(failures){
              process.on('exit', function () {
                process.exit(failures);  // exit with non-zero status if there were failures
              });
            });
          }, function(error) {

            return reject(error);
          });
      });
    }
    /**
     * Hook for creating the mocha test placeholder after function creation
     */

    _hookPostFuncCreate(evt) {
      // TODO: only run with runtime node4.3
      if (evt.options.runtime != 'nodejs4.3') {
        return;
      }
      let parsedPath = path.parse(evt.options.path);
      let funcName = parsedPath.base;

      return createTest(funcName);
    }
  }

  //Set environment variables
  function SetEnvVars(func, config) {
    var envVars = func.toObjectPopulated(config);
    var fields = Object.keys(envVars);

    for (var key in fields) {
      process.env[fields[key]] = envVars[fields[key]];
    }
    return process.env;
  }

  // Create the test folder
  function createTestFolder() {
      return new BbPromise(function(resolve, reject) {

        fs.exists(testFolder, function(exists) {
            if (exists) {
                return resolve(testFolder);
            }
            fs.mkdir(testFolder, function(err) {
                if (err) {
                    return reject(err);
                }
                return resolve(testFolder);
            })
        })
      });
  }

  // Create the test file (and test folder)

  function createTest(funcName) {
    return createTestFolder().then(function(testFolder) {
      return new BbPromise(function(resolve, reject) {
        let funcFilePath = testFilePath(funcName);
        let projectPath = S.getProject().getRootPath();
        let funcFullPath = S.getProject().getFunction(funcName).getRootPath();
        let funcPath = path.relative(projectPath, funcFullPath).replace(/\\/g, "/");

        fs.exists(funcFilePath, function (exists) {
           if (exists) {
               return reject(new Error(`File ${funcFilePath} already exists`));
           }
           fs.writeFile(funcFilePath, newTestFile(funcName, funcPath), function(err) {
               if (err) {
                   return reject(new Error(`Creating file ${funcFilePath} failed: ${err}`));
               }
               console.log(`serverless-mocha-plugin: created ${funcFilePath}`);
               return resolve(funcFilePath);
           })
        });
      });
    });
  }

  // getFunctions. If no functions provided, returns all files
  function getFunctions(funcNames) {
    return new BbPromise(function(resolve, reject) {
      let funcObjs = [];
      if (funcNames.length === 0) {
        let sFuncs = S.getProject().getAllFunctions();

        return resolve(sFuncs);
      }

      let func;
      funcNames.forEach(function(funcName, idx) {
        func = S.getProject().getFunction(funcName);
        if (func) {
          funcObjs.push(func);
        } else {
          console.log(`Warning: Could not find function '${funcName}'.`);
        }
      });
      resolve(funcObjs);
    });
  };

  // getTestFiles. If no functions provided, returns all files
  function getFilePaths(funcs) {
   // console.log(funcs);
    return new BbPromise(function(resolve, reject) {
        var paths = [];

        if (funcs && (funcs.length > 0)) {
            funcs.forEach(function(val, idx) {
              val.mochaPlugin = {
                testPath: testFilePath(val.name)
              };
              paths.push(val);
            });
            return resolve(paths);
        }
        return resolve([]);
    });
  };

  // Returns the path to a function's test file
  function testFilePath(funcName) {
      return path.join(testFolder, `${funcName.replace(/.*\//g, '')}.js`);
  }

  function newTestFile(funcName, funcPath) {
      return `'use strict';
// tests for ${funcName}
// Generated by serverless-mocha-plugin

const mod         = require('../${funcPath}/handler.js');
const mochaPlugin = require('serverless-mocha-plugin');
const wrapper     = mochaPlugin.lambdaWrapper;
const expect      = mochaPlugin.chai.expect;

describe('${funcName}', () => {
  before(function (done) {
    wrapper.init(mod);

    done()
  })

  it('implement tests here', (done) => {
    wrapper.init(mod);
    wrapper.run({}, (err, response) => {
      done('no tests implemented');
    });
  });
});
`;

  }
  // Export Plugin Class
  return PluginBoilerplate;
};

module.exports.lambdaWrapper = lambdaWrapper;
module.exports.chai = chai;
<|endoftext|>


<commit_before>var api = require('./api');
var async = require('async');
var auth = require('./auth');
var deploy = require('./deploy');
var etcd = require('./etcd');
var express = require('express');
var http = require('http');
var mkdirp = require('mkdirp');
var path = require('path');
var registry = require('etcd-registry');
var sprintf = require('sprintf').sprintf;
var url = require('url');
var _ = require('underscore');

var log = require('logmagic').local('virgo-upgrade-service.lib.entry');

var logmagic = require('logmagic');
logmagic.route('__root__', logmagic['DEBUG'], 'console');

function die(msg) {
  console.log(msg);
  process.exit(1);
}

/**
 * @param options
 * @return
 */
function entry(options) {
  var app = express(),
      server = http.createServer(app),
      services,
      authDb,
      de,
      value,
      l;

  /* required options */
  options.etcd_host = process.env.VIRGO_UPDATE_SERVICE_ETCD_HOST;
  if (!options.etcd_host) {
    die('VIRGO_UPDATE_SERVICE_ETCD_HOST is missing');
  }
  options.etcd_port = process.env.VIRGO_UPDATE_SERVICE_ETCD_PORT;
  if (!options.etcd_port) {
    die('VIRGO_UPDATE_SERVICE_ETCD_PORT is missing');
  }
  options.bind_host = process.env.VIRGO_UPDATE_SERVICE_BIND_HOST;
  if (!options.bind_host) {
    die('VIRGO_UPDATE_SERVICE_BIND_HOST is missing');
  }
  options.bind_port = process.env.VIRGO_UPDATE_SERVICE_BIND_PORT;
  if (!options.bind_port) {
    die('VIRGO_UPDATE_SERVICE_BIND_PORT is missing');
  }
  options.pkgcloud.username = process.env.VIRGO_UPDATE_SERVICE_PKGCLOUD_USERNAME;
  if (!options.pkgcloud.username) {
    die('VIRGO_UPDATE_SERVICE_PKGCLOUD_USERNAME is missing');
  }
  options.pkgcloud.apiKey = process.env.VIRGO_UPDATE_SERVICE_PKGCLOUD_APIKEY;
  if (!options.pkgcloud.apiKey) {
    die('VIRGO_UPDATE_SERVICE_PKGCLOUD_APIKEY is missing');
  }
  options.secret = process.env.VIRGO_UPDATE_SERVICE_SECRET;
  if (!options.secret) {
    die('VIRGO_UPDATE_SERVICE_SECRET is missing');
  }
  options.htpasswd_file = process.env.VIRGO_UPDATE_SERVICE_HTPASSWD_FILE;
  if (!options.htpasswd_file) {
    die('VIRGO_UPDATE_SERVICE_HTPASSWD_FILE is missing');
  }
  options.default_channels = process.env.VIRGO_UPDATE_SERVICE_DEFAULT_CHANNELS;
  if (!options.default_channels) {
    die('VIRGO_UPDATE_SERVICE_DEFAULT_CHANNELS is missing');
  } else {
    options.default_channels = options.default_channels.split(',');
  }
  options.default_channel_version = process.env.VIRGO_UPDATE_SERVICE_DEFAULT_CHANNEL_VERSION;
  if (!options.default_channel_version) {
    die('VIRGO_UPDATE_SERVICE_DEFAULT_CHANNEL_VERSION is missing');
  }

  /* optional options */
  value = process.env.VIRGO_UPDATE_SERVICE_PUBLIC_HOST;
  if (value) {
    options.addr_host = value;
  } else {
    options.addr_host = options.bind_host;
  }
  value = process.env.VIRGO_UPDATE_SERVICE_PUBLIC_PORT;
  if (value) {
    options.addr_port =  value;
  } else {
    options.addr_port = options.bind_port;
  }
  value = process.env.VIRGO_UPDATE_SERVICE_NAME;
  if (value) {
    options.service_name = value;
  }
  value = process.env.VIRGO_UPDATE_PACKAGE_BACKEND;
  if (value) {
    options.pkgbackend = value;
  } else {
    options.pkgbackend = 'pkgcloud';
  }

  function optionsMiddleware(req, res, next) {
    req.globalOptions = options;
    req.authDb = authDb;
    next();
  }

  etcd.setEndpoints(options.etcd_host + ':' + options.etcd_port);
  authDb = auth.loadDBFromFile(options.htpasswd_file);

  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.static(path.join(__dirname, '..', '..', 'app')));
  app.use('/exe', express.directory(options.exe_dir));
  app.use('/exe', express.static(options.exe_dir));
  app.use(optionsMiddleware);
  api.register(options, server, app);

  de = new deploy.create(options.pkgbackend, options);
  options.deploy_instance = de;

  log.infof('Using etcd ${host}:${port}', {host: options.etcd_host, port: options.etcd_port});
  log.infof('Listening on ${host}:${port}', {host: options.bind_host, port: options.bind_port});

  async.auto({
    makedirs: function(callback) {
      function iter(dir, callback) {
        mkdirp(dir, function() {
          callback();
        })
      }
      async.forEach([options.data_dir, options.exe_dir], iter, callback);
    },
    register: ['makedirs', function(callback) {
      services = registry(options.etcd_host + ':' + options.etcd_port);
      services.join(options.service_name, { hostname: options.addr_host, port: options.addr_port });
      callback();
    }],
    create: ['register', function(callback) {
      log.infof('Checking for default channels', {channels: options.default_channels});
      de.createDefaultChannels(callback);
    }],
    deploy: ['create', function(callback) {
      de.run(callback);
    }],
    listen: ['deploy', function(callback) {
      server.listen(options.bind_port, options.bind_host, callback);
    }]
  }, function(err) {
    if (err) {
      log.errorf("error", {err: err});
      process.exit(1);
    }
    log.info('running');
  });
}

exports.entry = entry;
<commit_msg>check for pkgcloud backend<commit_after>var api = require('./api');
var async = require('async');
var auth = require('./auth');
var deploy = require('./deploy');
var etcd = require('./etcd');
var express = require('express');
var http = require('http');
var mkdirp = require('mkdirp');
var path = require('path');
var registry = require('etcd-registry');
var sprintf = require('sprintf').sprintf;
var url = require('url');
var _ = require('underscore');

var log = require('logmagic').local('virgo-upgrade-service.lib.entry');

var logmagic = require('logmagic');
logmagic.route('__root__', logmagic['DEBUG'], 'console');

function die(msg) {
  console.log(msg);
  process.exit(1);
}

/**
 * @param options
 * @return
 */
function entry(options) {
  var app = express(),
      server = http.createServer(app),
      services,
      authDb,
      de,
      value,
      l;

  /* required options */
  options.etcd_host = process.env.VIRGO_UPDATE_SERVICE_ETCD_HOST;
  if (!options.etcd_host) {
    die('VIRGO_UPDATE_SERVICE_ETCD_HOST is missing');
  }
  options.etcd_port = process.env.VIRGO_UPDATE_SERVICE_ETCD_PORT;
  if (!options.etcd_port) {
    die('VIRGO_UPDATE_SERVICE_ETCD_PORT is missing');
  }
  options.bind_host = process.env.VIRGO_UPDATE_SERVICE_BIND_HOST;
  if (!options.bind_host) {
    die('VIRGO_UPDATE_SERVICE_BIND_HOST is missing');
  }
  options.bind_port = process.env.VIRGO_UPDATE_SERVICE_BIND_PORT;
  if (!options.bind_port) {
    die('VIRGO_UPDATE_SERVICE_BIND_PORT is missing');
  }
  options.secret = process.env.VIRGO_UPDATE_SERVICE_SECRET;
  if (!options.secret) {
    die('VIRGO_UPDATE_SERVICE_SECRET is missing');
  }
  options.htpasswd_file = process.env.VIRGO_UPDATE_SERVICE_HTPASSWD_FILE;
  if (!options.htpasswd_file) {
    die('VIRGO_UPDATE_SERVICE_HTPASSWD_FILE is missing');
  }
  options.default_channels = process.env.VIRGO_UPDATE_SERVICE_DEFAULT_CHANNELS;
  if (!options.default_channels) {
    die('VIRGO_UPDATE_SERVICE_DEFAULT_CHANNELS is missing');
  } else {
    options.default_channels = options.default_channels.split(',');
  }
  options.default_channel_version = process.env.VIRGO_UPDATE_SERVICE_DEFAULT_CHANNEL_VERSION;
  if (!options.default_channel_version) {
    die('VIRGO_UPDATE_SERVICE_DEFAULT_CHANNEL_VERSION is missing');
  }
  options.pkgcloud = process.env.VIRGO_UPDATE_PACKAGE_BACKEND;
  if (!value) {
    options.pkgbackend = 'pkgcloud';;
  }
  options.pkgcloud.username = process.env.VIRGO_UPDATE_SERVICE_PKGCLOUD_USERNAME;
  if (options.pkgbackend === 'pkgcloud' && !options.pkgcloud.username) {
    die('VIRGO_UPDATE_SERVICE_PKGCLOUD_USERNAME is missing');
  }
  options.pkgcloud.apiKey = process.env.VIRGO_UPDATE_SERVICE_PKGCLOUD_APIKEY;
  if (options.pkgbackend === 'pkgcloud' && !options.pkgcloud.apiKey) {
    die('VIRGO_UPDATE_SERVICE_PKGCLOUD_APIKEY is missing');
  }

  /* optional options */
  value = process.env.VIRGO_UPDATE_SERVICE_PUBLIC_HOST;
  if (value) {
    options.addr_host = value;
  } else {
    options.addr_host = options.bind_host;
  }
  value = process.env.VIRGO_UPDATE_SERVICE_PUBLIC_PORT;
  if (value) {
    options.addr_port =  value;
  } else {
    options.addr_port = options.bind_port;
  }
  value = process.env.VIRGO_UPDATE_SERVICE_NAME;
  if (value) {
    options.service_name = value;
  }

  function optionsMiddleware(req, res, next) {
    req.globalOptions = options;
    req.authDb = authDb;
    next();
  }

  etcd.setEndpoints(options.etcd_host + ':' + options.etcd_port);
  authDb = auth.loadDBFromFile(options.htpasswd_file);

  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.static(path.join(__dirname, '..', '..', 'app')));
  app.use('/exe', express.directory(options.exe_dir));
  app.use('/exe', express.static(options.exe_dir));
  app.use(optionsMiddleware);
  api.register(options, server, app);

  de = new deploy.create(options.pkgbackend, options);
  options.deploy_instance = de;

  log.infof('Using etcd ${host}:${port}', {host: options.etcd_host, port: options.etcd_port});
  log.infof('Listening on ${host}:${port}', {host: options.bind_host, port: options.bind_port});

  async.auto({
    makedirs: function(callback) {
      function iter(dir, callback) {
        mkdirp(dir, function() {
          callback();
        })
      }
      async.forEach([options.data_dir, options.exe_dir], iter, callback);
    },
    register: ['makedirs', function(callback) {
      services = registry(options.etcd_host + ':' + options.etcd_port);
      services.join(options.service_name, { hostname: options.addr_host, port: options.addr_port });
      callback();
    }],
    create: ['register', function(callback) {
      log.infof('Checking for default channels', {channels: options.default_channels});
      de.createDefaultChannels(callback);
    }],
    deploy: ['create', function(callback) {
      de.run(callback);
    }],
    listen: ['deploy', function(callback) {
      server.listen(options.bind_port, options.bind_host, callback);
    }]
  }, function(err) {
    if (err) {
      log.errorf("error", {err: err});
      process.exit(1);
    }
    log.info('running');
  });
}

exports.entry = entry;
<|endoftext|>


<commit_before>if (typeof module != 'undefined' && typeof require == 'function'){
    var VectorClock = require('../crdt/vectorClock.js');
    var ReplicaIdentity = require('../replication/replicaIdentity.js');
}

function Counter(id, initialIncrementValues, initialDecrementValues) {

    this.private = {};
    this.private.id = id;
    this.private.incrementClock = initialIncrementValues;
    this.private.decrementClock = initialDecrementValues;

}

/**
 * Increment the counter for the corresponding replica
 * @param replicaId
 * @return boolean
 */
Counter.prototype.increment = function (replicaId) {

    if (!ReplicaIdentity.IsValidStringIdentity(replicaId)) {
        return false
    }

    if (!this.private.incrementClock.tracks(replicaId)) {
        this.private.incrementClock.forceTracking(replicaId);
    }

    if (!this.private.decrementClock.tracks(replicaId)) {
        this.private.decrementClock.forceTracking(replicaId);
    }

    this.private.incrementClock.increment(replicaId);

    return true;
};

/**
 * Decrement the counter for the corresponding replica
 * @param replicaId
 * @return boolean
 */
Counter.prototype.decrement = function (replicaId) {

    if (!ReplicaIdentity.IsValidStringIdentity(replicaId)) {
        return false
    }

    if (!this.private.decrementClock.tracks(replicaId)) {
        this.private.decrementClock.forceTracking(replicaId);
    }

    if (!this.private.incrementClock.tracks(replicaId)) {
        this.private.incrementClock.forceTracking(replicaId);
    }

    this.private.decrementClock.increment(replicaId);

    return true;
};

/**
 * Returns the total count
 * @returns {number} total count
 */
Counter.prototype.getCount = function () {

    var total = 0;

    var keys = this.private.incrementClock.getKeys();

    keys.forEach(function (element){
        total += this.private.incrementClock.getCount(element);
        total -= this.private.decrementClock.getCount(element);
    }, this);

    return total;
};

/**
 * Returns the decrement count tracked for a given replicaID. False if not tracking it.
 * @param repId
 * @returns {*}
 */
Counter.prototype.getDecrementCountByReplicaId = function (repId) {
    if (this.private.decrementClock.tracks(repId)) {
        var val = this.private.decrementClock.getCount(repId);
        if (val < 0) {
            return 0;
        } else {
            return val;
        }
    }

    return false;
};

/**
 * Returns the increment count tracked for a given replica ID. False if not tracking it.
 * @param repId
 * @returns {*}
 */
Counter.prototype.getIncrementCountByReplicaId = function (repId) {
    if (this.private.incrementClock.tracks(repId)) {
        var val = this.private.incrementClock.getCount(repId);
        if (val < 0) {
            return 0;
        } else {
            return val;
        }
    }

    return false;
};

/**
 * Checks if the current counter keeps track of the count of the given replica ID
 * @param repId
 * @returns {boolean}
 */
Counter.prototype.tracks = function (repId) {
    return this.private.incrementClock.tracks(repId);
};

/**
 * Returns an array of the replica IDs that it is currently tracking
 * @returns {Array}
 */
Counter.prototype.getReplicaIds = function () {
    return this.private.incrementClock.getKeys();
};

/**
 * Returns the increment vector clock
 * @returns {*}
 */
Counter.prototype.getIncrementClock = function () {
    return this.private.incrementClock;
};

/**
 * Returns the decrement vector clock
 * @returns {*}
 */
Counter.prototype.getDecrementClock = function () {
    return this.private.decrementClock;
};

/**
 * Merge two counters and return the result
 * @param otherCounter
 * @returns {*}
 */
Counter.prototype.merge = function (otherCounter) {

    if (!otherCounter) {
        log("We need two counters in order to merge!");
        return this;
    }

    if (this.private.id != otherCounter.getId()) {
        log("counterIds don't match!");
        return false;
    }

    var incClock = this.private.incrementClock.merge(otherCounter.getIncrementClock());
    var decClock = this.private.decrementClock.merge(otherCounter.getDecrementClock());

    incClock.purge();
    decClock.purge();

    return new Counter(this.private.id, incClock, decClock);
};

/**
 * Return the current counter in JSON format
 * @returns {*}
 */
Counter.prototype.toJSON = function () {
    var bag = {};
    bag['id'] = this.private.id;
    bag['increment'] = this.private.incrementClock.getInternalVector();
    bag['decrement'] = this.private.decrementClock.getInternalVector();
    return JSON.stringify(bag);
};

/**
 * Returns the ID of the current counter
 * @returns {*}
 */
Counter.prototype.getId = function () {
    return this.private.id;
};

if (typeof module != 'undefined') {
    module.exports = Counter;
}

<commit_msg>Added the posibility to convert a Counter object into a very simple object to be serialized.<commit_after>if (typeof module != 'undefined' && typeof require == 'function'){
    var VectorClock = require('../crdt/vectorClock.js');
    var ReplicaIdentity = require('../replication/replicaIdentity.js');
}

function Counter(id, initialIncrementValues, initialDecrementValues) {

    this.private = {};
    this.private.id = id;
    this.private.incrementClock = initialIncrementValues;
    this.private.decrementClock = initialDecrementValues;

}

/**
 * Increment the counter for the corresponding replica
 * @param replicaId
 * @return boolean
 */
Counter.prototype.increment = function (replicaId) {

    if (!ReplicaIdentity.IsValidStringIdentity(replicaId)) {
        return false
    }

    if (!this.private.incrementClock.tracks(replicaId)) {
        this.private.incrementClock.forceTracking(replicaId);
    }

    if (!this.private.decrementClock.tracks(replicaId)) {
        this.private.decrementClock.forceTracking(replicaId);
    }

    this.private.incrementClock.increment(replicaId);

    return true;
};

/**
 * Decrement the counter for the corresponding replica
 * @param replicaId
 * @return boolean
 */
Counter.prototype.decrement = function (replicaId) {

    if (!ReplicaIdentity.IsValidStringIdentity(replicaId)) {
        return false
    }

    if (!this.private.decrementClock.tracks(replicaId)) {
        this.private.decrementClock.forceTracking(replicaId);
    }

    if (!this.private.incrementClock.tracks(replicaId)) {
        this.private.incrementClock.forceTracking(replicaId);
    }

    this.private.decrementClock.increment(replicaId);

    return true;
};

/**
 * Returns the total count
 * @returns {number} total count
 */
Counter.prototype.getCount = function () {

    var total = 0;

    var keys = this.private.incrementClock.getKeys();

    keys.forEach(function (element){
        total += this.private.incrementClock.getCount(element);
        total -= this.private.decrementClock.getCount(element);
    }, this);

    return total;
};

/**
 * Returns the decrement count tracked for a given replicaID. False if not tracking it.
 * @param repId
 * @returns {*}
 */
Counter.prototype.getDecrementCountByReplicaId = function (repId) {
    if (this.private.decrementClock.tracks(repId)) {
        var val = this.private.decrementClock.getCount(repId);
        if (val < 0) {
            return 0;
        } else {
            return val;
        }
    }

    return false;
};

/**
 * Returns the increment count tracked for a given replica ID. False if not tracking it.
 * @param repId
 * @returns {*}
 */
Counter.prototype.getIncrementCountByReplicaId = function (repId) {
    if (this.private.incrementClock.tracks(repId)) {
        var val = this.private.incrementClock.getCount(repId);
        if (val < 0) {
            return 0;
        } else {
            return val;
        }
    }

    return false;
};

/**
 * Checks if the current counter keeps track of the count of the given replica ID
 * @param repId
 * @returns {boolean}
 */
Counter.prototype.tracks = function (repId) {
    return this.private.incrementClock.tracks(repId);
};

/**
 * Returns an array of the replica IDs that it is currently tracking
 * @returns {Array}
 */
Counter.prototype.getReplicaIds = function () {
    return this.private.incrementClock.getKeys();
};

/**
 * Returns the increment vector clock
 * @returns {*}
 */
Counter.prototype.getIncrementClock = function () {
    return this.private.incrementClock;
};

/**
 * Returns the decrement vector clock
 * @returns {*}
 */
Counter.prototype.getDecrementClock = function () {
    return this.private.decrementClock;
};

/**
 * Merge two counters and return the result
 * @param otherCounter
 * @returns {*}
 */
Counter.prototype.merge = function (otherCounter) {

    if (!otherCounter) {
        log("We need two counters in order to merge!");
        return this;
    }

    if (this.private.id != otherCounter.getId()) {
        log("counterIds don't match!");
        return false;
    }

    var incClock = this.private.incrementClock.merge(otherCounter.getIncrementClock());
    var decClock = this.private.decrementClock.merge(otherCounter.getDecrementClock());

    incClock.purge();
    decClock.purge();

    return new Counter(this.private.id, incClock, decClock);
};

/**
 * Return the current counter as a very simple object.
 * @returns {{}}
 */
Counter.prototype.toObject = function (){
    var obj = {};
    obj['id'] = this.private.id;
    obj['increment'] = this.private.incrementClock.getInternalVector();
    obj['decrement'] = this.private.decrementClock.getInternalVector();
    return obj;
}

/**
 * Return the current counter in JSON format
 * @returns {*}
 */
Counter.prototype.toJSON = function () {
    return JSON.stringify(this.toObject());
};

/**
 * Returns the ID of the current counter
 * @returns {*}
 */
Counter.prototype.getId = function () {
    return this.private.id;
};

if (typeof module != 'undefined') {
    module.exports = Counter;
}

<|endoftext|>


<commit_before>/* eslint-env node */
'use strict';

module.exports = {
  name: 'ember-google-maps',

  config(env, config) {
    let src = '//maps.googleapis.com/maps/api/js';
    let mapConfig = config['ember-google-maps'] || {};
    let params = [];

    let key = mapConfig.key;
    if (key) {
      params.push('key=' + encodeURIComponent(key));
    }

    let version = mapConfig.version;
    if (version) {
      params.push('v=' + encodeURIComponent(version));
    }

    let client = mapConfig.client;
    if (client) {
      params.push('client=' + encodeURIComponent(client));
    }

    let channel = mapConfig.channel;
    if (channel) {
      params.push('channel=' + encodeURIComponent(channel));
    }

    let libraries = mapConfig.libraries;
    if (libraries && libraries.length) {
      params.push('libraries=' + encodeURIComponent(libraries.join(',')));
    }

    let language = mapConfig.language;
    if (language) {
      params.push('language=' + encodeURIComponent(language));
    }

    let protocol = mapConfig.protocol;
    if (protocol) {
      src = protocol + ':' + src;
    }

    src += '?' + params.join('&');

    mapConfig['src'] = src;

    config['ember-google-maps'] = mapConfig;

    return config;
  }
};
<commit_msg>Add options to treeshake components<commit_after>/* eslint-env node */
'use strict';

const Funnel = require('broccoli-funnel');
const path = require('path');

function intersection(a, b) {
  const intersection = new Set();
  for (let e of b) {
    if (a.has(e)) {
      intersection.add(e);
    }
  }
  return intersection;
}

function difference(a, b) {
  const difference = new Set(a);
  for (let e of b) {
    difference.delete(e);
  }
  return difference;
}

const dependencies = {
  'circle': ['marker'],
  'info-window': ['detect-render']
};

module.exports = {
  name: 'ember-google-maps',

  included() {
    this._super.included.apply(this, arguments);

    const app = this._findHost();

    const config = app.options['ember-google-maps'] || {};
    this.whitelist = this.generateWhitelist(config);
    this.blacklist = this.generateBlacklist(config);

    // If a whitelist is used, ensure that we include the base map component.
    if (this.whitelist.length) {
      this.whitelist.push('g-map', 'canvas', 'base');
      this.whitelist.forEach((w) => {
        const deps = dependencies[w];
        if (deps) {
          this.whitelist = this.whitelist.concat(deps);
        }
      });
    }

    this.noFiltersDefined = (!this.whitelist || this.whitelist.length === 0) && (!this.blacklist || this.blacklist.length === 0);
  },

  config(env, config) {
    let src = '//maps.googleapis.com/maps/api/js';
    let mapConfig = config['ember-google-maps'] || {};
    let params = [];

    let key = mapConfig.key;
    if (key) {
      params.push('key=' + encodeURIComponent(key));
    }

    let version = mapConfig.version;
    if (version) {
      params.push('v=' + encodeURIComponent(version));
    }

    let client = mapConfig.client;
    if (client) {
      params.push('client=' + encodeURIComponent(client));
    }

    let channel = mapConfig.channel;
    if (channel) {
      params.push('channel=' + encodeURIComponent(channel));
    }

    let libraries = mapConfig.libraries;
    if (libraries && libraries.length) {
      params.push('libraries=' + encodeURIComponent(libraries.join(',')));
    }

    let language = mapConfig.language;
    if (language) {
      params.push('language=' + encodeURIComponent(language));
    }

    let protocol = mapConfig.protocol;
    if (protocol) {
      src = protocol + ':' + src;
    }

    src += '?' + params.join('&');

    mapConfig['src'] = src;

    config['ember-google-maps'] = mapConfig;

    return config;
  },

  treeForAddon() {
    const tree = this._super.treeForAddon.apply(this, arguments);
    return this.filterComponents(tree);
  },

  treeForAddonTemplates() {
    const tree = this._super.treeForAddonTemplates.apply(this, arguments);
    return this.filterComponents(tree);
  },

  filterComponents(tree) {
    const whitelist = this.whitelist;
    const blacklist = this.blacklist;

    if (this.noFiltersDefined) {
      return tree;
    }

    return new Funnel(tree, {
      exclude: [(name) => this.excludeComponent(name, whitelist, blacklist)]
    });
  },

  excludeComponent(name, whitelist, blacklist) {
    const regex = /components\//;

    const isComponent = regex.test(name);
    if (!isComponent) {
      return false;
    }

    let baseName = path.basename(name);
    baseName = baseName.split('.').shift();

    let isWhiteListed = whitelist.indexOf(baseName) !== -1;
    let isBlackListed = blacklist.indexOf(baseName) !== -1;

    if (whitelist.length === 0 && blacklist.length === 0) {
      return false;
    }

    // Include if both white- and blacklisted
    if (isWhiteListed && isBlackListed) {
      return false;
    }

    // Only whitelisted
    if (whitelist.length && blacklist.length === 0) {
      return !isWhiteListed;
    }

    // Only blacklisted
    if (blacklist.length && whitelist.length === 0) {
      return isBlackListed;
    }

    return !isWhiteListed || isBlackListed;
  },

  generateWhitelist(config) {
    const only = new Set(config.only || []);
    const except = new Set(config.except || []);

    if (except && except.length) {
      return difference(only, except);
    }

    return Array.from(only);
  },

  generateBlacklist(config) {
    const only = new Set(config.only || []);
    const except = new Set(config.except || []);

    if (only && only.length) {
      return intersection(except, only);
    }

    return Array.from(except);
  }
};
<|endoftext|>