<commit_before>/* Copyright 2011 Carlos Guerreiro
   All rights reserved */

'use strict';

var redis  = require('redis');

module.exports = function (queueName) {
  var that = this;
  var client = redis.createClient();

  client.on('error', function(err) {
    console.error(err);
  });

  var listKey = queueName+ '_a';

  console.error('listKey', listKey);

  var quitting = false;
  var busyCount = 0;

  function clientQuit() {
    if(!client.connected) {
      // FIXME: this is to work around a bug in the redis client where it will keep retrying a reconnection just to send the QUIT request
      // FIXME: actually go and report bug
      client.closing = true;
    }
    client.quit();
  }

  function markDone() {
    --busyCount;
    if(busyCount === 0) {
      if(quitting) {
        clientQuit();
      }
    }
  }

  that.add = function(id, when, cb) {
    ++busyCount;
    if(typeof when !== 'number' || Math.floor(when) !== when) {
      process.nextTick(function() { cb('when must be an integer'); markDone();});
    } else {
      client.rpush(listKey, JSON.stringify({id: id, when:when}), function(err, results) {
        markDone();
        cb(err, results);
      });
    }
  };

  that.quit = function() {
    if(busyCount === 0) {
      clientQuit();
    } else {
      quitting = true;
    }
  };
};
<commit_msg>info with console.log<commit_after>/* Copyright 2011 Carlos Guerreiro
   All rights reserved */

'use strict';

var redis  = require('redis');

module.exports = function (queueName) {
  var that = this;
  var client = redis.createClient();

  client.on('error', function(err) {
    console.error(err);
  });

  var listKey = queueName+ '_a';

  console.log('listKey', listKey);

  var quitting = false;
  var busyCount = 0;

  function clientQuit() {
    if(!client.connected) {
      // FIXME: this is to work around a bug in the redis client where it will keep retrying a reconnection just to send the QUIT request
      // FIXME: actually go and report bug
      client.closing = true;
    }
    client.quit();
  }

  function markDone() {
    --busyCount;
    if(busyCount === 0) {
      if(quitting) {
        clientQuit();
      }
    }
  }

  that.add = function(id, when, cb) {
    ++busyCount;
    if(typeof when !== 'number' || Math.floor(when) !== when) {
      process.nextTick(function() { cb('when must be an integer'); markDone();});
    } else {
      client.rpush(listKey, JSON.stringify({id: id, when:when}), function(err, results) {
        markDone();
        cb(err, results);
      });
    }
  };

  that.quit = function() {
    if(busyCount === 0) {
      clientQuit();
    } else {
      quitting = true;
    }
  };
};
<|endoftext|>


<commit_before>'use strict'

var renderer_api  = new RendererAPI()
if (renderer_api.is_webgl_enabled() === false) {
    console.log('WebGL is not enabled!')
    throw new Error('WebGL is not enabled!')
}
var stats_api = new StatsAPI()
var scene = new THREE.Scene()
var camera   = new THREE.PerspectiveCamera(renderer_api.field_of_view, renderer_api.aspect_ratio, renderer_api.near_clipping, renderer_api.far_clipping)
renderer_api.set_camera(camera)
var fps_controls = new FPSControls(camera)
scene.add(fps_controls.get_object())

var pointer_lock_api = new PointerLockAPI(fps_controls)

var geometry = new THREE.BoxGeometry(5,5, 5)
//var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
var material = new THREE.MeshLambertMaterial({ color: 0x00ff00 })
var cube 	 = new THREE.Mesh(geometry, material)
scene.add(cube)

// Going to try to create a plane here.
var plane_geometry = new THREE.PlaneGeometry(2000, 2000, 100, 100)
plane_geometry.applyMatrix(new THREE.Matrix4().makeRotationX(- Math.PI / 2))
//var plane_material = new THREE.MeshBasicMaterial({color: 0x0000ff})
var plane_material = new THREE.MeshLambertMaterial({color: 0xccffcc, side: THREE.FrontSide, wireframe: false})
var plane_mesh     = new THREE.Mesh(plane_geometry, plane_material)
scene.add(plane_mesh)

var log_geometry = new THREE.PlaneGeometry(50, 50, 100, 100)
log_geometry.applyMatrix(new THREE.Matrix4().makeRotationY(- Math.PI / 2))
var log_material = new THREE.MeshBasicMaterial()
log_material.color.set('black')
log_material.opacity   = 0
log_material.blending  = THREE.NoBlending
var log_mesh = new THREE.Mesh(log_geometry, log_material)
scene.add(log_mesh)

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

var css_renderer_api = new CSSRendererAPI()

var cssScene = new THREE.Scene()

var math_formulas = document.getElementById('math_formulas')

var element = document.createElement('div')
element.innerHTML = 'Plain text inside a div.'
element.className = 'three-div'

//var css_object = new THREE.CSS3DObject(math_formulas)
var css_object = new THREE.CSS3DObject(element)

css_object.position.x = log_mesh.position.x
css_object.position.y = log_mesh.position.y
css_object.position.z = log_mesh.position.z

css_object.rotation.x = log_mesh.rotation.x
css_object.rotation.y = log_mesh.rotation.y
css_object.rotation.z = log_mesh.rotation.z

//var light4 = new THREE.HemisphereLight(0xffbf67, 0x15c6ff, .3)
//scene.add(light4)

//scene.add(css_object)
cssScene.add(css_object)

// @@@@
css_renderer_api.renderer.domElement.appendChild(renderer_api.renderer.domElement)
document.body.appendChild(css_renderer_api.renderer.domElement)
// @@@@

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//camera.position.z = 10

/*
// Line test.
var line_material = new THREE.LineBasicMaterial({color: LIGHT_GREEN, opacity: 1, linewidth: 50})
var line_geometry = new THREE.Geometry()
line_geometry.vertices.push(new THREE.Vector3(-100, 0, 0))
line_geometry.vertices.push(new THREE.Vector3(0, 100, 0))
line_geometry.vertices.push(new THREE.Vector3(0, 0, 0))
line_geometry.vertices.push(new THREE.Vector3(50, 50, 50))
var line = new THREE.Line(line_geometry, line_material)
scene.add(line)
*/

// Add lights.
var ambiColor = '#cbe7ff'
var ambientLight = new THREE.AmbientLight(ambiColor, .4)
scene.add(ambientLight)
/*
var light = new THREE.DirectionalLight( 0xffffff, 1.5 )
light.position.set(1, 1, 1 )
scene.add(light)s

var light2 = new THREE.DirectionalLight( 0xffffff, 0.75 )
light2.position.set(-1, - 0.5, -1)
scene.add(light2)
*/

var data_display = new DataDisplay(fps_controls)

var light3 = new THREE.PointLight(0xccffcc, 1, 1000)
light3.position.set(5, 15, 5)
scene.add(light3)

//var shader_api = new ShaderAPI(renderer_api, scene, camera)

var previous_time = performance.now()

var iii = 0

var animate = function () {

    if (iii === 1000) {
        iii = 0
        console.log(css_object.position.x + '\t' + log_mesh.position.x)
        console.log(css_object.position.y + '\t' + log_mesh.position.y)
        console.log(css_object.position.z + '\t' + log_mesh.position.z)

        console.log(css_object.rotation.x + '\t' + log_mesh.rotation.x)
        console.log(css_object.rotation.y + '\t' + log_mesh.rotation.y)
        console.log(css_object.rotation.z + '\t' + log_mesh.rotation.z)
    } else {
        iii += 1
    }

    //shader_api.render()

    requestAnimationFrame(animate)

    stats_api.pre_render()

    cube.rotation.x += 0.01
    cube.rotation.y += 0.01

    var time = performance.now()
    var delta = (time - previous_time) / 1000

    fps_controls.physics(delta)
    data_display.update()

    //css_renderer_api.renderer.render(cssScene, camera)
    //renderer_api.render(scene, camera)
    renderer_api.renderer.render(scene, camera)
    css_renderer_api.renderer.render(cssScene, camera)

    stats_api.post_render()

    previous_time = time
}

animate()

<commit_msg>Log rule display testing 53<commit_after>'use strict'

var renderer_api  = new RendererAPI()
if (renderer_api.is_webgl_enabled() === false) {
    console.log('WebGL is not enabled!')
    throw new Error('WebGL is not enabled!')
}
var stats_api = new StatsAPI()
var scene = new THREE.Scene()
var camera   = new THREE.PerspectiveCamera(renderer_api.field_of_view, renderer_api.aspect_ratio, renderer_api.near_clipping, renderer_api.far_clipping)
renderer_api.set_camera(camera)
var fps_controls = new FPSControls(camera)
scene.add(fps_controls.get_object())

var pointer_lock_api = new PointerLockAPI(fps_controls)

var geometry = new THREE.BoxGeometry(5,5, 5)
//var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
var material = new THREE.MeshLambertMaterial({ color: 0x00ff00 })
var cube 	 = new THREE.Mesh(geometry, material)
scene.add(cube)

// Going to try to create a plane here.
var plane_geometry = new THREE.PlaneGeometry(2000, 2000, 100, 100)
plane_geometry.applyMatrix(new THREE.Matrix4().makeRotationX(- Math.PI / 2))
//var plane_material = new THREE.MeshBasicMaterial({color: 0x0000ff})
var plane_material = new THREE.MeshLambertMaterial({color: 0xccffcc, side: THREE.FrontSide, wireframe: false})
var plane_mesh     = new THREE.Mesh(plane_geometry, plane_material)
scene.add(plane_mesh)

var log_geometry = new THREE.PlaneGeometry(50, 50, 100, 100)
log_geometry.applyMatrix(new THREE.Matrix4().makeRotationY(- Math.PI / 2))
var log_material = new THREE.MeshBasicMaterial({color: 0xccffcc, wireframe: true})
//var log_material = new THREE.MeshBasicMaterial()
//log_material.color.set('black')
//log_material.opacity   = 0
//log_material.blending  = THREE.NoBlending
var log_mesh = new THREE.Mesh(log_geometry, log_material)
scene.add(log_mesh)

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

var css_renderer_api = new CSSRendererAPI()

var cssScene = new THREE.Scene()

var math_formulas = document.getElementById('math_formulas')

var element = document.createElement('div')
element.innerHTML = 'Plain text inside a div.'
element.className = 'three-div'

//var css_object = new THREE.CSS3DObject(math_formulas)
var css_object = new THREE.CSS3DObject(element)

css_object.position.x = log_mesh.position.x
css_object.position.y = log_mesh.position.y
css_object.position.z = log_mesh.position.z

css_object.rotation.x = log_mesh.rotation.x
css_object.rotation.y = log_mesh.rotation.y
css_object.rotation.z = log_mesh.rotation.z

//var light4 = new THREE.HemisphereLight(0xffbf67, 0x15c6ff, .3)
//scene.add(light4)

//scene.add(css_object)
cssScene.add(css_object)

// @@@@
css_renderer_api.renderer.domElement.appendChild(renderer_api.renderer.domElement)
document.body.appendChild(css_renderer_api.renderer.domElement)
// @@@@

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//camera.position.z = 10

/*
// Line test.
var line_material = new THREE.LineBasicMaterial({color: LIGHT_GREEN, opacity: 1, linewidth: 50})
var line_geometry = new THREE.Geometry()
line_geometry.vertices.push(new THREE.Vector3(-100, 0, 0))
line_geometry.vertices.push(new THREE.Vector3(0, 100, 0))
line_geometry.vertices.push(new THREE.Vector3(0, 0, 0))
line_geometry.vertices.push(new THREE.Vector3(50, 50, 50))
var line = new THREE.Line(line_geometry, line_material)
scene.add(line)
*/

// Add lights.
var ambiColor = '#cbe7ff'
var ambientLight = new THREE.AmbientLight(ambiColor, .4)
scene.add(ambientLight)
/*
var light = new THREE.DirectionalLight( 0xffffff, 1.5 )
light.position.set(1, 1, 1 )
scene.add(light)s

var light2 = new THREE.DirectionalLight( 0xffffff, 0.75 )
light2.position.set(-1, - 0.5, -1)
scene.add(light2)
*/

var data_display = new DataDisplay(fps_controls)

var light3 = new THREE.PointLight(0xccffcc, 1, 1000)
light3.position.set(5, 15, 5)
scene.add(light3)

//var shader_api = new ShaderAPI(renderer_api, scene, camera)

var previous_time = performance.now()

var iii = 0

var animate = function () {

    if (iii === 1000) {
        iii = 0
        console.log(css_object.position.x + '\t' + log_mesh.position.x)
        console.log(css_object.position.y + '\t' + log_mesh.position.y)
        console.log(css_object.position.z + '\t' + log_mesh.position.z)

        console.log(css_object.rotation.x + '\t' + log_mesh.rotation.x)
        console.log(css_object.rotation.y + '\t' + log_mesh.rotation.y)
        console.log(css_object.rotation.z + '\t' + log_mesh.rotation.z)
    } else {
        iii += 1
    }

    //shader_api.render()

    requestAnimationFrame(animate)

    stats_api.pre_render()

    cube.rotation.x += 0.01
    cube.rotation.y += 0.01

    var time = performance.now()
    var delta = (time - previous_time) / 1000

    fps_controls.physics(delta)
    data_display.update()

    //css_renderer_api.renderer.render(cssScene, camera)
    //renderer_api.render(scene, camera)
    renderer_api.renderer.render(scene, camera)
    css_renderer_api.renderer.render(cssScene, camera)

    stats_api.post_render()

    previous_time = time
}

animate()

<|endoftext|>


<commit_before>
//A variable withouth the keyword var is global variable.
// This global function resize the content of a grid-stack-content element
// given its id (with the # sign eg: #qwrwsll12 )
adjustGridStackContent = function (elementId) {

        // Tiny trick in case there is no elementId
        // then just add an empty space and this function
        // will go over all the grid-stack-item
        var prefix = "";
        if (elementId) {
            prefix = elementId + " ";
        }

        var totalHeight = $(prefix  +  ".grid-stack-item-content").height();
        var headHeight  = $(prefix  +  ".grid-stack-item-content .header").height();
        var tailHeight  = $(prefix  +  ".grid-stack-item-content .tail").height();

        console.log('totalHeight= ' + totalHeight);
        console.log('headHeight= ' + headHeight);
        console.log('tailHeight= ' + tailHeight);

        var fillRemaining = totalHeight - headHeight - tailHeight - 15;
        console.log('fillRemaining: ' + fillRemaining);

        console.log(fillRemaining);
        $(prefix  +  ".grid-stack-item-content .content").css('height',fillRemaining);
}
<commit_msg>Implemented a pseudo minimal case for the resizing function.<commit_after>
//A variable withouth the keyword var is global variable.
// This global function resize the content of a grid-stack-content element
// given its id (with the # sign eg: #qwrwsll12 )
// TODO: Figure out the correct mininumHeight value.
//
//
adjustGridStackContent = function (elementId) {

        var mininumHeight = 200;

        // Tiny trick in case there is no elementId
        // then just add an empty space and this function
        // will go over all the grid-stack-item
        var prefix = "";
        if (elementId) {
            prefix = elementId + " ";
        }

        var totalHeight = $(prefix  +  ".grid-stack-item-content").height();
        if (totalHeight <= mininumHeight) {
            var headHeight  = 20;
            var tailHeight  = 20;
            totalHeight = mininumHeight;
            var fillRemaining = totalHeight - headHeight - tailHeight - 15;
        } else {
            var headHeight  = $(prefix  +  ".grid-stack-item-content .header").height();
            var tailHeight  = $(prefix  +  ".grid-stack-item-content .tail").height();
            var fillRemaining = totalHeight - headHeight - tailHeight - 15;
        }

        /*console.log('totalHeight= ' + totalHeight);
        console.log('headHeight= ' + headHeight);
        console.log('tailHeight= ' + tailHeight);
        console.log('fillRemaining: ' + fillRemaining);*/

        $(prefix  +  ".grid-stack-item-content .content").css('height',fillRemaining);
}
<|endoftext|>


<commit_before>/* globals Player: false, Song: false */

describe('Player', function() {
  var player;
  var song;

  beforeEach(function() {
    player = new Player();
    song = new Song();
  });

  it('should be able to play a Song', function() {
    player.play(song);
    expect(player.currentlyPlayingSong).toEqual(song);

    //demonstrates use of custom matcher
    expect(player).toBePlaying(song);
  });

  describe('when song has been paused', function() {
    beforeEach(function() {
      player.play(song);
      player.pause();
    });

    it('should indicate that the song is currently paused', function() {
      expect(player.isPlaying).toBeFalsy();

      // demonstrates use of 'not' with a custom matcher
      expect(player).not.toBePlaying(song);
    });

    it('should be possible to resume', function() {
      player.resume();
      expect(player.isPlaying).toBeTruthy();
      expect(player.currentlyPlayingSong).toEqual(song);
    });
  });

  // demonstrates use of spies to intercept and test method calls
  it('tells the current song if the user has made it a favorite', function() {
    spyOn(song, 'persistFavoriteStatus');

    player.play(song);
    player.makeFavorite();

    expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
  });
});
<commit_msg>Build and tests work, now testing that it will actually fail if a test fails<commit_after>/* globals Player: false, Song: false */

describe('Player', function() {
  var player;
  var song;

  beforeEach(function() {
    player = new Player();
    song = new Song();
  });

  it('should be able to play a Song', function() {
    player.play(song);
    expect(player.currentlyPlayingSong).toEqual(0);

    //demonstrates use of custom matcher
    expect(player).toBePlaying(song);
  });

  describe('when song has been paused', function() {
    beforeEach(function() {
      player.play(song);
      player.pause();
    });

    it('should indicate that the song is currently paused', function() {
      expect(player.isPlaying).toBeFalsy();

      // demonstrates use of 'not' with a custom matcher
      expect(player).not.toBePlaying(song);
    });

    it('should be possible to resume', function() {
      player.resume();
      expect(player.isPlaying).toBeTruthy();
      expect(player.currentlyPlayingSong).toEqual(song);
    });
  });

  // demonstrates use of spies to intercept and test method calls
  it('tells the current song if the user has made it a favorite', function() {
    spyOn(song, 'persistFavoriteStatus');

    player.play(song);
    player.makeFavorite();

    expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
  });
});
<|endoftext|>


<commit_before>'use strict;'

/*

  generate dynamic patterns

*/
var code = ReactiveVar();

Template.generator.helpers({

});

Template.generator.events({
  'keyup .generator .draw.code' : function(evt) {
    console.log('generate pattern');
    console.log($(evt.currentTarget).val());
    code.set( $(evt.currentTarget).val() );
  }
});

Template.generator.rendered = function () {

  // render the dynamic pattern whenever the code changes
  this.autorun(function() {
    render(code.get());
  });

  code.set( this.$('.code').val() );
}

// function _init() {

// }

var _state = null,
  _canvas = null,
  _ctx = null,
  _compiledDraw = null;

function _draw(body, time) {
  if (!_compiledDraw)
    _compiledDraw = new Function('canvas','ctx','state',body);

  console.log('drawing frame',_state);
  _compiledDraw(_canvas, _ctx, _state);
  var imgSrc = _canvas.toDataURL();
  var imageData = _ctx.getImageData(0,0,8,8);
  var step = {
    time: time,
    opcodes: [_imageDataToBitmap(imageData.data)],
    _image : imgSrc
  };

  CurrentPattern.update('42', {
    $push : {
      steps: step
    }
  })
}

function _imageDataToBitmap(data) {
  console.log(data.length)
  var bitmap = [];
  for (var p = 0 ; p<256 ; p+=4) {
    bitmap.push(data[p]);
    bitmap.push(data[p+1]);
    bitmap.push(data[p+2]);
  }
  return { opcode: 'bmp', data: bitmap };
}

function render(drawcode) {
  _compiledDraw = null;
  _state = {};
  _canvas = document.createElement('canvas');
  _canvas.width = _canvas.height = 8;
  _ctx = _canvas.getContext('2d');
  CurrentPattern.update('42', { $set: { steps : [] }});
  // _init(canvas, ctx, state);

  for (var i=0 ; i<4 ; i++)
    _draw(drawcode, i*200);

  //console.log(frames)
  // pattern.steps = frames;
}
<commit_msg>use session instead of reactive var for live code<commit_after>'use strict;'

/*

  generate dynamic patterns

*/
Session.setDefault('drawCode', null);

Template.generator.helpers({

});

Template.generator.events({
  'keyup .generator .draw.code' : function(evt) {
    console.log('generate pattern');
    console.log($(evt.currentTarget).val());
    Session.set('drawCode', $(evt.currentTarget).val() );
  }
});

Template.generator.rendered = function () {

  // render the dynamic pattern whenever the code changes
  this.autorun(function() {
    render(Session.get('drawCode'));
  });

  Session.set('drawCode', this.$('.code').val() );
}

// function _init() {

// }

var _state = null,
  _canvas = null,
  _ctx = null,
  _compiledDraw = null;

function _draw(body, time) {
  if (!_compiledDraw)
    _compiledDraw = new Function('canvas','ctx','state',body);

  console.log('drawing frame',_state);
  _compiledDraw(_canvas, _ctx, _state);
  var imgSrc = _canvas.toDataURL();
  var imageData = _ctx.getImageData(0,0,8,8);
  var step = {
    time: time,
    opcodes: [_imageDataToBitmap(imageData.data)],
    _image : imgSrc
  };

  CurrentPattern.update('42', {
    $push : {
      steps: step
    }
  })
}

function _imageDataToBitmap(data) {
  console.log(data.length)
  var bitmap = [];
  for (var p = 0 ; p<256 ; p+=4) {
    bitmap.push(data[p]);
    bitmap.push(data[p+1]);
    bitmap.push(data[p+2]);
  }
  return { opcode: 'bmp', data: bitmap };
}

function render(drawcode) {
  _compiledDraw = null;
  _state = {};
  _canvas = document.createElement('canvas');
  _canvas.width = _canvas.height = 8;
  _ctx = _canvas.getContext('2d');
  CurrentPattern.update('42', { $set: { steps : [] }});
  // _init(canvas, ctx, state);

  for (var i=0 ; i<4 ; i++)
    _draw(drawcode, i*200);

  //console.log(frames)
  // pattern.steps = frames;
}
<|endoftext|>


<commit_before>test('first test', function(){
  equal(2+1, 4, '2+2 should equal 4')
});<commit_msg>Add first failing test<commit_after>createConsole = function(options){
  // var el = document.createElement('div')
  var el = document.getElementById('console');
  el.className = 'console'

  return new CSConsole(el,{
    prompt: options.prompt,
    historyLabel: options.historyLabel,
    syntax: options.syntax,
    welcomeMessage: options.welcomeMessage,
    autoFocus: options.autoFocus,
    commandValidate: options.commandValidate,
    commandHandle: options.commandHandle,
    commandCancel: options.commandCancel
  });
}

module('constructor options');
test('setting prompt without welcome message should display prompt', function(){
  var prompt = "> ";
  var console = createConsole({
    prompt: prompt
  })
  var cm = console.innerConsole();

  ok( cm.getLine(cm.lineCount() - 1).match(new RegExp(prompt)) );
});<|endoftext|>


<commit_before>'use strict';

const DEFAULT_CONFIG = {
  host:     undefined,
  username: undefined,
};

/**
 * Client
 *
 * Serves as client to the bridge
 */
class Client {
  /**
   * Constructor
   *
   * @param {Object} config Configuration
   */
  constructor(config) {
    this.config = Object.assign({}, DEFAULT_CONFIG, config);

    for (let key in config) {
      this[key] = config[key];
    }

    this.accessors = {};
  }

  /**
   * Get host
   *
   * @return {string} Host
   */
  get host() {
    return this.config.host;
  }

  /**
   * Set host
   *
   * @param {string} host Host
   */
  set host(host) {
    this.config.host = host;
  }

  /**
   * Get username
   *
   * @return {string} Username
   */
  get username() {
    return this.config.username;
  }

  /**
   * Set username
   *
   * @param  {string} username Username
   */
  set username(username) {
    this.config.username = username;
  }

  /**
   * Ping bridge
   *
   * @return {Promise} Promise for chaining
   */
  ping() {
    let Ping = require('./Command/Ping');

    return this.invokeCommand(new Ping);
  }

  /**
   * Get bridge
   *
   * @return {Promise} Promise for chaining
   */
  getBridge() {
    let GetBridge = require('./Command/GetBridge');

    return this.invokeCommand(new GetBridge);
  }

  /**
   * Save bridge
   *
   * @param {mixed} bridge Bridge
   *
   * @return {Promise} Promise for chaining
   */
  saveBridge(bridge) {
    let SaveBridge = require('./Command/SaveBridge');

    return this.invokeCommand(new SaveBridge(bridge));
  }

  /**
   * Get portal
   *
   * @return {Promise} Promise for chaining
   */
  getPortal() {
    let GetPortal = require('./Command/GetPortal');

    return this.invokeCommand(new GetPortal);
  }

  /**
   * Get software update
   *
   * @return {Promise} Promise for chaining
   */
  getSoftwareUpdate() {
    let GetSoftwareUpdate = require('./Command/GetSoftwareUpdate');

    return this.invokeCommand(new GetSoftwareUpdate);
  }

  /**
   * Check for software updates
   *
   * @return {Promise} Promise for chaining
   */
  checkForSoftwareUpdates() {
    let CheckForSoftwareUpdates = require('./Command/CheckForSoftwareUpdates');

    return this.invokeCommand(new CheckForSoftwareUpdates);
  }

  /**
   * Disable install notification
   *
   * @return {Promise} Promise for chaining
   */
  disableInstallNotification() {
    let DisableInstallNotification = require('./Command/DisableInstallNotification');

    return this.invokeCommand(new DisableInstallNotification);
  }

  /**
   * Install software updates
   *
   * @return {Promise} Promise for chaining
   */
  installSoftwareUpdates() {
    let InstallSoftwareUpdates = require('./Command/InstallSoftwareUpdates');

    return this.invokeCommand(new InstallSoftwareUpdates);
  }

  /**
   * Is authenticated
   *
   * @return {Promise} Promise for chaining
   */
  isAuthenticated() {
    let IsAuthenticated = require('./Command/IsAuthenticated');

    return this.invokeCommand(new IsAuthenticated);
  }

  /**
   * Get users
   *
   * @return {Promise} Promise for chaining
   */
  getUsers() {
    let GetUsers = require('./Command/GetUsers');

    return this.invokeCommand(new GetUsers);
  }

  /**
   * Get user
   *
   * @param {mixed} username Username or User object
   *
   * @return {Promise} Promise for chaining
   */
  getUser(username) {
    if (username === undefined) {
      username = this.username;
    }

    let GetUser = require('./Command/GetUser');

    return this.invokeCommand(new GetUser(username));
  }

  /**
   * Create user
   *
   * @param {string} deviceType Device type (optional)
   *
   * @return {Promise} Promise for chaining
   */
  createUser(deviceType) {
    let CreateUser = require('./Command/CreateUser');

    return this.invokeCommand(new CreateUser(deviceType));
  }

  /**
   * Delete user
   *
   * @param {mixed} username Username or User object
   *
   * @return {Promise} Promise for chaining
   */
  deleteUser(username) {
    let DeleteUser = require('./Command/DeleteUser');

    return this.invokeCommand(new DeleteUser(username));
  }

  /**
   * Start light scan
   *
   * @return {Promise} Promise for chaining
   */
  startLightScan() {
    let StartLightScan = require('./Command/StartLightScan');

    return this.invokeCommand(new StartLightScan);
  }

  /**
   * Get new lights
   *
   * @return {Promise} Promise for chaining
   */
  getNewLights() {
    let GetNewLights = require('./Command/GetNewLights');

    return this.invokeCommand(new GetNewLights);
  }

  /**
   * Get lights
   *
   * @return {Promise} Promise for chaining
   */
  getLights() {
    let GetLights = require('./Command/GetLights');

    return this.invokeCommand(new GetLights);
  }

  /**
   * Get light
   *
   * @param {mixed} lightId Light Id
   *
   * @return {Promise} Promise for chaining
   */
  getLight(lightId) {
    let GetLight = require('./Command/GetLight');

    return this.invokeCommand(new GetLight(lightId));
  }

  /**
   * Save light
   *
   * @param {Light} light Light
   *
   * @return {Promise} Promise for chaining
   */
  saveLight(light) {
    let SaveLight      = require('./Command/SaveLight');
    let SaveLightState = require('./Command/SaveLightState');

    return Promise.all([
      this.invokeCommand(new SaveLight(light)),
      this.invokeCommand(new SaveLightState(light))
    ]).then(() => {
      return light;
    });
  }

  /**
   * Delete light
   *
   * @param {mixed} light Light object or light id
   *
   * @return {Promise} Promise for chaining
   */
  deleteLight(light) {
    let DeleteLight = require('./Command/DeleteLight');

    return this.invokeCommand(new DeleteLight(light));
  }

  /**
   * Get groups
   *
   * @return {Promise} Promise for chaining
   */
  getGroups() {
    let GetGroups = require('./Command/GetGroups');

    return this.invokeCommand(new GetGroups);
  }

  /**
   * Get group
   *
   * @param {mixed} groupId Group Id
   *
   * @return {Promise} Promise for chaining
   */
  getGroup(groupId) {
    let GetGroup = require('./Command/GetGroup');

    return this.invokeCommand(new GetGroup(groupId));
  }

  /**
   * Create group
   *
   * @param {Group} group Group
   *
   * @return {Promise} Promise for chaining
   */
  createGroup(group) {
    let CreateGroup = require('./Command/CreateGroup');

    return this.invokeCommand(new CreateGroup(group));
  }

  /**
   * Save group
   *
   * @param {Group} group Group
   *
   * @return {Promise} Promise for chaining
   */
  saveGroup(group) {
    let SaveGroup      = require('./Command/SaveGroup');
    let SaveGroupState = require('./Command/SaveGroupState');

    return Promise.all([
      this.invokeCommand(new SaveGroup(group)),
      this.invokeCommand(new SaveGroupState(group))
    ]).then(() => {
      return group;
    });
  }

  /**
   * Delete group
   *
   * @param {Group} group Group object or group Id
   *
   * @return {Promise} Promise for chaining
   */
  deleteGroup(group) {
    let DeleteGroup = require('./Command/DeleteGroup');

    return this.invokeCommand(new DeleteGroup(group));
  }

  /**
   * Get scenes
   *
   * @return {Promise} Promise for chaining
   */
  getScenes() {
    let GetScenes = require('./Command/GetScenes');

    return this.invokeCommand(new GetScenes);
  }

  /**
   * Create scene
   *
   * @param {Scene} scene Scene
   *
   * @return {Promise} Promise for chaining
   */
  createScene(scene) {
    let CreateScene = require('./Command/CreateScene');

    return this.invokeCommand(new CreateScene(scene));
  }

  /**
   * Save scene light state
   *
   * @param {mixed} scene       Scene object or scene id
   * @param {Light} light       Light
   * @param {Array} filterState Filter state (optional)
   *
   * @return {Promise} Promise for chaining
   */
  saveSceneLightState(scene, light, filterState) {
    let SaveSceneLightState = require('./Command/SaveSceneLightState');

    return this.invokeCommand(
      new SaveSceneLightState(scene, light, filterState)
    );
  }

  /**
   * Get schedules
   *
   * @return {Promise} Promise for chaining
   */
  getSchedules() {
    let GetSchedules = require('./Command/GetSchedules');

    return this.invokeCommand(new GetSchedules);
  }

  /**
   * Get schedule
   *
   * @param {mixed} scheduleId Schedule Id
   *
   * @return {Promise} Promise for chaining
   */
  getSchedule(scheduleId) {
    let GetSchedule = require('./Command/GetSchedule');

    return this.invokeCommand(new GetSchedule(scheduleId));
  }

  /**
   * Create schedule
   *
   * @param {Schedule} schedule    Schedule
   * @param {mixed}    model       Model
   * @param {Array}    filterState Filter state (optional)
   *
   * @return {Promise} Promise for chaining
   */
  createSchedule(schedule, model, filterState) {
    let CreateSchedule = require('./Command/CreateSchedule');

    return this.invokeCommand(
      new CreateSchedule(schedule, model, filterState)
    );
  }

  /**
   * Save schedule
   *
   * @param {Schedule} schedule    Schedule
   * @param {mixed}    model       Model
   * @param {Array}    filterState Filter state (optional)
   *
   * @return {Promise} Promise for chaining
   */
  saveSchedule(schedule, model, filterState) {
    let SaveSchedule = require('./Command/SaveSchedule');

    return this.invokeCommand(
      new SaveSchedule(schedule, model, filterState)
    );
  }

  /**
   * Delete schedule
   *
   * @param {mixed} Schedule object or schedule Id
   *
   * @return {Promise} Promise for chaining
   */
  deleteSchedule(schedule) {
    let DeleteSchedule = require('./Command/DeleteSchedule');

    return this.invokeCommand(new DeleteSchedule(schedule));
  }

  /**
   * Start sensor scan
   *
   * @return {Promise} Promise for chaining
   */
  startSensorScan() {
    let StartSensorScan = require('./Command/StartSensorScan');

    return this.invokeCommand(new StartSensorScan);
  }

  /**
   * Get new sensors
   *
   * @return {Promise} Promise for chaining
   */
  getNewSensors() {
    let GetNewSensors = require('./Command/GetNewSensors');

    return this.invokeCommand(new GetNewSensors);
  }

  /**
   * Get sensors
   *
   * @return {Promise} Promise for chaining
   */
  getSensors() {
    let GetSensors = require('./Command/GetSensors');

    return this.invokeCommand(new GetSensors);
  }

  /**
   * Get sensor
   *
   * @param {mixed} sensorId Sensor Id
   *
   * @return {Promise} Promise for chaining
   */
  getSensor(sensorId) {
    let GetSensor = require('./Command/GetSensor');

    return this.invokeCommand(new GetSensor(sensorId));
  }

  /**
   * Create sensor
   *
   * @param {mixed} sensor Sensor
   *
   * @return {Promise} Promise for chaining
   */
  createSensor(sensor) {
    let CreateSensor = require('./Command/CreateSensor');

    return this.invokeCommand(new CreateSensor(sensor));
  }

  /**
   * Save sensor
   *
   * @param {Sensor} sensor Sensor
   *
   * @return {Promise} Promise for chaining
   */
  saveSensor(sensor) {
    let SaveSensor       = require('./Command/SaveSensor');
    let SaveSensorState  = require('./Command/SaveSensorState');
    let SaveSensorConfig = require('./Command/SaveSensorConfig');

    return Promise.all([
      this.invokeCommand(new SaveSensor(sensor)),
      this.invokeCommand(new SaveSensorState(sensor)),
      this.invokeCommand(new SaveSensorConfig(sensor))
    ]).then(() => {
      return sensor;
    });
  }

  /**
   * Delete sensor
   *
   * @param {mixed} sensor Sensor object or sensor id
   *
   * @return {Promise} Promise for chaining
   */
  deleteSensor(sensor) {
    let DeleteSensor = require('./Command/DeleteSensor');

    return this.invokeCommand(new DeleteSensor(sensor));
  }

  /**
   * Get rules accessor
   *
   * @return {mixed} Rules accessor
   */
  get rules() {
    if (!this.accessors.rules) {
      let RulesAccessor = require('./Accessor/Rules');

      this.accessors.rules = new RulesAccessor(this);
    }

    return this.accessors.rules;
  }

  /**
   * Get time zones
   *
   * @return {Promise} Promise for chaining
   */
  getTimeZones() {
    let GetTimeZones = require('./Command/GetTimeZones');

    return this.invokeCommand(new GetTimeZones);
  }

  /**
   * Get transport
   *
   * @return {Transport} Transport (http)
   */
  getTransport() {
    if (this.transport === undefined) {
      let Transport = new require('./Transport');

      this.transport = new Transport(this);
    }

    return this.transport;
  }

  /**
   * Invoke command
   *
   * @param {mixed} command Command
   *
   * @return {mixed} Result from command
   */
  invokeCommand(command) {
    return command.invoke(this);
  }
}

module.exports = Client;
<commit_msg>GitHub #15 - Refactor accessor loading, add time zones accessor<commit_after>'use strict';

const DEFAULT_CONFIG = {
  host:     undefined,
  username: undefined,
};

/**
 * Client
 *
 * Serves as client to the bridge
 */
class Client {
  /**
   * Constructor
   *
   * @param {Object} config Configuration
   */
  constructor(config) {
    this.config = Object.assign({}, DEFAULT_CONFIG, config);

    for (let key in config) {
      this[key] = config[key];
    }

    this.accessors = {};
  }

  /**
   * Get host
   *
   * @return {string} Host
   */
  get host() {
    return this.config.host;
  }

  /**
   * Set host
   *
   * @param {string} host Host
   */
  set host(host) {
    this.config.host = host;
  }

  /**
   * Get username
   *
   * @return {string} Username
   */
  get username() {
    return this.config.username;
  }

  /**
   * Set username
   *
   * @param  {string} username Username
   */
  set username(username) {
    this.config.username = username;
  }

  /**
   * Ping bridge
   *
   * @return {Promise} Promise for chaining
   */
  ping() {
    let Ping = require('./Command/Ping');

    return this.invokeCommand(new Ping);
  }

  /**
   * Get bridge
   *
   * @return {Promise} Promise for chaining
   */
  getBridge() {
    let GetBridge = require('./Command/GetBridge');

    return this.invokeCommand(new GetBridge);
  }

  /**
   * Save bridge
   *
   * @param {mixed} bridge Bridge
   *
   * @return {Promise} Promise for chaining
   */
  saveBridge(bridge) {
    let SaveBridge = require('./Command/SaveBridge');

    return this.invokeCommand(new SaveBridge(bridge));
  }

  /**
   * Get portal
   *
   * @return {Promise} Promise for chaining
   */
  getPortal() {
    let GetPortal = require('./Command/GetPortal');

    return this.invokeCommand(new GetPortal);
  }

  /**
   * Get software update
   *
   * @return {Promise} Promise for chaining
   */
  getSoftwareUpdate() {
    let GetSoftwareUpdate = require('./Command/GetSoftwareUpdate');

    return this.invokeCommand(new GetSoftwareUpdate);
  }

  /**
   * Check for software updates
   *
   * @return {Promise} Promise for chaining
   */
  checkForSoftwareUpdates() {
    let CheckForSoftwareUpdates = require('./Command/CheckForSoftwareUpdates');

    return this.invokeCommand(new CheckForSoftwareUpdates);
  }

  /**
   * Disable install notification
   *
   * @return {Promise} Promise for chaining
   */
  disableInstallNotification() {
    let DisableInstallNotification = require('./Command/DisableInstallNotification');

    return this.invokeCommand(new DisableInstallNotification);
  }

  /**
   * Install software updates
   *
   * @return {Promise} Promise for chaining
   */
  installSoftwareUpdates() {
    let InstallSoftwareUpdates = require('./Command/InstallSoftwareUpdates');

    return this.invokeCommand(new InstallSoftwareUpdates);
  }

  /**
   * Is authenticated
   *
   * @return {Promise} Promise for chaining
   */
  isAuthenticated() {
    let IsAuthenticated = require('./Command/IsAuthenticated');

    return this.invokeCommand(new IsAuthenticated);
  }

  /**
   * Get users
   *
   * @return {Promise} Promise for chaining
   */
  getUsers() {
    let GetUsers = require('./Command/GetUsers');

    return this.invokeCommand(new GetUsers);
  }

  /**
   * Get user
   *
   * @param {mixed} username Username or User object
   *
   * @return {Promise} Promise for chaining
   */
  getUser(username) {
    if (username === undefined) {
      username = this.username;
    }

    let GetUser = require('./Command/GetUser');

    return this.invokeCommand(new GetUser(username));
  }

  /**
   * Create user
   *
   * @param {string} deviceType Device type (optional)
   *
   * @return {Promise} Promise for chaining
   */
  createUser(deviceType) {
    let CreateUser = require('./Command/CreateUser');

    return this.invokeCommand(new CreateUser(deviceType));
  }

  /**
   * Delete user
   *
   * @param {mixed} username Username or User object
   *
   * @return {Promise} Promise for chaining
   */
  deleteUser(username) {
    let DeleteUser = require('./Command/DeleteUser');

    return this.invokeCommand(new DeleteUser(username));
  }

  /**
   * Start light scan
   *
   * @return {Promise} Promise for chaining
   */
  startLightScan() {
    let StartLightScan = require('./Command/StartLightScan');

    return this.invokeCommand(new StartLightScan);
  }

  /**
   * Get new lights
   *
   * @return {Promise} Promise for chaining
   */
  getNewLights() {
    let GetNewLights = require('./Command/GetNewLights');

    return this.invokeCommand(new GetNewLights);
  }

  /**
   * Get lights
   *
   * @return {Promise} Promise for chaining
   */
  getLights() {
    let GetLights = require('./Command/GetLights');

    return this.invokeCommand(new GetLights);
  }

  /**
   * Get light
   *
   * @param {mixed} lightId Light Id
   *
   * @return {Promise} Promise for chaining
   */
  getLight(lightId) {
    let GetLight = require('./Command/GetLight');

    return this.invokeCommand(new GetLight(lightId));
  }

  /**
   * Save light
   *
   * @param {Light} light Light
   *
   * @return {Promise} Promise for chaining
   */
  saveLight(light) {
    let SaveLight      = require('./Command/SaveLight');
    let SaveLightState = require('./Command/SaveLightState');

    return Promise.all([
      this.invokeCommand(new SaveLight(light)),
      this.invokeCommand(new SaveLightState(light))
    ]).then(() => {
      return light;
    });
  }

  /**
   * Delete light
   *
   * @param {mixed} light Light object or light id
   *
   * @return {Promise} Promise for chaining
   */
  deleteLight(light) {
    let DeleteLight = require('./Command/DeleteLight');

    return this.invokeCommand(new DeleteLight(light));
  }

  /**
   * Get groups
   *
   * @return {Promise} Promise for chaining
   */
  getGroups() {
    let GetGroups = require('./Command/GetGroups');

    return this.invokeCommand(new GetGroups);
  }

  /**
   * Get group
   *
   * @param {mixed} groupId Group Id
   *
   * @return {Promise} Promise for chaining
   */
  getGroup(groupId) {
    let GetGroup = require('./Command/GetGroup');

    return this.invokeCommand(new GetGroup(groupId));
  }

  /**
   * Create group
   *
   * @param {Group} group Group
   *
   * @return {Promise} Promise for chaining
   */
  createGroup(group) {
    let CreateGroup = require('./Command/CreateGroup');

    return this.invokeCommand(new CreateGroup(group));
  }

  /**
   * Save group
   *
   * @param {Group} group Group
   *
   * @return {Promise} Promise for chaining
   */
  saveGroup(group) {
    let SaveGroup      = require('./Command/SaveGroup');
    let SaveGroupState = require('./Command/SaveGroupState');

    return Promise.all([
      this.invokeCommand(new SaveGroup(group)),
      this.invokeCommand(new SaveGroupState(group))
    ]).then(() => {
      return group;
    });
  }

  /**
   * Delete group
   *
   * @param {Group} group Group object or group Id
   *
   * @return {Promise} Promise for chaining
   */
  deleteGroup(group) {
    let DeleteGroup = require('./Command/DeleteGroup');

    return this.invokeCommand(new DeleteGroup(group));
  }

  /**
   * Get scenes
   *
   * @return {Promise} Promise for chaining
   */
  getScenes() {
    let GetScenes = require('./Command/GetScenes');

    return this.invokeCommand(new GetScenes);
  }

  /**
   * Create scene
   *
   * @param {Scene} scene Scene
   *
   * @return {Promise} Promise for chaining
   */
  createScene(scene) {
    let CreateScene = require('./Command/CreateScene');

    return this.invokeCommand(new CreateScene(scene));
  }

  /**
   * Save scene light state
   *
   * @param {mixed} scene       Scene object or scene id
   * @param {Light} light       Light
   * @param {Array} filterState Filter state (optional)
   *
   * @return {Promise} Promise for chaining
   */
  saveSceneLightState(scene, light, filterState) {
    let SaveSceneLightState = require('./Command/SaveSceneLightState');

    return this.invokeCommand(
      new SaveSceneLightState(scene, light, filterState)
    );
  }

  /**
   * Get schedules
   *
   * @return {Promise} Promise for chaining
   */
  getSchedules() {
    let GetSchedules = require('./Command/GetSchedules');

    return this.invokeCommand(new GetSchedules);
  }

  /**
   * Get schedule
   *
   * @param {mixed} scheduleId Schedule Id
   *
   * @return {Promise} Promise for chaining
   */
  getSchedule(scheduleId) {
    let GetSchedule = require('./Command/GetSchedule');

    return this.invokeCommand(new GetSchedule(scheduleId));
  }

  /**
   * Create schedule
   *
   * @param {Schedule} schedule    Schedule
   * @param {mixed}    model       Model
   * @param {Array}    filterState Filter state (optional)
   *
   * @return {Promise} Promise for chaining
   */
  createSchedule(schedule, model, filterState) {
    let CreateSchedule = require('./Command/CreateSchedule');

    return this.invokeCommand(
      new CreateSchedule(schedule, model, filterState)
    );
  }

  /**
   * Save schedule
   *
   * @param {Schedule} schedule    Schedule
   * @param {mixed}    model       Model
   * @param {Array}    filterState Filter state (optional)
   *
   * @return {Promise} Promise for chaining
   */
  saveSchedule(schedule, model, filterState) {
    let SaveSchedule = require('./Command/SaveSchedule');

    return this.invokeCommand(
      new SaveSchedule(schedule, model, filterState)
    );
  }

  /**
   * Delete schedule
   *
   * @param {mixed} Schedule object or schedule Id
   *
   * @return {Promise} Promise for chaining
   */
  deleteSchedule(schedule) {
    let DeleteSchedule = require('./Command/DeleteSchedule');

    return this.invokeCommand(new DeleteSchedule(schedule));
  }

  /**
   * Start sensor scan
   *
   * @return {Promise} Promise for chaining
   */
  startSensorScan() {
    let StartSensorScan = require('./Command/StartSensorScan');

    return this.invokeCommand(new StartSensorScan);
  }

  /**
   * Get new sensors
   *
   * @return {Promise} Promise for chaining
   */
  getNewSensors() {
    let GetNewSensors = require('./Command/GetNewSensors');

    return this.invokeCommand(new GetNewSensors);
  }

  /**
   * Get sensors
   *
   * @return {Promise} Promise for chaining
   */
  getSensors() {
    let GetSensors = require('./Command/GetSensors');

    return this.invokeCommand(new GetSensors);
  }

  /**
   * Get sensor
   *
   * @param {mixed} sensorId Sensor Id
   *
   * @return {Promise} Promise for chaining
   */
  getSensor(sensorId) {
    let GetSensor = require('./Command/GetSensor');

    return this.invokeCommand(new GetSensor(sensorId));
  }

  /**
   * Create sensor
   *
   * @param {mixed} sensor Sensor
   *
   * @return {Promise} Promise for chaining
   */
  createSensor(sensor) {
    let CreateSensor = require('./Command/CreateSensor');

    return this.invokeCommand(new CreateSensor(sensor));
  }

  /**
   * Save sensor
   *
   * @param {Sensor} sensor Sensor
   *
   * @return {Promise} Promise for chaining
   */
  saveSensor(sensor) {
    let SaveSensor       = require('./Command/SaveSensor');
    let SaveSensorState  = require('./Command/SaveSensorState');
    let SaveSensorConfig = require('./Command/SaveSensorConfig');

    return Promise.all([
      this.invokeCommand(new SaveSensor(sensor)),
      this.invokeCommand(new SaveSensorState(sensor)),
      this.invokeCommand(new SaveSensorConfig(sensor))
    ]).then(() => {
      return sensor;
    });
  }

  /**
   * Delete sensor
   *
   * @param {mixed} sensor Sensor object or sensor id
   *
   * @return {Promise} Promise for chaining
   */
  deleteSensor(sensor) {
    let DeleteSensor = require('./Command/DeleteSensor');

    return this.invokeCommand(new DeleteSensor(sensor));
  }

  /**
   * Get rules accessor
   *
   * @return {mixed} Rules accessor
   */
  get rules() {
    return this.loadAccessor('Rules');
  }

  /**
   * Get time zones accessor
   *
   * @return {mixed} Time zones accessor
   */
  get timeZones() {
    return this.loadAccessor('TimeZones');
  }

  /**
   * Load accessor
   *
   * @param {string} accessor Accessor name
   *
   * @return {mixed} Accessor
   */
  loadAccessor(accessor) {
    if (!this.accessors[accessor]) {
      let Accessor = require(`./Accessor/${accessor}`);

      this.accessors[accessor] = new Accessor(this);
    }

    return this.accessors[accessor];
  }

  /**
   * Get transport
   *
   * @return {Transport} Transport (http)
   */
  getTransport() {
    if (this.transport === undefined) {
      let Transport = new require('./Transport');

      this.transport = new Transport(this);
    }

    return this.transport;
  }

  /**
   * Invoke command
   *
   * @param {mixed} command Command
   *
   * @return {mixed} Result from command
   */
  invokeCommand(command) {
    return command.invoke(this);
  }
}

module.exports = Client;
<|endoftext|>


<commit_before>jQuery(function ($) {

    $("form").bind("orchard-admin-contentpicker-open", function (ev, data) {
        data = data || {};
        // the popup will be doing full page reloads, so will not be able to retain
        // a pointer to the callback. We will generate a temporary callback
        // with a known/unique name and pass that in on the querystring so it
        // is remembers across reloads. Once executed, it calls the real callback
        // and removes itself.
        var callbackName = "_contentpicker_" + new Date().getTime();
        data.callbackName = callbackName;
        $[callbackName] = function (returnData) {
            delete $[callbackName];
            data.callback(returnData);
        };
        $[callbackName].data = data;

        var baseUrl = data.baseUrl;

        // remove trailing slash if any
        if (baseUrl.substr(-1) == '/')
            baseUrl = baseUrl.substr(0, baseUrl.length - 1);

        var url = baseUrl
            + "/Admin/Orchard.ContentPicker?"
            + "callback=" + callbackName
            + "&" + (new Date() - 0);

        if (data.part) {
            url += "&part=" + encodeURIComponent(data.part);
        }

        if (data.field) {
            url += "&field=" + encodeURIComponent(data.field);
        }

        var w = window.open(url, "_blank", data.windowFeatures || "width=685,height=700,status=no,toolbar=no,location=no,menubar=no,resizable=no,scrollbars=yes");
    });
});<commit_msg>19557 fix for IE<commit_after>jQuery(function ($) {

    $("form").bind("orchard-admin-contentpicker-open", function (ev, data) {
        data = data || {};
        // the popup will be doing full page reloads, so will not be able to retain
        // a pointer to the callback. We will generate a temporary callback
        // with a known/unique name and pass that in on the querystring so it
        // is remembers across reloads. Once executed, it calls the real callback
        // and removes itself.
        var callbackName = "_contentpicker_" + new Date().getTime();
        data.callbackName = callbackName;
        $[callbackName] = function (returnData) {
            delete $[callbackName];
            data.callback(returnData);
        };
        $[callbackName].data = data;

        var baseUrl = data.baseUrl;

        // remove trailing slash if any
        if (baseUrl.slice(-1) == '/')
            baseUrl = baseUrl.substr(0, baseUrl.length - 1);

        var url = baseUrl
            + "/Admin/Orchard.ContentPicker?"
            + "callback=" + callbackName
            + "&" + (new Date() - 0);

        if (data.part) {
            url += "&part=" + encodeURIComponent(data.part);
        }

        if (data.field) {
            url += "&field=" + encodeURIComponent(data.field);
        }

        var w = window.open(url, "_blank", data.windowFeatures || "width=685,height=700,status=no,toolbar=no,location=no,menubar=no,resizable=no,scrollbars=yes");
    });
});<|endoftext|>


<commit_before>'use strict'

const {Buffer} = require('buffer')
const electron = require('electron')
const v8Util = process.atomBinding('v8_util')
const {ipcMain, isPromise, webContents} = electron

const fs = require('fs')

const objectsRegistry = require('./objects-registry')

const hasProp = {}.hasOwnProperty

// The internal properties of Function.
const FUNCTION_PROPERTIES = [
  'length', 'name', 'arguments', 'caller', 'prototype'
]

// The remote functions in renderer processes.
// id => Function
let rendererFunctions = v8Util.createDoubleIDWeakMap()

// Return the description of object's members:
let getObjectMembers = function (object) {
  let names = Object.getOwnPropertyNames(object)
  // For Function, we should not override following properties even though they
  // are "own" properties.
  if (typeof object === 'function') {
    names = names.filter((name) => {
      return !FUNCTION_PROPERTIES.includes(name)
    })
  }
  // Map properties to descriptors.
  return names.map((name) => {
    let descriptor = Object.getOwnPropertyDescriptor(object, name)
    let member = {name, enumerable: descriptor.enumerable, writable: false}
    if (descriptor.get === undefined && typeof object[name] === 'function') {
      member.type = 'method'
    } else {
      if (descriptor.set || descriptor.writable) member.writable = true
      member.type = 'get'
    }
    return member
  })
}

// Return the description of object's prototype.
let getObjectPrototype = function (object) {
  let proto = Object.getPrototypeOf(object)
  if (proto === null || proto === Object.prototype) return null
  return {
    members: getObjectMembers(proto),
    proto: getObjectPrototype(proto)
  }
}

// Convert a real value into meta data.
let valueToMeta = function (sender, value, optimizeSimpleObject = false) {
  // Determine the type of value.
  const meta = { type: typeof value }
  if (meta.type === 'object') {
    // Recognize certain types of objects.
    if (value === null) {
      meta.type = 'value'
    } else if (ArrayBuffer.isView(value)) {
      meta.type = 'buffer'
    } else if (Array.isArray(value)) {
      meta.type = 'array'
    } else if (value instanceof Error) {
      meta.type = 'error'
    } else if (value instanceof Date) {
      meta.type = 'date'
    } else if (isPromise(value)) {
      meta.type = 'promise'
    } else if (hasProp.call(value, 'callee') && value.length != null) {
      // Treat the arguments object as array.
      meta.type = 'array'
    } else if (optimizeSimpleObject && v8Util.getHiddenValue(value, 'simple')) {
      // Treat simple objects as value.
      meta.type = 'value'
    }
  }

  // Fill the meta object according to value's type.
  if (meta.type === 'array') {
    meta.members = value.map((el) => valueToMeta(sender, el))
  } else if (meta.type === 'object' || meta.type === 'function') {
    meta.name = value.constructor ? value.constructor.name : ''

    // Reference the original value if it's an object, because when it's
    // passed to renderer we would assume the renderer keeps a reference of
    // it.
    meta.id = objectsRegistry.add(sender, value)
    meta.members = getObjectMembers(value)
    meta.proto = getObjectPrototype(value)
  } else if (meta.type === 'buffer') {
    meta.value = Buffer.from(value)
  } else if (meta.type === 'promise') {
    // Add default handler to prevent unhandled rejections in main process
    // Instead they should appear in the renderer process
    value.then(function () {}, function () {})

    meta.then = valueToMeta(sender, function (onFulfilled, onRejected) {
      value.then(onFulfilled, onRejected)
    })
  } else if (meta.type === 'error') {
    meta.members = plainObjectToMeta(value)

    // Error.name is not part of own properties.
    meta.members.push({
      name: 'name',
      value: value.name
    })
  } else if (meta.type === 'date') {
    meta.value = value.getTime()
  } else {
    meta.type = 'value'
    meta.value = value
  }
  return meta
}

// Convert object to meta by value.
const plainObjectToMeta = function (obj) {
  return Object.getOwnPropertyNames(obj).map(function (name) {
    return {
      name: name,
      value: obj[name]
    }
  })
}

// Convert Error into meta data.
const exceptionToMeta = function (error) {
  return {
    type: 'exception',
    message: error.message,
    stack: error.stack || error
  }
}

const throwRPCError = function (message) {
  const error = new Error(message)
  error.code = 'EBADRPC'
  error.errno = -72
  throw error
}

const rendererMissingErrorMessage = (meta, args, callIntoRenderer) => {
  let message = `Attempting to call a function in a renderer window that has been closed or released.` +
    `\nFunction provided here: ${meta.location}`

  if (args.length === 0) return message
  if (!args[0].sender || !args[0].sender._events) return message

  const eventsAttached = args[0].sender._events
  const remoteEvents = Object.keys(eventsAttached).filter((eventName) => {
    return Array.isArray(eventsAttached[eventName])
      ? eventsAttached[eventName].includes(callIntoRenderer)
      : eventsAttached[eventName] === callIntoRenderer
  })

  if (remoteEvents.length > 0) {
    message += `\nRemote event names: ${remoteEvents.join(', ')}`
  }

  return message
}

// Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender, args) {
  const metaToValue = function (meta) {
    let i, len, member, ref, returnValue
    switch (meta.type) {
      case 'value':
        return meta.value
      case 'remote-object':
        return objectsRegistry.get(meta.id)
      case 'array':
        return unwrapArgs(sender, meta.value)
      case 'buffer':
        return Buffer.from(meta.value)
      case 'date':
        return new Date(meta.value)
      case 'promise':
        return Promise.resolve({
          then: metaToValue(meta.then)
        })
      case 'object': {
        let ret = {}
        Object.defineProperty(ret.constructor, 'name', { value: meta.name })

        ref = meta.members
        for (i = 0, len = ref.length; i < len; i++) {
          member = ref[i]
          ret[member.name] = metaToValue(member.value)
        }
        return ret
      }
      case 'function-with-return-value':
        returnValue = metaToValue(meta.value)
        return function () {
          return returnValue
        }
      case 'function': {
        // Merge webContentsId and meta.id, since meta.id can be the same in
        // different webContents.
        const webContentsId = sender.getId()
        const objectId = [webContentsId, meta.id]

        // Cache the callbacks in renderer.
        if (rendererFunctions.has(objectId)) {
          return rendererFunctions.get(objectId)
        }

        let callIntoRenderer = function (...args) {
          if (!sender.isDestroyed() && webContentsId === sender.getId()) {
            sender.send('ELECTRON_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args))
          } else {
            throw new Error(rendererMissingErrorMessage(meta, args, callIntoRenderer))
          }
        }

        v8Util.setRemoteCallbackFreer(callIntoRenderer, meta.id, sender)
        rendererFunctions.set(objectId, callIntoRenderer)
        return callIntoRenderer
      }
      default:
        throw new TypeError(`Unknown type: ${meta.type}`)
    }
  }
  return args.map(metaToValue)
}

// Call a function and send reply asynchronously if it's a an asynchronous
// style function and the caller didn't pass a callback.
const callFunction = function (event, func, caller, args) {
  let funcMarkedAsync, funcName, funcPassedCallback, ref, ret
  funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous')
  funcPassedCallback = typeof args[args.length - 1] === 'function'
  try {
    if (funcMarkedAsync && !funcPassedCallback) {
      args.push(function (ret) {
        event.returnValue = valueToMeta(event.sender, ret, true)
      })
      func.apply(caller, args)
    } else {
      ret = func.apply(caller, args)
      event.returnValue = valueToMeta(event.sender, ret, true)
    }
  } catch (error) {
    // Catch functions thrown further down in function invocation and wrap
    // them with the function name so it's easier to trace things like
    // `Error processing argument -1.`
    funcName = ((ref = func.name) != null) ? ref : 'anonymous'
    throw new Error(`Could not call remote function '${funcName}'. Check that the function signature is correct. Underlying error: ${error.message}`)
  }
}

ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, process.mainModule.require(module))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_READ_FILE', function (event, file) {
  fs.readFile(file, (err, data) => {
    if (err) event.returnValue = {err: err.message}
    else event.returnValue = {data: data.toString()}
  })
})

ipcMain.on('ELECTRON_BROWSER_GET_BUILTIN', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, electron[module])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_GLOBAL', function (event, name) {
  try {
    event.returnValue = valueToMeta(event.sender, global[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WINDOW', function (event) {
  try {
    event.returnValue = valueToMeta(event.sender, event.sender.getOwnerBrowserWindow())
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event) {
  event.returnValue = valueToMeta(event.sender, event.sender)
})

ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let constructor = objectsRegistry.get(id)

    if (constructor == null) {
      throwRPCError(`Cannot call constructor on missing remote object ${id}`)
    }

    // Call new with array of arguments.
    // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))()
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let func = objectsRegistry.get(id)

    if (func == null) {
      throwRPCError(`Cannot call function on missing remote object ${id}`)
    }

    callFunction(event, func, global, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let object = objectsRegistry.get(id)

    if (object == null) {
      throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
    }

    // Call new with array of arguments.
    let constructor = object[method]
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))()
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let obj = objectsRegistry.get(id)

    if (obj == null) {
      throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`)
    }

    callFunction(event, obj[method], obj, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, value) {
  try {
    let obj = objectsRegistry.get(id)

    if (obj == null) {
      throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
    }

    obj[name] = value
    event.returnValue = null
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, id, name) {
  try {
    let obj = objectsRegistry.get(id)

    if (obj == null) {
      throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
    }

    event.returnValue = valueToMeta(event.sender, obj[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, id) {
  objectsRegistry.remove(event.sender.getId(), id)
})

ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, guestInstanceId) {
  try {
    let guestViewManager = require('./guest-view-manager')
    event.returnValue = valueToMeta(event.sender, guestViewManager.getGuest(guestInstanceId))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, requestId, guestInstanceId, method, ...args) {
  try {
    let guestViewManager = require('./guest-view-manager')
    let guest = guestViewManager.getGuest(guestInstanceId)
    if (requestId) {
      const responseCallback = function (result) {
        event.sender.send(`ELECTRON_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, result)
      }
      args.push(responseCallback)
    }
    guest[method].apply(guest, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_SEND_TO', function (event, sendToAll, webContentsId, channel, ...args) {
  let contents = webContents.fromId(webContentsId)
  if (!contents) {
    console.error(`Sending message to WebContents with unknown ID ${webContentsId}`)
    return
  }

  if (sendToAll) {
    contents.sendToAll(channel, ...args)
  } else {
    contents.send(channel, ...args)
  }
})

// Implements window.alert(message, title)
ipcMain.on('ELECTRON_BROWSER_WINDOW_ALERT', function (event, message, title) {
  if (message == null) message = ''
  if (title == null) title = ''

  event.returnValue = electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), {
    message: `${message}`,
    title: `${title}`,
    buttons: ['OK']
  })
})

// Implements window.confirm(message, title)
ipcMain.on('ELECTRON_BROWSER_WINDOW_CONFIRM', function (event, message, title) {
  if (message == null) message = ''
  if (title == null) title = ''

  event.returnValue = !electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), {
    message: `${message}`,
    title: `${title}`,
    buttons: ['OK', 'Cancel'],
    cancelId: 1
  })
})

// Implements window.close()
ipcMain.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
  event.sender.getOwnerBrowserWindow().close()
  event.returnValue = null
})
<commit_msg>Use EventEmitter public methods instead of _events.<commit_after>'use strict'

const {Buffer} = require('buffer')
const electron = require('electron')
const v8Util = process.atomBinding('v8_util')
const {ipcMain, isPromise, webContents} = electron

const fs = require('fs')

const objectsRegistry = require('./objects-registry')

const hasProp = {}.hasOwnProperty

// The internal properties of Function.
const FUNCTION_PROPERTIES = [
  'length', 'name', 'arguments', 'caller', 'prototype'
]

// The remote functions in renderer processes.
// id => Function
let rendererFunctions = v8Util.createDoubleIDWeakMap()

// Return the description of object's members:
let getObjectMembers = function (object) {
  let names = Object.getOwnPropertyNames(object)
  // For Function, we should not override following properties even though they
  // are "own" properties.
  if (typeof object === 'function') {
    names = names.filter((name) => {
      return !FUNCTION_PROPERTIES.includes(name)
    })
  }
  // Map properties to descriptors.
  return names.map((name) => {
    let descriptor = Object.getOwnPropertyDescriptor(object, name)
    let member = {name, enumerable: descriptor.enumerable, writable: false}
    if (descriptor.get === undefined && typeof object[name] === 'function') {
      member.type = 'method'
    } else {
      if (descriptor.set || descriptor.writable) member.writable = true
      member.type = 'get'
    }
    return member
  })
}

// Return the description of object's prototype.
let getObjectPrototype = function (object) {
  let proto = Object.getPrototypeOf(object)
  if (proto === null || proto === Object.prototype) return null
  return {
    members: getObjectMembers(proto),
    proto: getObjectPrototype(proto)
  }
}

// Convert a real value into meta data.
let valueToMeta = function (sender, value, optimizeSimpleObject = false) {
  // Determine the type of value.
  const meta = { type: typeof value }
  if (meta.type === 'object') {
    // Recognize certain types of objects.
    if (value === null) {
      meta.type = 'value'
    } else if (ArrayBuffer.isView(value)) {
      meta.type = 'buffer'
    } else if (Array.isArray(value)) {
      meta.type = 'array'
    } else if (value instanceof Error) {
      meta.type = 'error'
    } else if (value instanceof Date) {
      meta.type = 'date'
    } else if (isPromise(value)) {
      meta.type = 'promise'
    } else if (hasProp.call(value, 'callee') && value.length != null) {
      // Treat the arguments object as array.
      meta.type = 'array'
    } else if (optimizeSimpleObject && v8Util.getHiddenValue(value, 'simple')) {
      // Treat simple objects as value.
      meta.type = 'value'
    }
  }

  // Fill the meta object according to value's type.
  if (meta.type === 'array') {
    meta.members = value.map((el) => valueToMeta(sender, el))
  } else if (meta.type === 'object' || meta.type === 'function') {
    meta.name = value.constructor ? value.constructor.name : ''

    // Reference the original value if it's an object, because when it's
    // passed to renderer we would assume the renderer keeps a reference of
    // it.
    meta.id = objectsRegistry.add(sender, value)
    meta.members = getObjectMembers(value)
    meta.proto = getObjectPrototype(value)
  } else if (meta.type === 'buffer') {
    meta.value = Buffer.from(value)
  } else if (meta.type === 'promise') {
    // Add default handler to prevent unhandled rejections in main process
    // Instead they should appear in the renderer process
    value.then(function () {}, function () {})

    meta.then = valueToMeta(sender, function (onFulfilled, onRejected) {
      value.then(onFulfilled, onRejected)
    })
  } else if (meta.type === 'error') {
    meta.members = plainObjectToMeta(value)

    // Error.name is not part of own properties.
    meta.members.push({
      name: 'name',
      value: value.name
    })
  } else if (meta.type === 'date') {
    meta.value = value.getTime()
  } else {
    meta.type = 'value'
    meta.value = value
  }
  return meta
}

// Convert object to meta by value.
const plainObjectToMeta = function (obj) {
  return Object.getOwnPropertyNames(obj).map(function (name) {
    return {
      name: name,
      value: obj[name]
    }
  })
}

// Convert Error into meta data.
const exceptionToMeta = function (error) {
  return {
    type: 'exception',
    message: error.message,
    stack: error.stack || error
  }
}

const throwRPCError = function (message) {
  const error = new Error(message)
  error.code = 'EBADRPC'
  error.errno = -72
  throw error
}

const rendererMissingErrorMessage = (meta, args, callIntoRenderer) => {
  let message = `Attempting to call a function in a renderer window that has been closed or released.` +
    `\nFunction provided here: ${meta.location}`

  if (args.length === 0) return message
  if (!args[0].sender || !args[0].sender.eventNames) return message

  const sender = args[0].sender
  const remoteEvents = sender.eventNames().filter((eventName) => {
    return sender.listeners(eventName).includes(callIntoRenderer);
  })

  if (remoteEvents.length > 0) {
    message += `\nRemote event names: ${remoteEvents.join(', ')}`
  }

  return message
}

// Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender, args) {
  const metaToValue = function (meta) {
    let i, len, member, ref, returnValue
    switch (meta.type) {
      case 'value':
        return meta.value
      case 'remote-object':
        return objectsRegistry.get(meta.id)
      case 'array':
        return unwrapArgs(sender, meta.value)
      case 'buffer':
        return Buffer.from(meta.value)
      case 'date':
        return new Date(meta.value)
      case 'promise':
        return Promise.resolve({
          then: metaToValue(meta.then)
        })
      case 'object': {
        let ret = {}
        Object.defineProperty(ret.constructor, 'name', { value: meta.name })

        ref = meta.members
        for (i = 0, len = ref.length; i < len; i++) {
          member = ref[i]
          ret[member.name] = metaToValue(member.value)
        }
        return ret
      }
      case 'function-with-return-value':
        returnValue = metaToValue(meta.value)
        return function () {
          return returnValue
        }
      case 'function': {
        // Merge webContentsId and meta.id, since meta.id can be the same in
        // different webContents.
        const webContentsId = sender.getId()
        const objectId = [webContentsId, meta.id]

        // Cache the callbacks in renderer.
        if (rendererFunctions.has(objectId)) {
          return rendererFunctions.get(objectId)
        }

        let callIntoRenderer = function (...args) {
          if (!sender.isDestroyed() && webContentsId === sender.getId()) {
            sender.send('ELECTRON_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args))
          } else {
            throw new Error(rendererMissingErrorMessage(meta, args, callIntoRenderer))
          }
        }

        v8Util.setRemoteCallbackFreer(callIntoRenderer, meta.id, sender)
        rendererFunctions.set(objectId, callIntoRenderer)
        return callIntoRenderer
      }
      default:
        throw new TypeError(`Unknown type: ${meta.type}`)
    }
  }
  return args.map(metaToValue)
}

// Call a function and send reply asynchronously if it's a an asynchronous
// style function and the caller didn't pass a callback.
const callFunction = function (event, func, caller, args) {
  let funcMarkedAsync, funcName, funcPassedCallback, ref, ret
  funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous')
  funcPassedCallback = typeof args[args.length - 1] === 'function'
  try {
    if (funcMarkedAsync && !funcPassedCallback) {
      args.push(function (ret) {
        event.returnValue = valueToMeta(event.sender, ret, true)
      })
      func.apply(caller, args)
    } else {
      ret = func.apply(caller, args)
      event.returnValue = valueToMeta(event.sender, ret, true)
    }
  } catch (error) {
    // Catch functions thrown further down in function invocation and wrap
    // them with the function name so it's easier to trace things like
    // `Error processing argument -1.`
    funcName = ((ref = func.name) != null) ? ref : 'anonymous'
    throw new Error(`Could not call remote function '${funcName}'. Check that the function signature is correct. Underlying error: ${error.message}`)
  }
}

ipcMain.on('ELECTRON_BROWSER_REQUIRE', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, process.mainModule.require(module))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_READ_FILE', function (event, file) {
  fs.readFile(file, (err, data) => {
    if (err) event.returnValue = {err: err.message}
    else event.returnValue = {data: data.toString()}
  })
})

ipcMain.on('ELECTRON_BROWSER_GET_BUILTIN', function (event, module) {
  try {
    event.returnValue = valueToMeta(event.sender, electron[module])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_GLOBAL', function (event, name) {
  try {
    event.returnValue = valueToMeta(event.sender, global[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WINDOW', function (event) {
  try {
    event.returnValue = valueToMeta(event.sender, event.sender.getOwnerBrowserWindow())
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event) {
  event.returnValue = valueToMeta(event.sender, event.sender)
})

ipcMain.on('ELECTRON_BROWSER_CONSTRUCTOR', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let constructor = objectsRegistry.get(id)

    if (constructor == null) {
      throwRPCError(`Cannot call constructor on missing remote object ${id}`)
    }

    // Call new with array of arguments.
    // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))()
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_FUNCTION_CALL', function (event, id, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let func = objectsRegistry.get(id)

    if (func == null) {
      throwRPCError(`Cannot call function on missing remote object ${id}`)
    }

    callFunction(event, func, global, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let object = objectsRegistry.get(id)

    if (object == null) {
      throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
    }

    // Call new with array of arguments.
    let constructor = object[method]
    let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))()
    event.returnValue = valueToMeta(event.sender, obj)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) {
  try {
    args = unwrapArgs(event.sender, args)
    let obj = objectsRegistry.get(id)

    if (obj == null) {
      throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`)
    }

    callFunction(event, obj[method], obj, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_SET', function (event, id, name, value) {
  try {
    let obj = objectsRegistry.get(id)

    if (obj == null) {
      throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
    }

    obj[name] = value
    event.returnValue = null
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_MEMBER_GET', function (event, id, name) {
  try {
    let obj = objectsRegistry.get(id)

    if (obj == null) {
      throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
    }

    event.returnValue = valueToMeta(event.sender, obj[name])
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_DEREFERENCE', function (event, id) {
  objectsRegistry.remove(event.sender.getId(), id)
})

ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, guestInstanceId) {
  try {
    let guestViewManager = require('./guest-view-manager')
    event.returnValue = valueToMeta(event.sender, guestViewManager.getGuest(guestInstanceId))
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function (event, requestId, guestInstanceId, method, ...args) {
  try {
    let guestViewManager = require('./guest-view-manager')
    let guest = guestViewManager.getGuest(guestInstanceId)
    if (requestId) {
      const responseCallback = function (result) {
        event.sender.send(`ELECTRON_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, result)
      }
      args.push(responseCallback)
    }
    guest[method].apply(guest, args)
  } catch (error) {
    event.returnValue = exceptionToMeta(error)
  }
})

ipcMain.on('ELECTRON_BROWSER_SEND_TO', function (event, sendToAll, webContentsId, channel, ...args) {
  let contents = webContents.fromId(webContentsId)
  if (!contents) {
    console.error(`Sending message to WebContents with unknown ID ${webContentsId}`)
    return
  }

  if (sendToAll) {
    contents.sendToAll(channel, ...args)
  } else {
    contents.send(channel, ...args)
  }
})

// Implements window.alert(message, title)
ipcMain.on('ELECTRON_BROWSER_WINDOW_ALERT', function (event, message, title) {
  if (message == null) message = ''
  if (title == null) title = ''

  event.returnValue = electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), {
    message: `${message}`,
    title: `${title}`,
    buttons: ['OK']
  })
})

// Implements window.confirm(message, title)
ipcMain.on('ELECTRON_BROWSER_WINDOW_CONFIRM', function (event, message, title) {
  if (message == null) message = ''
  if (title == null) title = ''

  event.returnValue = !electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), {
    message: `${message}`,
    title: `${title}`,
    buttons: ['OK', 'Cancel'],
    cancelId: 1
  })
})

// Implements window.close()
ipcMain.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
  event.sender.getOwnerBrowserWindow().close()
  event.returnValue = null
})
<|endoftext|>


<commit_before>/*global module*/var today=20160814;module.exports=today;<commit_msg>back dating today.js to ensure JSLint installs on the test runners<commit_after>/*global module*/var today=20160811;module.exports=today;
<|endoftext|>


<commit_before>'use strict';

class AnimatedValue {
  constructor(value) {
    this.write(value);
  }

  get() {
    if (this.timeout) {
      const now = performance.now();
      const end = this.frTime + this.timeout;
      if (now >= end) {
        this.timeout = 0;
        return this.toVal;
      } else {
        if (this.following) {
          this.toVal = this.following();
        }
        return this.toVal - (this.toVal - this.frVal) * (end - now) / this.timeout;
      }
    } else {
      return this.toVal;
    }
  }

  set(value, timeout) {
    if (value != this.toVal) {
      this.frVal = this.get();
      this.toVal = value;
      this.timeout = timeout;
      this.following = undefined;
      this.frTime = performance.now();
    }
  }

  follow(following, timeout) {
    this.frVal = this.get();
    this.following = following;
    this.timeout = timeout;
    this.frTime = performance.now();
  }

  write(value) {
    this.frVal = value;
    this.toVal = value;
    this.timeout = 0;
    this.frTime = performance.now(); // so end == now
  }
}

module.exports = AnimatedValue;
<commit_msg>NEXT-36 Make AnimatedValue use Date.now() instead of performance.now()<commit_after>'use strict';

class AnimatedValue {
  constructor(value) {
    this.write(value);
  }

  get() {
    if (this.timeout) {
      const now = Date.now();
      const end = this.frTime + this.timeout;
      if (now >= end) {
        this.timeout = 0;
        return this.toVal;
      } else {
        if (this.following) {
          this.toVal = this.following();
        }
        return this.toVal - (this.toVal - this.frVal) * (end - now) / this.timeout;
      }
    } else {
      return this.toVal;
    }
  }

  set(value, timeout) {
    if (value != this.toVal) {
      this.frVal = this.get();
      this.toVal = value;
      this.timeout = timeout;
      this.following = undefined;
      this.frTime = Date.now();
    }
  }

  follow(following, timeout) {
    this.frVal = this.get();
    this.following = following;
    this.timeout = timeout;
    this.frTime = Date.now();
  }

  write(value) {
    this.frVal = value;
    this.toVal = value;
    this.timeout = 0;
    this.frTime = Date.now(); // so end == now
  }
}

module.exports = AnimatedValue;
<|endoftext|>


<commit_before>import fetch from 'isomorphic-fetch'
import moment from 'moment'

import * as types from '../constants/ActionTypes'
import { requireLoginBeforeAction } from './LoginActions'
import { showModal } from './ModalActions'
import ModalComponents from '../constants/ModalComponents'
import Errors from '../constants/Errors'
import * as ProfileActions from './ProfileActions'
import { action, errorAction } from './GenericActions'

export function changePickupLocation (reserveId, branchCode) {
  const url = '/api/v1/holds/'
  return dispatch => {
    dispatch(requestChangePickupLocation(reserveId, branchCode))
    return fetch(url, {
      method: 'PATCH',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ reserveId, branchCode })
    })
      .then(response => {
        if (response.status === 200) {
          setTimeout(() => {
            dispatch(changePickupLocationSuccess(reserveId, branchCode))
          }, 500)
        } else {
          throw Error(Errors.reservation.GENERIC_CHANGE_PICKUP_LOCATION_ERROR)
        }
      })
      .catch(error => dispatch(changePickupLocationFailure(error)))
  }
}

export const requestChangePickupLocation = (reserveId, branchCode) => action(types.REQUEST_CHANGE_PICKUP_LOCATION, {
  reserveId,
  branchCode
})

export const changePickupLocationSuccess = (reserveId, branchCode) => action(types.CHANGE_PICKUP_LOCATION_SUCCESS, {
  reserveId,
  branchCode
})

export const changePickupLocationFailure = error => errorAction(types.CHANGE_PICKUP_LOCATION_FAILURE, error)

export function suspendReservation (reserveId, suspended) {
  return dispatch => {
    if (suspended) {
      return dispatch(showModal(ModalComponents.POSTPONE_RESERVATION, { isSuccess: true, reserveId: reserveId, suspended: suspended }))
    }
    return dispatch(changeReservationSuspension(reserveId, suspended))
  }
}

export function changeReservationSuspension (reserveId, suspended, date) {
  let suspendUntil

  if (date) {
    suspendUntil = moment(date, 'DD.MM.YYYY').format('YYYY-MM-DD')
  } else {
    suspendUntil = null
  }

  const url = '/api/v1/holds/'
  return dispatch => {
    dispatch(requestChangeReservationSuspension(reserveId, suspended, suspendUntil))
    return fetch(url, {
      method: 'PATCH',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ reserveId, suspended, suspendUntil })
    })
      .then(response => {
        if (response.status === 200) {
          setTimeout(() => {
            dispatch(changeReservationSuspensionSuccess(reserveId, suspended, suspendUntil))
          }, 500)
        } else {
          throw Error(Errors.reservation.GENERIC_CHANGE_RESERVATION_SUSPENSION_ERROR)
        }
      })
      .catch(error => dispatch(changeReservationSuspensionFailure(error)))
  }
}

export const requestChangeReservationSuspension = (reserveId, suspended, suspendUntil) => action(types.REQUEST_CHANGE_RESERVATION_SUSPENSION, {
  reserveId,
  suspended,
  suspendUntil
})

export const changeReservationSuspensionSuccess = (reserveId, suspended, suspendUntil) => action(types.CHANGE_RESERVATION_SUSPENSION_SUCCESS, {
  reserveId,
  suspended,
  suspendUntil
})

export const changeReservationSuspensionFailure = error => errorAction(types.CHANGE_PICKUP_LOCATION_FAILURE, error)

export function startReservation (publication) {
  return requireLoginBeforeAction(showModal(ModalComponents.RESERVATION, { publication: publication }))
}

export function requestReservePublication (recordId, branchCode) {
  return {
    type: types.REQUEST_RESERVE_PUBLICATION,
    payload: {
      recordId: recordId,
      branchCode: branchCode
    }
  }
}

export function reservePublicationSuccess (recordId, branchCode) {
  return dispatch => {
    dispatch(showModal(ModalComponents.RESERVATION, { isSuccess: true, recordId: recordId, branchCode: branchCode }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.RESERVE_PUBLICATION_SUCCESS,
      payload: {
        recordId: recordId,
        branchCode: branchCode
      }
    })
  }
}

export function reservePublicationFailure (error, recordId, branchCode) {
  return dispatch => {
    dispatch(showModal(ModalComponents.RESERVATION, {
      isError: true,
      message: error.message,
      recordId: recordId,
      branchCode: branchCode
    }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.RESERVE_PUBLICATION_FAILURE,
      payload: error,
      error: true
    })
  }
}

export function reservePublication (recordId, branchCode) {
  const url = '/api/v1/holds'
  return dispatch => {
    dispatch(requestReservePublication(recordId, branchCode))
    return fetch(url, {
      method: 'POST',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ recordId: recordId, branchCode: branchCode })
    })
      .then(response => {
        if (response.status === 201) {
          dispatch(reservePublicationSuccess(recordId, branchCode))
        } else if (response.status === 403) {
          return response.json()
        } else {
          throw Error(Errors.reservation.GENERIC_RESERVATION_ERROR)
        }
      })
      .then(maybeError => {
        if (!maybeError) {
          // reservation was succesfull
          return
        }
        if (maybeError.error && maybeError.error.includes('ageRestricted')) {
          throw Error(Errors.reservation.AGE_RESTRICTION)
        } else {
          console.log(`unmatched hold error reason: ${maybeError.error}`)
          throw Error(Errors.reservation.TOO_MANY_RESERVES)
        }
      })
      .catch(error => dispatch(reservePublicationFailure(error, recordId, branchCode)))
  }
}

export function startCancelReservation (reserveId) {
  return requireLoginBeforeAction(showModal(ModalComponents.CANCEL_RESERVATION, { reserveId: reserveId }))
}

export function requestCancelReservation (reserveId) {
  return {
    type: types.REQUEST_CANCEL_RESERVATION,
    payload: {
      reserveId: reserveId
    }
  }
}

export function cancelReservationSuccess (reserveId) {
  return dispatch => {
    dispatch(showModal(ModalComponents.CANCEL_RESERVATION, { isSuccess: true, reserveId: reserveId }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.CANCEL_RESERVATION_SUCCESS,
      payload: {
        reserveId: reserveId
      }
    })
  }
}

export function cancelReservationFailure (error, reserveId) {
  return dispatch => {
    dispatch(showModal(ModalComponents.CANCEL_RESERVATION, {
      isError: true,
      message: error.message,
      reserveId: reserveId
    }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.CANCEL_RESERVATION_FAILURE,
      payload: error,
      error: true
    })
  }
}

export function cancelReservation (reserveId) {
  const url = '/api/v1/holds'
  return dispatch => {
    dispatch(requestCancelReservation(reserveId))
    return fetch(url, {
      method: 'DELETE',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ reserveId: reserveId })
    })
      .then(response => {
        if (response.status === 200) {
          dispatch(cancelReservationSuccess(reserveId))
        } else {
          throw Error(Errors.reservation.GENERIC_CANCEL_RESERVATION_ERROR)
        }
      })
      .catch(error => dispatch(cancelReservationFailure(error, reserveId)))
  }
}
<commit_msg>patron-client: correct url to holds route<commit_after>import fetch from 'isomorphic-fetch'
import moment from 'moment'

import * as types from '../constants/ActionTypes'
import { requireLoginBeforeAction } from './LoginActions'
import { showModal } from './ModalActions'
import ModalComponents from '../constants/ModalComponents'
import Errors from '../constants/Errors'
import * as ProfileActions from './ProfileActions'
import { action, errorAction } from './GenericActions'

export function changePickupLocation (reserveId, branchCode) {
  const url = '/api/v1/holds'
  return dispatch => {
    dispatch(requestChangePickupLocation(reserveId, branchCode))
    return fetch(url, {
      method: 'PATCH',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ reserveId, branchCode })
    })
      .then(response => {
        if (response.status === 200) {
          setTimeout(() => {
            dispatch(changePickupLocationSuccess(reserveId, branchCode))
          }, 500)
        } else {
          throw Error(Errors.reservation.GENERIC_CHANGE_PICKUP_LOCATION_ERROR)
        }
      })
      .catch(error => dispatch(changePickupLocationFailure(error)))
  }
}

export const requestChangePickupLocation = (reserveId, branchCode) => action(types.REQUEST_CHANGE_PICKUP_LOCATION, {
  reserveId,
  branchCode
})

export const changePickupLocationSuccess = (reserveId, branchCode) => action(types.CHANGE_PICKUP_LOCATION_SUCCESS, {
  reserveId,
  branchCode
})

export const changePickupLocationFailure = error => errorAction(types.CHANGE_PICKUP_LOCATION_FAILURE, error)

export function suspendReservation (reserveId, suspended) {
  return dispatch => {
    if (suspended) {
      return dispatch(showModal(ModalComponents.POSTPONE_RESERVATION, { isSuccess: true, reserveId: reserveId, suspended: suspended }))
    }
    return dispatch(changeReservationSuspension(reserveId, suspended))
  }
}

export function changeReservationSuspension (reserveId, suspended, date) {
  let suspendUntil

  if (date) {
    suspendUntil = moment(date, 'DD.MM.YYYY').format('YYYY-MM-DD')
  } else {
    suspendUntil = null
  }

  const url = '/api/v1/holds'
  return dispatch => {
    dispatch(requestChangeReservationSuspension(reserveId, suspended, suspendUntil))
    return fetch(url, {
      method: 'PATCH',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ reserveId, suspended, suspendUntil })
    })
      .then(response => {
        if (response.status === 200) {
          setTimeout(() => {
            dispatch(changeReservationSuspensionSuccess(reserveId, suspended, suspendUntil))
          }, 500)
        } else {
          throw Error(Errors.reservation.GENERIC_CHANGE_RESERVATION_SUSPENSION_ERROR)
        }
      })
      .catch(error => dispatch(changeReservationSuspensionFailure(error)))
  }
}

export const requestChangeReservationSuspension = (reserveId, suspended, suspendUntil) => action(types.REQUEST_CHANGE_RESERVATION_SUSPENSION, {
  reserveId,
  suspended,
  suspendUntil
})

export const changeReservationSuspensionSuccess = (reserveId, suspended, suspendUntil) => action(types.CHANGE_RESERVATION_SUSPENSION_SUCCESS, {
  reserveId,
  suspended,
  suspendUntil
})

export const changeReservationSuspensionFailure = error => errorAction(types.CHANGE_PICKUP_LOCATION_FAILURE, error)

export function startReservation (publication) {
  return requireLoginBeforeAction(showModal(ModalComponents.RESERVATION, { publication: publication }))
}

export function requestReservePublication (recordId, branchCode) {
  return {
    type: types.REQUEST_RESERVE_PUBLICATION,
    payload: {
      recordId: recordId,
      branchCode: branchCode
    }
  }
}

export function reservePublicationSuccess (recordId, branchCode) {
  return dispatch => {
    dispatch(showModal(ModalComponents.RESERVATION, { isSuccess: true, recordId: recordId, branchCode: branchCode }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.RESERVE_PUBLICATION_SUCCESS,
      payload: {
        recordId: recordId,
        branchCode: branchCode
      }
    })
  }
}

export function reservePublicationFailure (error, recordId, branchCode) {
  return dispatch => {
    dispatch(showModal(ModalComponents.RESERVATION, {
      isError: true,
      message: error.message,
      recordId: recordId,
      branchCode: branchCode
    }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.RESERVE_PUBLICATION_FAILURE,
      payload: error,
      error: true
    })
  }
}

export function reservePublication (recordId, branchCode) {
  const url = '/api/v1/holds'
  return dispatch => {
    dispatch(requestReservePublication(recordId, branchCode))
    return fetch(url, {
      method: 'POST',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ recordId: recordId, branchCode: branchCode })
    })
      .then(response => {
        if (response.status === 201) {
          dispatch(reservePublicationSuccess(recordId, branchCode))
        } else if (response.status === 403) {
          return response.json()
        } else {
          throw Error(Errors.reservation.GENERIC_RESERVATION_ERROR)
        }
      })
      .then(maybeError => {
        if (!maybeError) {
          // reservation was succesfull
          return
        }
        if (maybeError.error && maybeError.error.includes('ageRestricted')) {
          throw Error(Errors.reservation.AGE_RESTRICTION)
        } else {
          console.log(`unmatched hold error reason: ${maybeError.error}`)
          throw Error(Errors.reservation.TOO_MANY_RESERVES)
        }
      })
      .catch(error => dispatch(reservePublicationFailure(error, recordId, branchCode)))
  }
}

export function startCancelReservation (reserveId) {
  return requireLoginBeforeAction(showModal(ModalComponents.CANCEL_RESERVATION, { reserveId: reserveId }))
}

export function requestCancelReservation (reserveId) {
  return {
    type: types.REQUEST_CANCEL_RESERVATION,
    payload: {
      reserveId: reserveId
    }
  }
}

export function cancelReservationSuccess (reserveId) {
  return dispatch => {
    dispatch(showModal(ModalComponents.CANCEL_RESERVATION, { isSuccess: true, reserveId: reserveId }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.CANCEL_RESERVATION_SUCCESS,
      payload: {
        reserveId: reserveId
      }
    })
  }
}

export function cancelReservationFailure (error, reserveId) {
  return dispatch => {
    dispatch(showModal(ModalComponents.CANCEL_RESERVATION, {
      isError: true,
      message: error.message,
      reserveId: reserveId
    }))
    dispatch(ProfileActions.fetchProfileLoans())
    dispatch({
      type: types.CANCEL_RESERVATION_FAILURE,
      payload: error,
      error: true
    })
  }
}

export function cancelReservation (reserveId) {
  const url = '/api/v1/holds'
  return dispatch => {
    dispatch(requestCancelReservation(reserveId))
    return fetch(url, {
      method: 'DELETE',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ reserveId: reserveId })
    })
      .then(response => {
        if (response.status === 200) {
          dispatch(cancelReservationSuccess(reserveId))
        } else {
          throw Error(Errors.reservation.GENERIC_CANCEL_RESERVATION_ERROR)
        }
      })
      .catch(error => dispatch(cancelReservationFailure(error, reserveId)))
  }
}
<|endoftext|>