<commit_before>/* eslint-disable strict */

'use strict';

/* This plugin based on https://gist.github.com/Morhaus/333579c2a5b4db644bd5

 Original license:
 --------
 The MIT License (MIT)
 Copyright (c) 2015 Alexandre Kirszenberg
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 --------

 And it's NPM-ified version: https://github.com/dcousineau/force-case-sensitivity-webpack-plugin
 Author Daniel Cousineau indicated MIT license as well but did not include it

 The originals did not properly case-sensitize the entire path, however. This plugin resolves that issue.

 This plugin license, also MIT:
 --------
 The MIT License (MIT)
 Copyright (c) 2016 Michael Pratt
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 --------
 */

const path = require('path');

function CaseSensitivePathsPlugin(options) {
  this.options = options || {};
  this.reset();
}

CaseSensitivePathsPlugin.prototype.reset = function () {
  this.pathCache = {};
  this.fsOperations = 0;
  this.primed = false;
};

CaseSensitivePathsPlugin.prototype.getFilenamesInDir = function (dir, callback) {
  const that = this;
  const fs = this.compiler.inputFileSystem;
  this.fsOperations += 1;

  if (Object.prototype.hasOwnProperty.call(this.pathCache, dir)) {
    callback(this.pathCache[dir]);
    return;
  }
  if (this.options.debug) {
    console.log('[CaseSensitivePathsPlugin] Reading directory', dir);
  }

  fs.readdir(dir, (err, files) => {
    if (err) {
      if (that.options.debug) {
        console.log('[CaseSensitivePathsPlugin] Failed to read directory', dir, err);
      }
      callback([]);
      return;
    }

    callback(files.map(f => f.normalize ? f.normalize('NFC') : f));
  });
};

// This function based on code found at http://stackoverflow.com/questions/27367261/check-if-file-exists-case-sensitive
// By Patrick McElhaney (No license indicated - Stack Overflow Answer)
// This version will return with the real name of any incorrectly-cased portion of the path, null otherwise.
CaseSensitivePathsPlugin.prototype.fileExistsWithCase = function (filepath, callback) {
  // Split filepath into current filename (or directory name) and parent directory tree.
  const that = this;
  const dir = path.dirname(filepath);
  const filename = path.basename(filepath);
  const parsedPath = path.parse(dir);

  // If we are at the root, or have found a path we already know is good, return.
  if (parsedPath.dir === parsedPath.root || dir === '.' || Object.prototype.hasOwnProperty.call(that.pathCache, filepath)) {
    callback();
    return;
  }

  // Check all filenames in the current dir against current filename to ensure one of them matches.
  // Read from the cache if available, from FS if not.
  that.getFilenamesInDir(dir, (filenames) => {
    // If the exact match does not exist, attempt to find the correct filename.
    if (filenames.indexOf(filename) === -1) {
      // Fallback value which triggers us to abort.
      let correctFilename = '!nonexistent';

      for (let i = 0; i < filenames.length; i += 1) {
        if (filenames[i].toLowerCase() === filename.toLowerCase()) {
          correctFilename = `\`${filenames[i]}\`.`;
          break;
        }
      }
      callback(correctFilename);
      return;
    }

    // If exact match exists, recurse through directory tree until root.
    that.fileExistsWithCase(dir, (recurse) => {
      // If found an error elsewhere, return that correct filename
      // Don't bother caching - we're about to error out anyway.
      if (!recurse) {
        that.pathCache[dir] = filenames;
      }

      callback(recurse);
    });
  });
};

CaseSensitivePathsPlugin.prototype.primeCache = function (callback) {
  if (this.primed) {
    callback();
    return;
  }

  const that = this;
  // Prime the cache with the current directory. We have to assume the current casing is correct,
  // as in certain circumstances people can switch into an incorrectly-cased directory.
  const currentPath = path.resolve();
  that.getFilenamesInDir(currentPath, (files) => {
    that.pathCache[currentPath] = files;
    that.primed = true;
    callback();
  });
};

CaseSensitivePathsPlugin.prototype.apply = function (compiler) {
  this.compiler = compiler;

  const onDone = () => {
    if (this.options.debug) {
      console.log('[CaseSensitivePathsPlugin] Total filesystem reads:', this.fsOperations);
    }

    this.reset();
  };

  const checkFile = (pathName, data, done) => {
    this.fileExistsWithCase(pathName, (realName) => {
      if (realName) {
        if (realName === '!nonexistent') {
          // If file does not exist, let Webpack show a more appropriate error.
          done(null, data);
        } else {
          done(new Error(`[CaseSensitivePathsPlugin] \`${pathName}\` does not match the corresponding path on disk ${realName}`));
        }
      } else {
        done(null, data);
      }
    });
  };

  const onAfterResolve = (data, done) => {
    this.primeCache(() => {
      // Trim ? off, since some loaders add that to the resource they're attemping to load
      let pathName = data.resource.split('?')[0];
      pathName = pathName.normalize ? pathName.normalize('NFC') : pathName;

      checkFile(pathName, data, done);
    });
  };

  if (compiler.hooks) {
    compiler.hooks.done.tap('CaseSensitivePathsPlugin', onDone);
    if (this.options.useBeforeEmitHook) {
      if (this.options.debug) {
        console.log('[CaseSensitivePathsPlugin] Using the hook for before emit.');
      }
      compiler.hooks.emit.tapAsync('CaseSensitivePathsPlugin', (compilation, callback) => {
        let resolvedFilesCount = 0;
        const errors = [];
        this.primeCache(() => {
          compilation.fileDependencies.forEach((filename) => {
            checkFile(filename, filename, (error) => {
              resolvedFilesCount += 1;
              if (error) {
                errors.push(error);
              }
              if (resolvedFilesCount === compilation.fileDependencies.size) {
                if (errors.length) {
                  // Send all errors to webpack
                  Array.prototype.push.apply(compilation.errors, errors);
                }
                callback();
              }
            });
          });
        });
      });
    } else {
      compiler.hooks.normalModuleFactory.tap('CaseSensitivePathsPlugin', (nmf) => {
        nmf.hooks.afterResolve.tapAsync('CaseSensitivePathsPlugin', onAfterResolve);
      });
    }
  } else {
    compiler.plugin('done', onDone);
    compiler.plugin('normal-module-factory', (nmf) => {
      nmf.plugin('after-resolve', onAfterResolve);
    });
  }
};

module.exports = CaseSensitivePathsPlugin;
<commit_msg>Add configurable logger<commit_after>/* eslint-disable strict */

'use strict';

/* This plugin based on https://gist.github.com/Morhaus/333579c2a5b4db644bd5

 Original license:
 --------
 The MIT License (MIT)
 Copyright (c) 2015 Alexandre Kirszenberg
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 --------

 And it's NPM-ified version: https://github.com/dcousineau/force-case-sensitivity-webpack-plugin
 Author Daniel Cousineau indicated MIT license as well but did not include it

 The originals did not properly case-sensitize the entire path, however. This plugin resolves that issue.

 This plugin license, also MIT:
 --------
 The MIT License (MIT)
 Copyright (c) 2016 Michael Pratt
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 --------
 */

const path = require('path');

function CaseSensitivePathsPlugin(options) {
  this.options = options || {};
  this.logger = this.options.logger || console;
  this.reset();
}

CaseSensitivePathsPlugin.prototype.reset = function () {
  this.pathCache = {};
  this.fsOperations = 0;
  this.primed = false;
};

CaseSensitivePathsPlugin.prototype.getFilenamesInDir = function (dir, callback) {
  const that = this;
  const fs = this.compiler.inputFileSystem;
  this.fsOperations += 1;

  if (Object.prototype.hasOwnProperty.call(this.pathCache, dir)) {
    callback(this.pathCache[dir]);
    return;
  }
  if (this.options.debug) {
    this.logger.log('[CaseSensitivePathsPlugin] Reading directory', dir);
  }

  fs.readdir(dir, (err, files) => {
    if (err) {
      if (that.options.debug) {
        this.logger.log('[CaseSensitivePathsPlugin] Failed to read directory', dir, err);
      }
      callback([]);
      return;
    }

    callback(files.map(f => f.normalize ? f.normalize('NFC') : f));
  });
};

// This function based on code found at http://stackoverflow.com/questions/27367261/check-if-file-exists-case-sensitive
// By Patrick McElhaney (No license indicated - Stack Overflow Answer)
// This version will return with the real name of any incorrectly-cased portion of the path, null otherwise.
CaseSensitivePathsPlugin.prototype.fileExistsWithCase = function (filepath, callback) {
  // Split filepath into current filename (or directory name) and parent directory tree.
  const that = this;
  const dir = path.dirname(filepath);
  const filename = path.basename(filepath);
  const parsedPath = path.parse(dir);

  // If we are at the root, or have found a path we already know is good, return.
  if (parsedPath.dir === parsedPath.root || dir === '.' || Object.prototype.hasOwnProperty.call(that.pathCache, filepath)) {
    callback();
    return;
  }

  // Check all filenames in the current dir against current filename to ensure one of them matches.
  // Read from the cache if available, from FS if not.
  that.getFilenamesInDir(dir, (filenames) => {
    // If the exact match does not exist, attempt to find the correct filename.
    if (filenames.indexOf(filename) === -1) {
      // Fallback value which triggers us to abort.
      let correctFilename = '!nonexistent';

      for (let i = 0; i < filenames.length; i += 1) {
        if (filenames[i].toLowerCase() === filename.toLowerCase()) {
          correctFilename = `\`${filenames[i]}\`.`;
          break;
        }
      }
      callback(correctFilename);
      return;
    }

    // If exact match exists, recurse through directory tree until root.
    that.fileExistsWithCase(dir, (recurse) => {
      // If found an error elsewhere, return that correct filename
      // Don't bother caching - we're about to error out anyway.
      if (!recurse) {
        that.pathCache[dir] = filenames;
      }

      callback(recurse);
    });
  });
};

CaseSensitivePathsPlugin.prototype.primeCache = function (callback) {
  if (this.primed) {
    callback();
    return;
  }

  const that = this;
  // Prime the cache with the current directory. We have to assume the current casing is correct,
  // as in certain circumstances people can switch into an incorrectly-cased directory.
  const currentPath = path.resolve();
  that.getFilenamesInDir(currentPath, (files) => {
    that.pathCache[currentPath] = files;
    that.primed = true;
    callback();
  });
};

CaseSensitivePathsPlugin.prototype.apply = function (compiler) {
  this.compiler = compiler;

  const onDone = () => {
    if (this.options.debug) {
      this.logger.log('[CaseSensitivePathsPlugin] Total filesystem reads:', this.fsOperations);
    }

    this.reset();
  };

  const checkFile = (pathName, data, done) => {
    this.fileExistsWithCase(pathName, (realName) => {
      if (realName) {
        if (realName === '!nonexistent') {
          // If file does not exist, let Webpack show a more appropriate error.
          done(null, data);
        } else {
          done(new Error(`[CaseSensitivePathsPlugin] \`${pathName}\` does not match the corresponding path on disk ${realName}`));
        }
      } else {
        done(null, data);
      }
    });
  };

  const onAfterResolve = (data, done) => {
    this.primeCache(() => {
      // Trim ? off, since some loaders add that to the resource they're attemping to load
      let pathName = data.resource.split('?')[0];
      pathName = pathName.normalize ? pathName.normalize('NFC') : pathName;

      checkFile(pathName, data, done);
    });
  };

  if (compiler.hooks) {
    compiler.hooks.done.tap('CaseSensitivePathsPlugin', onDone);
    if (this.options.useBeforeEmitHook) {
      if (this.options.debug) {
        this.logger.log('[CaseSensitivePathsPlugin] Using the hook for before emit.');
      }
      compiler.hooks.emit.tapAsync('CaseSensitivePathsPlugin', (compilation, callback) => {
        let resolvedFilesCount = 0;
        const errors = [];
        this.primeCache(() => {
          compilation.fileDependencies.forEach((filename) => {
            checkFile(filename, filename, (error) => {
              resolvedFilesCount += 1;
              if (error) {
                errors.push(error);
              }
              if (resolvedFilesCount === compilation.fileDependencies.size) {
                if (errors.length) {
                  // Send all errors to webpack
                  Array.prototype.push.apply(compilation.errors, errors);
                }
                callback();
              }
            });
          });
        });
      });
    } else {
      compiler.hooks.normalModuleFactory.tap('CaseSensitivePathsPlugin', (nmf) => {
        nmf.hooks.afterResolve.tapAsync('CaseSensitivePathsPlugin', onAfterResolve);
      });
    }
  } else {
    compiler.plugin('done', onDone);
    compiler.plugin('normal-module-factory', (nmf) => {
      nmf.plugin('after-resolve', onAfterResolve);
    });
  }
};

module.exports = CaseSensitivePathsPlugin;
<|endoftext|>


<commit_before>
var initId = 0;

module.exports = function makeColumn(rootCol, fraction) {
  rootCol = rootCol || {K: 1, G: 0, depth: 0, children: {}};

  var col = {
    depth: rootCol.depth + 1,
    children: {}
  };

  var id = initId++;
  var rawf, f;

  col.setWidth = function (fraction) {
    fraction = fraction || '1/1';

    if (fraction === rawf) return;
    rawf = fraction;

    f = fractionToArray(fraction);

    col.updateWidth = function () {
      col.K = rootCol.K * f[0] / f[1];
      col.G = (rootCol.G * f[0] / f[1]) + (f[0] / f[1]) - 1;
    }

    col.updateWidth();

    if (col.children.length) {
      var child;
      for (child in col.children) {
        col.children[child].updateWidth();
      }
    }
  }

  col.getFraction = function () {
    return f;
  }

  col.getId = function() {
    return id;
  }

  col.getWidth = function (viewport, gutter) {
    return (viewport * col.K) + (gutter * col.G);
  }

  col.detach = function () {
    delete rootCol.children[id];
  }

  col.setWidth(fraction);
  rootCol.children[id] = col;

  return col;
}

function fractionToArray(f) {
  f = f.split('/');
  f[0] = parseInt(f[0]);
  f[1] = parseInt(f[1]);
  return f;
}
<commit_msg>removing the rebuilding of updateWidth<commit_after>
var initId = 0;

module.exports = function makeColumn(rootCol, fraction) {
  rootCol = rootCol || {K: 1, G: 0, depth: 0, children: {}};

  var col = {
    depth: rootCol.depth + 1,
    children: {}
  };

  var id = initId++;
  var rawf, f;

  col.setWidth = function (fraction) {
    fraction = fraction || '1/1';

    if (fraction === rawf) return;
    rawf = fraction;

    f = fractionToArray(fraction);
    col.updateWidth();

    if (col.children.length) {
      var child;
      for (child in col.children) {
        col.children[child].updateWidth();
      }
    }
  }

  col.updateWidth = function () {
    col.K = rootCol.K * f[0] / f[1];
    col.G = (rootCol.G * f[0] / f[1]) + (f[0] / f[1]) - 1;
  }

  col.getFraction = function () {
    return f;
  }

  col.getId = function() {
    return id;
  }

  col.getWidth = function (viewport, gutter) {
    return (viewport * col.K) + (gutter * col.G);
  }

  col.detach = function () {
    delete rootCol.children[id];
  }

  col.setWidth(fraction);
  rootCol.children[id] = col;

  return col;
}

function fractionToArray(f) {
  f = f.split('/');
  f[0] = parseInt(f[0]);
  f[1] = parseInt(f[1]);
  return f;
}
<|endoftext|>


<commit_before>var net = require('net'),
    protobuf = require('protobuf.js'),
    butils = require('butils');

var messageCodes = {
    '0': 'RpbErrorResp',
    '1': 'RpbPingReq',
    '2': 'RpbPingResp',
    '3': 'RpbGetClientIdReq',
    '4': 'RpbGetClientIdResp',
    '5': 'RpbSetClientIdReq',
    '6': 'RpbSetClientIdResp',
    '7': 'RpbGetServerInfoReq',
    '8': 'RpbGetServerInfoResp',
    '9': 'RpbGetReq',
    '10': 'RpbGetResp',
    '11': 'RpbPutReq',
    '12': 'RpbPutResp',
    '13': 'RpbDelReq',
    '14': 'RpbDelResp',
    '15': 'RpbListBucketsReq',
    '16': 'RpbListBucketsResp',
    '17': 'RpbListKeysReq',
    '18': 'RpbListKeysResp',
    '19': 'RpbGetBucketReq',
    '20': 'RpbGetBucketResp',
    '21': 'RpbSetBucketReq',
    '22': 'RpbSetBucketResp',
    '23': 'RpbMapRedReq',
    '24': 'RpbMapRedResp',
    '25': 'RpbIndexReq',
    '26': 'RpbIndexResp',
    '27': 'RpbSearchQueryReq',
    '28': 'RpbSearchQueryResp'
};
Object.keys(messageCodes).forEach(function (key) {
    messageCodes[messageCodes[key]] = Number(key);
});

function RiakPBC(options) {
    var self = this;
    options = options || {};
    self.host = options.host || '127.0.0.1';
    self.port = options.port || 8087;
    self.bucket = options.bucket || undefined;
    self.translator = protobuf.loadSchema('./spec/riak_kv.proto');
    self.client = new net.Socket();
    self.connected = false;
    self.client.on('end', self.disconnect);
    self.client.on('error', self.disconnect);
    self.paused = false;
    self.queue = [];
    var mc, reply = {};

    function splitPacket(pkt) {
        var ret = [], len, pos = 0, end = pkt.length;
        while (pos < end) {
            len = butils.readInt32(pkt, pos);
            ret.push(pkt.slice(pos + 4, pos + len + 4));
            pos += len + 4;
        }
        return ret;
    }

    self.client.on('data', function (chunk) {
        splitPacket(chunk).forEach(function (packet) {
            mc = messageCodes['' + packet[0]];

            if (self.task.streaming && !reply.done) {
                self.task.callback(reply);
                return;
            }

            reply = _merge(reply, self.translator.decode(mc, packet.slice(1)));
            if (!self.task.expectMultiple || reply.done || mc === 'RpbErrorResp') {
                self.task.callback(reply);
                mc = undefined;
                self.task = undefined;
                reply = {};
                self.paused = false;
                self.processNext();
            }
        });
    });

    self.processNext = function () {
        if (self.queue.length && !self.paused) {
            self.paused = true;
            self.connect(function () {
                self.task = self.queue.shift();
                self.client.write(self.task.message);
            });
        }
    };
}

function _merge(obj1, obj2) {
    var obj = {};
    if (obj2.hasOwnProperty('phase')) {
        obj = obj1;
        if (obj[obj2.phase] === undefined) obj[obj2.phase] = [];
        obj[obj2.phase] = obj[obj2.phase].concat(JSON.parse(obj2.response));
    } else {
        [obj1, obj2].forEach(function (old) {
            Object.keys(old).forEach(function (key) {
                if (!old.hasOwnProperty(key)) return;
                if (Array.isArray(old[key])) {
                    if (!obj[key]) obj[key] = [];
                    obj[key] = obj[key].concat(old[key]);
                } else {
                    obj[key] = old[key];
                }
            });
        });
    }
    return obj;
}

RiakPBC.prototype.makeRequest = function (type, data, callback, expectMultiple, streaming) {
    var self = this,
        reply = {},
        buffer = this.translator.encode(type, data),
        message = [];

    butils.writeInt32(message, buffer.length + 1);
    butils.writeInt(message, messageCodes[type], 4);
    message = message.concat(buffer);
    self.queue.push({ message: new Buffer(message), callback: callback, expectMultiple: expectMultiple, streaming: streaming });
    process.nextTick(self.processNext);
};

RiakPBC.prototype.getBuckets = function (callback) {
    this.makeRequest('RpbListBucketsReq', null, callback);
};

RiakPBC.prototype.getBucket = function (params, callback) {
    this.makeRequest('RpbGetBucketReq', params, callback);
};

RiakPBC.prototype.setBucket = function (params, callback) {
    this.makeRequest('RpbSetBucketReq', params, callback);
};

RiakPBC.prototype.getKeys = function (params, callback) {
    this.makeRequest('RpbListKeysReq', params, callback, true, streaming);
};

RiakPBC.prototype.put = function (params, callback) {
    this.makeRequest('RpbPutReq', params, callback);
};

RiakPBC.prototype.get = function (params, callback) {
    this.makeRequest('RpbGetReq', params, callback);
};

RiakPBC.prototype.del = function (params, callback) {
    this.makeRequest('RpbDelReq', params, callback);
};

RiakPBC.prototype.mapred = function (params, callback, streaming) {
    this.makeRequest('RpbMapRedReq', params, callback, true, streaming);
};

RiakPBC.prototype.getIndex = function (params, callback) {
    this.makeRequest('RpbIndexReq', params, callback);
};

RiakPBC.prototype.search = function (params, callback) {
    this.makeRequest('RpbSearchQueryReq', params, callback);
};

RiakPBC.prototype.getClientId = function (callback) {
    this.makeRequest('RpbGetClientIdReq', null, callback);
};

RiakPBC.prototype.setClientId = function (params, callback) {
    this.makeRequest('RpbSetClientIdReq', params, callback);
};

RiakPBC.prototype.getServerInfo = function (callback) {
    this.makeRequest('RpbGetServerInfoReq', null, callback);
};

RiakPBC.prototype.ping = function (callback) {
    this.makeRequest('RpbPingReq', null, callback);
};

RiakPBC.prototype.connect = function (callback) {
    if (this.connected) return callback();
    var self = this;
    self.client.connect(self.port, self.host, function () {
        self.connected = true;
        callback();
    });
};

RiakPBC.prototype.disconnect = function () {
    if (!this.connected) return;
    this.client.end();
    this.connected = false;
    if (this.task) {
        this.queue.unshift(this.task);
        this.task = undefined;
    }
};

exports.createClient = function (options) {
    return new RiakPBC(options);
};
<commit_msg>Use EventEmitters for streaming.<commit_after>var net = require('net'),
    protobuf = require('protobuf.js'),
    butils = require('butils'),
    EventEmitter = require('events').EventEmitter;

var messageCodes = {
    '0': 'RpbErrorResp',
    '1': 'RpbPingReq',
    '2': 'RpbPingResp',
    '3': 'RpbGetClientIdReq',
    '4': 'RpbGetClientIdResp',
    '5': 'RpbSetClientIdReq',
    '6': 'RpbSetClientIdResp',
    '7': 'RpbGetServerInfoReq',
    '8': 'RpbGetServerInfoResp',
    '9': 'RpbGetReq',
    '10': 'RpbGetResp',
    '11': 'RpbPutReq',
    '12': 'RpbPutResp',
    '13': 'RpbDelReq',
    '14': 'RpbDelResp',
    '15': 'RpbListBucketsReq',
    '16': 'RpbListBucketsResp',
    '17': 'RpbListKeysReq',
    '18': 'RpbListKeysResp',
    '19': 'RpbGetBucketReq',
    '20': 'RpbGetBucketResp',
    '21': 'RpbSetBucketReq',
    '22': 'RpbSetBucketResp',
    '23': 'RpbMapRedReq',
    '24': 'RpbMapRedResp',
    '25': 'RpbIndexReq',
    '26': 'RpbIndexResp',
    '27': 'RpbSearchQueryReq',
    '28': 'RpbSearchQueryResp'
};
Object.keys(messageCodes).forEach(function (key) {
    messageCodes[messageCodes[key]] = Number(key);
});

function RiakPBC(options) {
    var self = this;
    options = options || {};
    self.host = options.host || '127.0.0.1';
    self.port = options.port || 8087;
    self.bucket = options.bucket || undefined;
    self.translator = protobuf.loadSchema('./spec/riak_kv.proto');
    self.client = new net.Socket();
    self.connected = false;
    self.client.on('end', self.disconnect);
    self.client.on('error', self.disconnect);
    self.paused = false;
    self.queue = [];
    var mc, reply = {};

    function splitPacket(pkt) {
        var ret = [], len, pos = 0, end = pkt.length;
        while (pos < end) {
            len = butils.readInt32(pkt, pos);
            ret.push(pkt.slice(pos + 4, pos + len + 4));
            pos += len + 4;
        }
        return ret;
    }

    self.client.on('data', function (chunk) {
        splitPacket(chunk).forEach(function (packet) {
            mc = messageCodes['' + packet[0]];

            if (self.task.emitter && !reply.done) {
                self.task.emitter.emit('data', reply);
                return;
            }

            reply = _merge(reply, self.translator.decode(mc, packet.slice(1)));
            if (!self.task.expectMultiple || reply.done || mc === 'RpbErrorResp') {
                if (self.task.emitter) {
                  self.task.emitter.emit('end', reply);
                } else {
                  self.task.callback(reply);
                }
                mc = undefined;
                self.task = undefined;
                reply = {};
                self.paused = false;
                self.processNext();
            }
        });
    });

    self.processNext = function () {
        if (self.queue.length && !self.paused) {
            self.paused = true;
            self.connect(function () {
                self.task = self.queue.shift();
                self.client.write(self.task.message);
            });
        }
    };
}

function _merge(obj1, obj2) {
    var obj = {};
    if (obj2.hasOwnProperty('phase')) {
        obj = obj1;
        if (obj[obj2.phase] === undefined) obj[obj2.phase] = [];
        obj[obj2.phase] = obj[obj2.phase].concat(JSON.parse(obj2.response));
    } else {
        [obj1, obj2].forEach(function (old) {
            Object.keys(old).forEach(function (key) {
                if (!old.hasOwnProperty(key)) return;
                if (Array.isArray(old[key])) {
                    if (!obj[key]) obj[key] = [];
                    obj[key] = obj[key].concat(old[key]);
                } else {
                    obj[key] = old[key];
                }
            });
        });
    }
    return obj;
}

RiakPBC.prototype.makeRequest = function (type, data, callback, expectMultiple, emitter) {
    var self = this,
        reply = {},
        buffer = this.translator.encode(type, data),
        message = [];

    butils.writeInt32(message, buffer.length + 1);
    butils.writeInt(message, messageCodes[type], 4);
    message = message.concat(buffer);
    self.queue.push({ message: new Buffer(message), callback: callback, expectMultiple: expectMultiple, emitter: emitter });
    process.nextTick(self.processNext);
};

RiakPBC.prototype.getBuckets = function (callback) {
    this.makeRequest('RpbListBucketsReq', null, callback);
};

RiakPBC.prototype.getBucket = function (params, callback) {
    this.makeRequest('RpbGetBucketReq', params, callback);
};

RiakPBC.prototype.setBucket = function (params, callback) {
    this.makeRequest('RpbSetBucketReq', params, callback);
};

RiakPBC.prototype.getKeys = function (params, callback, streaming) {
    if (streaming) {
      var emitter = new EventEmitter();
      this.makeRequest('RpbListKeysReq', params, callback, true, emitter);
      return emitter;
    } else {
      this.makeRequest('RpbListKeysReq', params, callback, true);
    }
};

RiakPBC.prototype.put = function (params, callback) {
    this.makeRequest('RpbPutReq', params, callback);
};

RiakPBC.prototype.get = function (params, callback) {
    this.makeRequest('RpbGetReq', params, callback);
};

RiakPBC.prototype.del = function (params, callback) {
    this.makeRequest('RpbDelReq', params, callback);
};

RiakPBC.prototype.mapred = function (params, callback, streaming) {
    if (streaming) {
      var emitter = new EventEmitter();
      this.makeRequest('RpbMapRedReq', params, callback, true, emitter);
      return emitter;
    } else {
      this.makeRequest('RpbMapRedReq', params, callback, true);
    }
};

RiakPBC.prototype.getIndex = function (params, callback) {
    this.makeRequest('RpbIndexReq', params, callback);
};

RiakPBC.prototype.search = function (params, callback) {
    this.makeRequest('RpbSearchQueryReq', params, callback);
};

RiakPBC.prototype.getClientId = function (callback) {
    this.makeRequest('RpbGetClientIdReq', null, callback);
};

RiakPBC.prototype.setClientId = function (params, callback) {
    this.makeRequest('RpbSetClientIdReq', params, callback);
};

RiakPBC.prototype.getServerInfo = function (callback) {
    this.makeRequest('RpbGetServerInfoReq', null, callback);
};

RiakPBC.prototype.ping = function (callback) {
    this.makeRequest('RpbPingReq', null, callback);
};

RiakPBC.prototype.connect = function (callback) {
    if (this.connected) return callback();
    var self = this;
    self.client.connect(self.port, self.host, function () {
        self.connected = true;
        callback();
    });
};

RiakPBC.prototype.disconnect = function () {
    if (!this.connected) return;
    this.client.end();
    this.connected = false;
    if (this.task) {
        this.queue.unshift(this.task);
        this.task = undefined;
    }
};

exports.createClient = function (options) {
    return new RiakPBC(options);
};
<|endoftext|>


<commit_before>
var pull = require('pull-stream')
var pushable = require('pull-pushable')

module.exports = function (select, createStream) {
  var streams = {}, n = 0

  var sink = pull.drain(function (item) {
    var key = select(item)
    if(!streams[key]) {
      streams[key] = pushable(function (err) {
        delete streams[key]
        if(--n) return
      })
      pull(streams[key], createStream(key))
    }
    streams[key].push(item)
  }, function (err) {
    for(var key in streams) {
      streams[key].end(err)
    }
  })

  sink.add = function (key, streams) {
    streams[key] = pushable(function (err) {
      delete streams[key]
      if(--n) return
    })
    pull(streams[key], sink)
  }

  return sink
}
<commit_msg>fix horrendous mistake<commit_after>'use strict';
var pull = require('pull-stream')
var pushable = require('pull-pushable')

module.exports = function (select, createStream) {
  var streams = {}, n = 0

  var sink = pull.drain(function (item) {
    var key = select(item)
    if(!streams[key]) {
      streams[key] = pushable(function (err) {
        delete streams[key]
        --n
      })
      pull(streams[key], createStream(key))
    }
    streams[key].push(item)
  }, function (err) {
    for(var key in streams) {
      streams[key].end(err)
    }
  })

  sink.add = function (key, subsink) {
    streams[key] = pushable(function (err) {
      delete streams[key]
      --n
    })
    pull(streams[key], subsink)
  }

  return sink
}
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const request = require('request');
const Cheerio = require('cheerio');
const SteamTotp = require('steam-totp');
const _ = require('underscore');

const Confirmation = require('/lib/Confirmation.js');

class SteamCommunityMobileConfirmations {
  this.STEAM_BASE = 'http://steamcommunity.com'
  this.steamId = '';
  this.identitySecret = '';
  this.deviceId = '';
  this.offest = 0;
  this.has429Error = false;
  this.timeBetweenCalls = 0;
  this._requestJar = request.jar();
  this._request = request.defaults({ jar: this._requestJar });

  constructor(data) {
    this.steamId = data.steamId;
    this.identitySecret = data.identitySecret;
    this.deviceId = data.deviceId || SteamTotp.getDeviceID(this.steamId);
    this.offset = data.steamOffset || 0;
    this.timeBetweenCalls = data.waitTime || 10000;

    // Set each cookie NOM NOM
    for (let cookie of data.webCookie) {
      this._requestJar.setCookie(request.cookie(cookie), 'https://steamcommunity.com');
    }
  }

  /**
   * Grabs all confirmations
   * @param {Function} callback The function callback'd.
   * @return {void}
   */
  fetchConfirmations(callback) {
    this._request({
      url:
    }, (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      // Parse our confirmations
      let confirmations = [];
      let finalConfirmations = [];
      let $ = Cheerio.load(body);
      fs.writeFileSync(`output.html`, body);

      // Go through each confirmation, and generate a new Confirmation object
      $('[data-confid]').each((index, element) => {
        let $confirmation = $(element);
        let description = $confirmation.find('.mobileconf_list_entry_description > div').map(() => $(this).text());
        console.log(description);

        confirmations.push(new Confirmation({
          id: $confirmation.data('confid'),
          key: $confirmation.data('key'),
          description: description,
          cancel: $confirmation.data('cancel'),
          accept: $confirmation.data('accept'),
          tradeId: null
        }));
      });

      for (let confirmation of confirmations) {
        this.getConfirmationTradeId(confirmation, (error, updatedConfirmation) => {
          finalConfirmations.push(updatedConfirmation);

          // If we've finalized each confirmation, callback()
          if (finalConfirmations.length == confirmations.length) {
            callback(null, finalConfirmations);
            return;
          }
        });
      }
    });
  }

  /**
   * Sends the response to accept the confirmation
   * @param  {Confirmation} confirmation The Confirmation we are responding too (or an array of confirmations)
   * @param  {Function}     callback
   * @return {void}
   */
  acceptConfirmation(confirmation, callback) {
    if (!Array.isArray(confirmation)) {
      this._sendConfirmationResponse(confirmation, 'allow', (error, result) => {

      });
    } else {
      this._sendMultiConfirmationResponse(confirmation, 'allow', (error, result) => {

      });
    }
  }

  /**
   * This retrieves the tradeId from a confirmation
   * @param  {Confirmation}   confirmation The specific confirmation
   * @param  {Function}       callback
   * @return {void}
   */
  getConfirmationTradeId(confirmation, callback) {
    this._getConfirmationDetails(confirmation, (error, body) => {
      if (error) {
        callback(error, confirmation);
        return;
      }

      let $ = Cheerio.load(body);
      fs.writeFileSync(`output-details.html`, body);

      let tradeId = $('div.tradeoffer').attr('id').match(/\d+/i);

      confirmation.tradeId = tradeId;

      callback(null, confirmation);
    });
  }

  /**
   * Our custom request call, applies headers where needed / etc
   * @param  {String}   url      The URL to be requested
   * @param  {String}   method   The HTTP method (GET, POST, PUT, DELETE)
   * @param  {Object}   form     (Optional) A form to be sent, only works if method is POST
   * @param  {Function} callback
   * @return {void}
   */
  request(url, method, form, callback) {
    if (typeof form === 'function') {
      callback = form;
      form = {};
    }

    // Generate some headers to simulate a real application
    let headers = {
      'accept': 'text/javascript, text/html, application/xml, text/xml, */*',
      'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; Google Nexus 4 - 4.1.1 - API 16 - 768x1280 Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'
    };

    this._request({
      method: method,
      url: url,
      headers: headers,
      form: form
    }, callback);
  }

  /**
   * Sends a confirmation response
   * @param  {Confirmation} confirmation The Confirmation we are responding too
   * @param  {String}       operation    allow / cancel
   * @param  {Function}     callback     The function callback'd
   * @return {void}
   */
  _sendConfirmationResponse(confirmation, operation, callback) {
    let url = `${this.STEAM_BASE}/mobileconf/ajaxop?op=${operation}&${this._generateQueryString(operation)}&cid=${confirmation.id}&ck=${confirmation.key}`;

    this.request(url, 'GET', (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      try {
        let result = JSON.parse(body);
        callback(null, result.success);
      } catch (e) {
        callback(e, null);
      }
    });
  }

  /**
   * Allows multiple confirmations to be sent at once (either all accept, or all deny)
   * @param  {Array}    confirmations The confirmation array
   * @param  {String}   operation     accept / deny
   * @param  {Function} callback
   * @return {void}
   */
  _sendMultiConfirmationResponse(confirmations, operation, callback) {
    let url = `${this.STEAM_BASE}/mobileconf/multiajaxop`;
    let queryVariables = this._generateQueryVariables(operation);

    // Initialize our form
    let form = {
      op: operation,
      cid: [],
      ck: []
    };

    // Move our query variables to the new form
    _.extend(form, queryVariables);

    // Loop over each confirmation, adding each id / key to their respective array
    for (let confirmation of confirmations) {
      form.cid.push(confirmation.id);
      form.ck.push(confirmation.key);
    }

    this.request(url, 'POST', form, (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      try {
        let result = JSON.parse(body);
        callback(null, result.success);
      } catch (e) {
        callback(e, null);
      }
    });
  }

  /**
   * Gets the confirmation details
   * @param  {Confirmation} confirmation The Confirmation we care about
   * @param {Function} callback
   * @return {void}
   */
  _getConfirmationDetails(confirmation, callback) {
    let url = `${this.STEAM_BASE}/mobileconf/details/${confirmation.id}?${this._generateQueryString('details')}`;

    this.request(url, 'GET', (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      callback(null, body);
    });
  }

  /**
   * Generates the HTTP query string, to be prepended to all GET requests
   * @param  {String} tag The action. "conf" to load the confirmations page, "details" to load details about a trade, "allow" to confirm a trade, "cancel" to cancel it.
   * @return {String}     The generated string
   */
  _generateQueryString(tag) {
    let queryVariables = this._generateQueryVariables(tag);
    let queryString = '';

    // Generate our string
    for (let name in queryVariables) {
      queryString += `${name}=${queryVariables[name]}&`;
    }

    // Remove trailing &
    queryString = queryString.slice(0, -1);

    return queryString;
  }

  /**
   * Actually generate the needed variables
   * @param  {String} tag Action tag
   * @return {Object}     The variables, zipped together a nice & neat object!
   */
  _generateQueryVariables(tag) {
    let time = Math.floor(Date.now() / 1000) + this.steamOffset;

    let result = {
      p: this.deviceId,
      a: this.steamId,
      k: SteamTotp.generateConfirmationKey(this.identitySecret, time, tag),
      t: time,
      m: 'android',
      tag: tag
    };

    return result;
  }
}

/**
 * Checks the HTTP response
 * @param  {Error} error    An HTTP error
 * @param  {Object} response The HTTP response object
 * @param  {Object} body     The HTTP body
 * @return {Error}          An error, if one exists (null otherwise)
 */
function checkResponse(error, response, body) {
  if (error || response.statusCode != 200) {
    return error || new Error(response.statusCode);
  }

  if (!body) {
    return new Error('Invalid response body');
  }

  return null;
}

module.exports = SteamCommunityMobileConfirmations;
<commit_msg>Finalized acceptConfirmation()<commit_after>'use strict';

const fs = require('fs');
const request = require('request');
const Cheerio = require('cheerio');
const SteamTotp = require('steam-totp');
const _ = require('underscore');

const Confirmation = require('/lib/Confirmation.js');

class SteamCommunityMobileConfirmations {
  this.STEAM_BASE = 'http://steamcommunity.com'
  this.steamId = '';
  this.identitySecret = '';
  this.deviceId = '';
  this.offest = 0;
  this.has429Error = false;
  this.timeBetweenCalls = 0;
  this._requestJar = request.jar();
  this._request = request.defaults({ jar: this._requestJar });

  constructor(data) {
    this.steamId = data.steamId;
    this.identitySecret = data.identitySecret;
    this.deviceId = data.deviceId || SteamTotp.getDeviceID(this.steamId);
    this.offset = data.steamOffset || 0;
    this.timeBetweenCalls = data.waitTime || 10000;

    // Set each cookie NOM NOM
    for (let cookie of data.webCookie) {
      this._requestJar.setCookie(request.cookie(cookie), 'https://steamcommunity.com');
    }
  }

  /**
   * Grabs all confirmations
   * @param {Function} callback The function callback'd.
   * @return {void}
   */
  fetchConfirmations(callback) {
    this._request({
      url:
    }, (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      // Parse our confirmations
      let confirmations = [];
      let finalConfirmations = [];
      let $ = Cheerio.load(body);
      fs.writeFileSync(`output.html`, body);

      // Go through each confirmation, and generate a new Confirmation object
      $('[data-confid]').each((index, element) => {
        let $confirmation = $(element);
        let description = $confirmation.find('.mobileconf_list_entry_description > div').map(() => $(this).text());
        console.log(description);

        confirmations.push(new Confirmation({
          id: $confirmation.data('confid'),
          key: $confirmation.data('key'),
          description: description,
          cancel: $confirmation.data('cancel'),
          accept: $confirmation.data('accept'),
          tradeId: null
        }));
      });

      for (let confirmation of confirmations) {
        this.getConfirmationTradeId(confirmation, (error, updatedConfirmation) => {
          finalConfirmations.push(updatedConfirmation);

          // If we've finalized each confirmation, callback()
          if (finalConfirmations.length == confirmations.length) {
            callback(null, finalConfirmations);
            return;
          }
        });
      }
    });
  }

  /**
   * Sends the response to accept the confirmation
   * @param  {Confirmation} confirmation The Confirmation we are responding too (or an array of confirmations)
   * @param  {Function}     callback
   * @return {void}
   */
  acceptConfirmation(confirmation, callback) {
    if (!Array.isArray(confirmation)) {
      this._sendConfirmationResponse(confirmation, 'allow', handleConfirmationResponse);
    } else {
      this._sendMultiConfirmationResponse(confirmation, 'allow', handleConfirmationResponse);
    }

    let handleConfirmationResponse = (error, result) => {
      if (error || !result.success) {
        setTimeout(() => {
          this.acceptConfirmation(confirmation, callback);
        }, timeBetweenCalls);

        return;
      }

      callback(true);
    }
  }

  /**
   * This retrieves the tradeId from a confirmation
   * @param  {Confirmation}   confirmation The specific confirmation
   * @param  {Function}       callback
   * @return {void}
   */
  getConfirmationTradeId(confirmation, callback) {
    this._getConfirmationDetails(confirmation, (error, body) => {
      if (error) {
        callback(error, confirmation);
        return;
      }

      let $ = Cheerio.load(body);
      fs.writeFileSync(`output-details.html`, body);

      let tradeId = $('div.tradeoffer').attr('id').match(/\d+/i);

      confirmation.tradeId = tradeId;

      callback(null, confirmation);
    });
  }

  /**
   * Our custom request call, applies headers where needed / etc
   * @param  {String}   url      The URL to be requested
   * @param  {String}   method   The HTTP method (GET, POST, PUT, DELETE)
   * @param  {Object}   form     (Optional) A form to be sent, only works if method is POST
   * @param  {Function} callback
   * @return {void}
   */
  request(url, method, form, callback) {
    if (typeof form === 'function') {
      callback = form;
      form = {};
    }

    // Generate some headers to simulate a real application
    let headers = {
      'accept': 'text/javascript, text/html, application/xml, text/xml, */*',
      'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; Google Nexus 4 - 4.1.1 - API 16 - 768x1280 Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'
    };

    this._request({
      method: method,
      url: url,
      headers: headers,
      form: form
    }, callback);
  }

  /**
   * Sends a confirmation response
   * @param  {Confirmation} confirmation The Confirmation we are responding too
   * @param  {String}       operation    allow / cancel
   * @param  {Function}     callback     The function callback'd
   * @return {void}
   */
  _sendConfirmationResponse(confirmation, operation, callback) {
    let url = `${this.STEAM_BASE}/mobileconf/ajaxop?op=${operation}&${this._generateQueryString(operation)}&cid=${confirmation.id}&ck=${confirmation.key}`;

    this.request(url, 'GET', (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      try {
        let result = JSON.parse(body);
        callback(null, result.success);
      } catch (e) {
        callback(e, null);
      }
    });
  }

  /**
   * Allows multiple confirmations to be sent at once (either all accept, or all deny)
   * @param  {Array}    confirmations The confirmation array
   * @param  {String}   operation     accept / deny
   * @param  {Function} callback
   * @return {void}
   */
  _sendMultiConfirmationResponse(confirmations, operation, callback) {
    let url = `${this.STEAM_BASE}/mobileconf/multiajaxop`;
    let queryVariables = this._generateQueryVariables(operation);

    // Initialize our form
    let form = {
      op: operation,
      cid: [],
      ck: []
    };

    // Move our query variables to the new form
    _.extend(form, queryVariables);

    // Loop over each confirmation, adding each id / key to their respective array
    for (let confirmation of confirmations) {
      form.cid.push(confirmation.id);
      form.ck.push(confirmation.key);
    }

    this.request(url, 'POST', form, (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      try {
        let result = JSON.parse(body);
        callback(null, result.success);
      } catch (e) {
        callback(e, null);
      }
    });
  }

  /**
   * Gets the confirmation details
   * @param  {Confirmation} confirmation The Confirmation we care about
   * @param {Function} callback
   * @return {void}
   */
  _getConfirmationDetails(confirmation, callback) {
    let url = `${this.STEAM_BASE}/mobileconf/details/${confirmation.id}?${this._generateQueryString('details')}`;

    this.request(url, 'GET', (err, response, body) => {
      let error = checkResponse(err, response, body);

      if (error) {
        callback(error, null);
        return;
      }

      callback(null, body);
    });
  }

  /**
   * Generates the HTTP query string, to be prepended to all GET requests
   * @param  {String} tag The action. "conf" to load the confirmations page, "details" to load details about a trade, "allow" to confirm a trade, "cancel" to cancel it.
   * @return {String}     The generated string
   */
  _generateQueryString(tag) {
    let queryVariables = this._generateQueryVariables(tag);
    let queryString = '';

    // Generate our string
    for (let name in queryVariables) {
      queryString += `${name}=${queryVariables[name]}&`;
    }

    // Remove trailing &
    queryString = queryString.slice(0, -1);

    return queryString;
  }

  /**
   * Actually generate the needed variables
   * @param  {String} tag Action tag
   * @return {Object}     The variables, zipped together a nice & neat object!
   */
  _generateQueryVariables(tag) {
    let time = Math.floor(Date.now() / 1000) + this.steamOffset;

    let result = {
      p: this.deviceId,
      a: this.steamId,
      k: SteamTotp.generateConfirmationKey(this.identitySecret, time, tag),
      t: time,
      m: 'android',
      tag: tag
    };

    return result;
  }
}

/**
 * Checks the HTTP response
 * @param  {Error} error    An HTTP error
 * @param  {Object} response The HTTP response object
 * @param  {Object} body     The HTTP body
 * @return {Error}          An error, if one exists (null otherwise)
 */
function checkResponse(error, response, body) {
  if (error || response.statusCode != 200) {
    return error || new Error(response.statusCode);
  }

  if (!body) {
    return new Error('Invalid response body');
  }

  return null;
}

module.exports = SteamCommunityMobileConfirmations;
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs');
var program = require('commander');
var pkg = require('./package.json');

// program basic
program.version(pkg.version);
program.description('Pacificate your CSS');

// before
var css = ".class{color:#fff;}";

// after
var css_2 = ".class {\n\tcolor: #fff;\n}";

// show
console.log(css);
console.log(css_2);

// program.command( '<name>' );

// program.action(function nam( name ) {

// 	fs.writeFile('message.css', name);

// });

// program.parse( process.argv );
<commit_msg>regular expression rules added<commit_after>#!/usr/bin/env node

// var fs = require('fs');
// var program = require('commander');
// var pkg = require('./package.json');

// program basic
// program.version(pkg.version);
// program.description('Pacificate your CSS');

// The CSS
var css = ".clGDGDASS__s{ bacjground-color:url('dwdwd');}.rer{ color:#660066;}";
console.log("Before:\n"+css);

css = css.replace(/\s/g, ""); //Retira todos os espacos em branco e quebras de linha e identacao
css = css.toLowerCase(); //Transforma todos os caracteres para minusculo
css = css.replace(/\'/g, "\""); //Altera todas as ' para "
css = css.replace(/_/g, "-"); //Altera todas os _ para -
css = css.replace(/\{/g, " \{\n"); //Adiciona um espaco antes do { e uma quebra de linha apos
css = css.replace(/(.*[\:])/g, "\t$1"); //Adiciona identacao aos textos terminados em :
css = css.replace(/\:/g, "\: "); //Adiona um espaco apos os :
css = css.replace(/\;/g, "\;\n"); //Adiciona uma quebra de linha apos o ;
css = css.replace(/\}/g, "\}\n\n"); //Adiciona duas quebras de linha apos o }

//Result
console.log("After:\n"+css);

// program.command( '<name>' );

// program.action(function nam( name ) {

// 	fs.writeFile('message.css', name);

// });

// program.parse( process.argv );
<|endoftext|>


<commit_before>(function () {
    'use strict';

    // through2 is a thin wrapper around node transform streams
    var through = require('through2');
    var gutil = require('gulp-util');
    var mustache = require('mustache');
    var PluginError = gutil.PluginError;
    var File = require('vinyl');
    var fs = require('fs');
    var extend = require('node.extend');

    // consts
    var PLUGIN_NAME = 'gulp-ng-scaffold';

    var OPTIONS = {
        debug: true,

        appName: 'myApp',

        resourceOutput: '.build/resources',

        testsOutput: '.build/tests',

        serverBase: 'http://webapi.myApp.local/',

        resourceConfigName: 'resourceConfig',
    };

    var buildTestUrl = function (url, parameters) {
        var testPath = url;
        for (var index in parameters) {
            if (parameters.hasOwnProperty(index)) {
                testPath = testPath.replace(':' + parameters[index].name, parameters[index].testValue);
            }
        }
        return testPath;
    };

    function getPaths(model) {
        var paths = [];
        var pathKeys = Object.keys(model.paths);

        for (var i = 0; i < pathKeys.length; i++) {
            var path = model.paths[pathKeys[i]];
            path.url = pathKeys[i];
            paths.push(path);
        }
        return paths;
    }

    function getTags(model) {
        var tags = [];

        var paths = getPaths(model);

        for (var i = 0; i < paths.length; i++) {
            var requestModels = getRequestModelsForPath(paths[i]);
            for (var j = 0; j < requestModels.length; j++) {
                var request = requestModels[j].request;
                tags = tags.concat(request.tags);
            }
        }

        tags = tags.filter(function onlyUnique(value, index, self) {
            return self.indexOf(value) === index;
        });

        return tags;
    }

    function getRequestModelsForPath(path) {
        var requestModels = [];
        var requestKeys = Object.keys(path);
        for (var i = 0; i < requestKeys.length; i++) {
            if (requestKeys[i] !== 'url') {
                var requestModel = {
                    url: path.url,
                    action: requestKeys[i].toUpperCase(),
                    request: path[requestKeys[i]]
                };
                requestModels.push(requestModel);
            }
        }
        return requestModels;
    }

    function getPathsForTag(model, tag) {
        var paths = getPaths(model);
        return paths.filter(function onlyForTag(value, index, self) {
            var requestModels = getRequestModelsForPath(value);
            for (var i = 0; i < requestModels.length; i++) {
                for (var j = 0; j < requestModels[i].request.tags.length; j++) {
                    if (requestModels[i].request.tags[j] === tag) {
                        return true
                    }
                }
            }
            return false;
        });
    }

    var firstLetterToLowerCase = function (str) {
        return str.substr(0, 1).toLowerCase() + str.substr(1);
    };

    function getMethodNameFromRequest(request) {
        return firstLetterToLowerCase(request.operationId.split('_')[1]);
    }

    function buildMethodFromRequest(requestModel) {
        var isGet = false || requestModel.action === 'GET';
        var hasPathParameters = false;
        var hasBodyParameters = false;
        var isArrayResponse = requestModel.request.responses['200'].schema.type === 'array';
        var url = JSON.parse(JSON.stringify(requestModel.url));
        var parameters = []
        if (requestModel.request.parameters) {
            for (var i = 0; i < requestModel.request.parameters.length; i++) {
                hasPathParameters = hasPathParameters || requestModel.request.parameters[i].in === 'path';
                hasBodyParameters = hasBodyParameters || requestModel.request.parameters[i].in === 'body';
                var parameter = {
                    type: requestModel.request.parameters[i].type,
                    name: firstLetterToLowerCase(requestModel.request.parameters[i].name),
                    isPathParameter: requestModel.request.parameters[i].in === 'path',
                    isBodyParameter: requestModel.request.parameters[i].in === 'body',
                    isStringParameter: requestModel.request.parameters[i].type === 'string'
                };

                if (parameter.type === 'integer' || parameter.type === 'long' || parameter.type === 'double' || parameter.type === 'float' || parameter.type === 'decimal') {
                    parameter.testValue = 1;
                }

                if (parameter.type === 'string') {
                    parameter.testValue = 'test';
                }

                if (parameter.type === 'char') {
                    parameter.testValue = 'a';
                }

                if (parameter.type === 'bool' || parameter.type === 'boolean') {
                    parameter.testValue = true;
                }

                if (parameter.type === 'Guid') {
                    parameter.testValue = '25892e17-80f6-415f-9c65-7395632f0223';
                }

                if (parameter.type === undefined) {
                    parameter.type = 'object';
                    parameter.testValue = '{}';
                }
                url = url.replace('{' + requestModel.request.parameters[i].name + '}', ':' + parameter.name)
                parameters.push(parameter);
            }
        }

        for (var j = 0; j < parameters.length; j++) {
            parameters[j].hasBodyAndPathParameters = hasPathParameters && hasBodyParameters;
        }

        return {
            action: requestModel.action,
            methodName: getMethodNameFromRequest(requestModel.request),
            url: url,
            parameters: parameters,
            isGet: isGet,
            isArrayResponse: isArrayResponse,
            hasParameters: hasPathParameters || hasBodyParameters,
            hasPathParameters: hasPathParameters,
            hasBodyParameters: hasBodyParameters,
            hasBodyAndPathParameters: hasPathParameters && hasBodyParameters,
            testUrl: buildTestUrl(url, parameters)
        }
    }

    function buildResourceModelFromPaths(paths, tag) {

        var methods = [];
        for (var i = 0; i < paths.length; i++) {
            var requestModels = getRequestModelsForPath(paths[i]);
            for (var j = 0; j < requestModels.length; j++) {
                methods.push(buildMethodFromRequest(requestModels[j]))
            }
        }

        var resourceModel = {
            appName: OPTIONS.appName,
            controllerName: tag,
            appEnvironmentName: OPTIONS.resourceConfigName,
            methods: methods
        }

        return resourceModel;
    }

    function buildResourceForTag(model, tag, template) {
        var paths = getPathsForTag(model, tag);
        var resourceModel = buildResourceModelFromPaths(paths, tag);
        return mustache.render(template, resourceModel);
    }

    function buildResources(model, template) {
        var resourceFiles = [];
        var tags = getTags(model);

        for (var i = 0; i < tags.length; i++) {
            var resourceContents = buildResourceForTag(model, tags[i], template);
            var resourceFile = new File({
                cwd: "/",
                base: OPTIONS.resourceOutput + '/',
                path: OPTIONS.resourceOutput + '/' + tags[i] + '.js',
                contents: new Buffer(resourceContents)
            });
            resourceFiles.push(resourceFile);
        }

        return resourceFiles;
    }

    function buildResourceTests(model, template) {
        var resourceFiles = [];
        var tags = getTags(model);

        for (var i = 0; i < tags.length; i++) {
            var resourceContents = buildResourceForTag(model, tags[i], template);
            var resourceFile = new File({
                cwd: "/",
                base: OPTIONS.resourceOutput + '/',
                path: OPTIONS.resourceOutput + '/' + tags[i] + '.spec.js',
                contents: new Buffer(resourceContents)
            });
            resourceFiles.push(resourceFile);
        }

        return resourceFiles;
    }

    function buildResourceConfig(model, template) {
        var resourceContents = mustache.render(template, model);
        var resourceConfigFile = new File({
            cwd: "/",
            base: OPTIONS.resourceOutput + '/',
            path: OPTIONS.resourceOutput + '/resource.config.js',
            contents: new Buffer(resourceContents)
        });
        return resourceConfigFile
    }

    function readFile(filename, callback) {
        try {
            console.log(filename)
            fs.readFile(filename, 'utf8', callback);
        } catch (e) {
            callback(e);
        }
    }

    function scaffold(options, data, render) {
        return through.obj(function (file, enc, cb) {
            var vm = this;

             vm.templatePaths = {
                angularResource: __dirname + '\\templates\\angular-resource.mustache',
                angularResourceTest: __dirname + '\\templates\\angular-resource-test.mustache',
                resourceConfig: __dirname + '\\templates\\resource.config.mustache'
            }

            if (file.isNull()) {
                cb(null, file);
                return;
            }

            if (file.isStream()) {
                cb(new gutil.PluginError('gulp-ng-scaffold', 'Streaming not supported'));
                return;
            }

            OPTIONS = extend(true, OPTIONS, options);

            vm.cb = function () {
                if (vm.resourcesScaffolded && vm.testsScaffolded && vm.configScaffolded) {
                    cb();
                }
            }

            readFile(vm.templatePaths.angularResource, function (templateError, template) {
                if (templateError) {
                    console.log(templateError);
                }

                try {
                    var model = JSON.parse(file.contents.toString());
                    var resourceFiles = buildResources(model, template);

                    for (var i = 0; i < resourceFiles.length; i++) {
                        vm.push(resourceFiles[i]);
                    }
                    vm.resourcesScaffolded = true;
                    vm.cb()

                } catch (err) {
                    vm.emit('error', new gutil.PluginError('gulp-ng-scaffold', err, { fileName: file.path }));
                }
            });

            readFile(vm.templatePaths.angularResourceTest, function (templateError, template) {
                if (templateError) {
                    console.log(templateError);
                }

                try {
                    var model = JSON.parse(file.contents.toString());
                    var resourceTestFiles = buildResourceTests(model, template);

                    for (var i = 0; i < resourceTestFiles.length; i++) {
                        vm.push(resourceTestFiles[i]);
                    }
                    vm.testsScaffolded = true;
                    vm.cb()

                } catch (err) {
                    vm.emit('error', new gutil.PluginError('gulp-ng-scaffold', err, { fileName: file.path }));
                }
            });

            readFile(vm.templatePaths.resourceConfig, function (templateError, template) {
                if (templateError) {
                    console.log(templateError);
                }

                try {
                    var resourceConfigFile = buildResourceConfig(OPTIONS, template);

                    vm.push(resourceConfigFile);

                    vm.configScaffolded = true;
                    vm.cb()

                } catch (err) {
                    vm.emit('error', new gutil.PluginError('gulp-ng-scaffold', err, { fileName: file.path }));
                }
            });
        });
    }

    module.exports = function (options, data) {
        return scaffold(options, data, true);
    };

})();<commit_msg>Removed logging info.<commit_after>(function () {
    'use strict';

    // through2 is a thin wrapper around node transform streams
    var through = require('through2');
    var gutil = require('gulp-util');
    var mustache = require('mustache');
    var PluginError = gutil.PluginError;
    var File = require('vinyl');
    var fs = require('fs');
    var extend = require('node.extend');

    // consts
    var PLUGIN_NAME = 'gulp-ng-scaffold';

    var OPTIONS = {
        debug: true,

        appName: 'myApp',

        resourceOutput: '.build/resources',

        testsOutput: '.build/tests',

        serverBase: 'http://webapi.myApp.local/',

        resourceConfigName: 'resourceConfig',
    };

    var buildTestUrl = function (url, parameters) {
        var testPath = url;
        for (var index in parameters) {
            if (parameters.hasOwnProperty(index)) {
                testPath = testPath.replace(':' + parameters[index].name, parameters[index].testValue);
            }
        }
        return testPath;
    };

    function getPaths(model) {
        var paths = [];
        var pathKeys = Object.keys(model.paths);

        for (var i = 0; i < pathKeys.length; i++) {
            var path = model.paths[pathKeys[i]];
            path.url = pathKeys[i];
            paths.push(path);
        }
        return paths;
    }

    function getTags(model) {
        var tags = [];

        var paths = getPaths(model);

        for (var i = 0; i < paths.length; i++) {
            var requestModels = getRequestModelsForPath(paths[i]);
            for (var j = 0; j < requestModels.length; j++) {
                var request = requestModels[j].request;
                tags = tags.concat(request.tags);
            }
        }

        tags = tags.filter(function onlyUnique(value, index, self) {
            return self.indexOf(value) === index;
        });

        return tags;
    }

    function getRequestModelsForPath(path) {
        var requestModels = [];
        var requestKeys = Object.keys(path);
        for (var i = 0; i < requestKeys.length; i++) {
            if (requestKeys[i] !== 'url') {
                var requestModel = {
                    url: path.url,
                    action: requestKeys[i].toUpperCase(),
                    request: path[requestKeys[i]]
                };
                requestModels.push(requestModel);
            }
        }
        return requestModels;
    }

    function getPathsForTag(model, tag) {
        var paths = getPaths(model);
        return paths.filter(function onlyForTag(value, index, self) {
            var requestModels = getRequestModelsForPath(value);
            for (var i = 0; i < requestModels.length; i++) {
                for (var j = 0; j < requestModels[i].request.tags.length; j++) {
                    if (requestModels[i].request.tags[j] === tag) {
                        return true
                    }
                }
            }
            return false;
        });
    }

    var firstLetterToLowerCase = function (str) {
        return str.substr(0, 1).toLowerCase() + str.substr(1);
    };

    function getMethodNameFromRequest(request) {
        return firstLetterToLowerCase(request.operationId.split('_')[1]);
    }

    function buildMethodFromRequest(requestModel) {
        var isGet = false || requestModel.action === 'GET';
        var hasPathParameters = false;
        var hasBodyParameters = false;
        var isArrayResponse = requestModel.request.responses['200'].schema.type === 'array';
        var url = JSON.parse(JSON.stringify(requestModel.url));
        var parameters = []
        if (requestModel.request.parameters) {
            for (var i = 0; i < requestModel.request.parameters.length; i++) {
                hasPathParameters = hasPathParameters || requestModel.request.parameters[i].in === 'path';
                hasBodyParameters = hasBodyParameters || requestModel.request.parameters[i].in === 'body';
                var parameter = {
                    type: requestModel.request.parameters[i].type,
                    name: firstLetterToLowerCase(requestModel.request.parameters[i].name),
                    isPathParameter: requestModel.request.parameters[i].in === 'path',
                    isBodyParameter: requestModel.request.parameters[i].in === 'body',
                    isStringParameter: requestModel.request.parameters[i].type === 'string'
                };

                if (parameter.type === 'integer' || parameter.type === 'long' || parameter.type === 'double' || parameter.type === 'float' || parameter.type === 'decimal') {
                    parameter.testValue = 1;
                }

                if (parameter.type === 'string') {
                    parameter.testValue = 'test';
                }

                if (parameter.type === 'char') {
                    parameter.testValue = 'a';
                }

                if (parameter.type === 'bool' || parameter.type === 'boolean') {
                    parameter.testValue = true;
                }

                if (parameter.type === 'Guid') {
                    parameter.testValue = '25892e17-80f6-415f-9c65-7395632f0223';
                }

                if (parameter.type === undefined) {
                    parameter.type = 'object';
                    parameter.testValue = '{}';
                }
                url = url.replace('{' + requestModel.request.parameters[i].name + '}', ':' + parameter.name)
                parameters.push(parameter);
            }
        }

        for (var j = 0; j < parameters.length; j++) {
            parameters[j].hasBodyAndPathParameters = hasPathParameters && hasBodyParameters;
        }

        return {
            action: requestModel.action,
            methodName: getMethodNameFromRequest(requestModel.request),
            url: url,
            parameters: parameters,
            isGet: isGet,
            isArrayResponse: isArrayResponse,
            hasParameters: hasPathParameters || hasBodyParameters,
            hasPathParameters: hasPathParameters,
            hasBodyParameters: hasBodyParameters,
            hasBodyAndPathParameters: hasPathParameters && hasBodyParameters,
            testUrl: buildTestUrl(url, parameters)
        }
    }

    function buildResourceModelFromPaths(paths, tag) {

        var methods = [];
        for (var i = 0; i < paths.length; i++) {
            var requestModels = getRequestModelsForPath(paths[i]);
            for (var j = 0; j < requestModels.length; j++) {
                methods.push(buildMethodFromRequest(requestModels[j]))
            }
        }

        var resourceModel = {
            appName: OPTIONS.appName,
            controllerName: tag,
            appEnvironmentName: OPTIONS.resourceConfigName,
            methods: methods
        }

        return resourceModel;
    }

    function buildResourceForTag(model, tag, template) {
        var paths = getPathsForTag(model, tag);
        var resourceModel = buildResourceModelFromPaths(paths, tag);
        return mustache.render(template, resourceModel);
    }

    function buildResources(model, template) {
        var resourceFiles = [];
        var tags = getTags(model);

        for (var i = 0; i < tags.length; i++) {
            var resourceContents = buildResourceForTag(model, tags[i], template);
            var resourceFile = new File({
                cwd: "/",
                base: OPTIONS.resourceOutput + '/',
                path: OPTIONS.resourceOutput + '/' + tags[i] + '.js',
                contents: new Buffer(resourceContents)
            });
            resourceFiles.push(resourceFile);
        }

        return resourceFiles;
    }

    function buildResourceTests(model, template) {
        var resourceFiles = [];
        var tags = getTags(model);

        for (var i = 0; i < tags.length; i++) {
            var resourceContents = buildResourceForTag(model, tags[i], template);
            var resourceFile = new File({
                cwd: "/",
                base: OPTIONS.resourceOutput + '/',
                path: OPTIONS.resourceOutput + '/' + tags[i] + '.spec.js',
                contents: new Buffer(resourceContents)
            });
            resourceFiles.push(resourceFile);
        }

        return resourceFiles;
    }

    function buildResourceConfig(model, template) {
        var resourceContents = mustache.render(template, model);
        var resourceConfigFile = new File({
            cwd: "/",
            base: OPTIONS.resourceOutput + '/',
            path: OPTIONS.resourceOutput + '/resource.config.js',
            contents: new Buffer(resourceContents)
        });
        return resourceConfigFile
    }

    function readFile(filename, callback) {
        try {
            fs.readFile(filename, 'utf8', callback);
        } catch (e) {
            callback(e);
        }
    }

    function scaffold(options, data, render) {
        return through.obj(function (file, enc, cb) {
            var vm = this;

             vm.templatePaths = {
                angularResource: __dirname + '\\templates\\angular-resource.mustache',
                angularResourceTest: __dirname + '\\templates\\angular-resource-test.mustache',
                resourceConfig: __dirname + '\\templates\\resource.config.mustache'
            }

            if (file.isNull()) {
                cb(null, file);
                return;
            }

            if (file.isStream()) {
                cb(new gutil.PluginError('gulp-ng-scaffold', 'Streaming not supported'));
                return;
            }

            OPTIONS = extend(true, OPTIONS, options);

            vm.cb = function () {
                if (vm.resourcesScaffolded && vm.testsScaffolded && vm.configScaffolded) {
                    cb();
                }
            }

            readFile(vm.templatePaths.angularResource, function (templateError, template) {
                if (templateError) {
                    console.log(templateError);
                }

                try {
                    var model = JSON.parse(file.contents.toString());
                    var resourceFiles = buildResources(model, template);

                    for (var i = 0; i < resourceFiles.length; i++) {
                        vm.push(resourceFiles[i]);
                    }
                    vm.resourcesScaffolded = true;
                    vm.cb()

                } catch (err) {
                    vm.emit('error', new gutil.PluginError('gulp-ng-scaffold', err, { fileName: file.path }));
                }
            });

            readFile(vm.templatePaths.angularResourceTest, function (templateError, template) {
                if (templateError) {
                    console.log(templateError);
                }

                try {
                    var model = JSON.parse(file.contents.toString());
                    var resourceTestFiles = buildResourceTests(model, template);

                    for (var i = 0; i < resourceTestFiles.length; i++) {
                        vm.push(resourceTestFiles[i]);
                    }
                    vm.testsScaffolded = true;
                    vm.cb()

                } catch (err) {
                    vm.emit('error', new gutil.PluginError('gulp-ng-scaffold', err, { fileName: file.path }));
                }
            });

            readFile(vm.templatePaths.resourceConfig, function (templateError, template) {
                if (templateError) {
                    console.log(templateError);
                }

                try {
                    var resourceConfigFile = buildResourceConfig(OPTIONS, template);

                    vm.push(resourceConfigFile);

                    vm.configScaffolded = true;
                    vm.cb()

                } catch (err) {
                    vm.emit('error', new gutil.PluginError('gulp-ng-scaffold', err, { fileName: file.path }));
                }
            });
        });
    }

    module.exports = function (options, data) {
        return scaffold(options, data, true);
    };

})();<|endoftext|>


<commit_before>var debug = require('debug')('pg-bricks');
var pf = require('point-free');
var sql = require('sql-bricks-postgres');
var pg = require('pg');

function _expectRow(res, callback) {
    if (res.rows.length === 0)
        return callback(new Error('Expected a row, none found'), res);
    if (res.rows.length > 1)
        return callback(new Error('Expected a single row, multiple found'), res);
    return callback(null, res)
}
function _expectCol(res, callback) {
    if (res.fields.length === 0)
        return callback(new Error('Expected a column, none found'), res);
    if (res.fields.length > 1)
        return callback(new Error('Expected a single column, multiple found'), res);
    return callback(null, res)
}

var Accessors = {
    rows: function (res, callback) {
        callback(null, res.rows)
    },
    row: pf.waterfall(
        _expectRow,
        function (res, callback) { callback(null, res.rows[0]) }
    ),
    col: pf.waterfall(
        _expectCol,
        function (res, callback) {
            var field = res.fields[0].name;
            callback(null, res.rows.map(function (row) { return row[field] }));
        }
    ),
    val: pf.waterfall(
        _expectRow,
        _expectCol,
        function (res, callback) {
            var field = res.fields[0].name;
            callback(null, res.rows[0][field]);
        }
    )
}

function RawSQL(text, values) {
    return {
        toParams: function () {
            return {text: text, values: values || []}
        }
    }
}

function instrument(client) {
    if (client.update) return;

    ['select', 'insert', 'update', 'delete', 'raw'].forEach(function (statement) {
        client[statement] = function () {
            var brick = statement == 'raw' ? RawSQL.apply(this, arguments)
                                           : sql[statement].apply(sql, arguments);

            brick.run = function (callback) {
                var config = brick.toParams();
                config.callback = callback;
                return this.query(config);
            }.bind(this);

            // Bind accessors
            brick.rows = pf.waterfall(brick.run, Accessors.rows);
            brick.row  = pf.waterfall(brick.run, Accessors.row);
            brick.col  = pf.waterfall(brick.run, Accessors.col);
            brick.val  = pf.waterfall(brick.run, Accessors.val);

            // Patch insert().select()
            if (statement == 'insert') {
                brick.select = function select() {
                    var select = sql.insert.prototype.select.apply(this, arguments);
                    ['run', 'rows', 'row', 'col', 'val'].forEach(function (method) {
                        select[method] = brick[method];
                    })
                    return select;
                }
            }

            return brick;
        }
    })

    if (client !== Conf.prototype) {
        var oldQuery = client.query;
        client.query = function (query, params, callback) {
            var query = query instanceof pg.Query ? query : new pg.Query(query, params, callback);
            debug('%s %o', query.text, query.values);
            return instrumentQuery(oldQuery.call(client, query));
        }
    }
}

function instrumentQuery(query) {
    query.pipe = function (dest) {
        query.on('error', dest.emit.bind(dest, 'error'));
        query.on('row', function (row) {
            dest.write(row);
        });
        query.on('end', function (res) {
            dest.end();
        });
        return dest;
    }
    return query;
}

// A Conf object
function Conf(connStr) {
    this._connStr = connStr;
}

Conf.prototype = {
    sql: sql,
    pg: pg,

    run: function (func, callback) {
        pg.connect(this._connStr, function(err, client, done) {
            if (err) return callback(err);

            instrument(client);

            func(client, function () {
                done();
                callback.apply(null, arguments);
            })
        });
    },

    query: function (query, params, callback) {
        query = new pg.Query(query, params, callback);
        callback = query.callback;

        if (callback) {
            // Callback style
            this.run(function (client, done) {
                query.callback = done;
                client.query(query);
            }, callback);
        } else {
            // Streaming style
            this.run(function (client, done) {
                query.on('end', done);
                query.on('error', done);
                client.query(query);
            }, function () {});
        }

        return instrumentQuery(query);
    },

    transaction: function (func, callback) {
        var results;

        this.run(function (client, callback) {
            pf.serial(
                function (callback) {
                    client.query('begin', callback);
                },
                function (callback) {
                    func(client, function () {
                        // Capture func results
                        results = arguments;
                        callback.apply(null, arguments);
                    })
                },
                function (callback) {
                    client.query('commit', callback);
                }
            )(function (err) {
                if (err) return client.query('rollback', function () {
                    callback(err);
                });
                // Resend results from func
                callback.apply(null, results);
            })
        }, callback)
    }
}
instrument(Conf.prototype);

// Exports
exports.sql = sql;

exports.configure = function (connStr) {
    return new Conf(connStr)
}
<commit_msg>Add some comments and newlines<commit_after>var debug = require('debug')('pg-bricks');
var pf = require('point-free');
var sql = require('sql-bricks-postgres');
var pg = require('pg');

function _expectRow(res, callback) {
    if (res.rows.length === 0)
        return callback(new Error('Expected a row, none found'), res);
    if (res.rows.length > 1)
        return callback(new Error('Expected a single row, multiple found'), res);
    return callback(null, res)
}

function _expectCol(res, callback) {
    if (res.fields.length === 0)
        return callback(new Error('Expected a column, none found'), res);
    if (res.fields.length > 1)
        return callback(new Error('Expected a single column, multiple found'), res);
    return callback(null, res)
}

var Accessors = {
    rows: function (res, callback) {
        callback(null, res.rows)
    },
    row: pf.waterfall(
        _expectRow,
        function (res, callback) { callback(null, res.rows[0]) }
    ),
    col: pf.waterfall(
        _expectCol,
        function (res, callback) {
            var field = res.fields[0].name;
            callback(null, res.rows.map(function (row) { return row[field] }));
        }
    ),
    val: pf.waterfall(
        _expectRow,
        _expectCol,
        function (res, callback) {
            var field = res.fields[0].name;
            callback(null, res.rows[0][field]);
        }
    )
}

function RawSQL(text, values) {
    return {
        toParams: function () {
            return {text: text, values: values || []}
        }
    }
}

function instrument(client) {
    if (client.update) return;

    // Monkey patch statement constructors to pg client and make them runnable
    ['select', 'insert', 'update', 'delete', 'raw'].forEach(function (statement) {
        client[statement] = function () {
            var brick = statement == 'raw' ? RawSQL.apply(this, arguments)
                                           : sql[statement].apply(sql, arguments);

            brick.run = function (callback) {
                var config = brick.toParams();
                config.callback = callback;
                return this.query(config);
            }.bind(this);

            // Bind accessors
            brick.rows = pf.waterfall(brick.run, Accessors.rows);
            brick.row  = pf.waterfall(brick.run, Accessors.row);
            brick.col  = pf.waterfall(brick.run, Accessors.col);
            brick.val  = pf.waterfall(brick.run, Accessors.val);

            // Patch insert().select()
            if (statement == 'insert') {
                brick.select = function select() {
                    var select = sql.insert.prototype.select.apply(this, arguments);
                    ['run', 'rows', 'row', 'col', 'val'].forEach(function (method) {
                        select[method] = brick[method];
                    })
                    return select;
                }
            }

            return brick;
        }
    })

    if (client !== Conf.prototype) {
        var oldQuery = client.query;
        client.query = function (query, params, callback) {
            var query = query instanceof pg.Query ? query : new pg.Query(query, params, callback);
            debug('%s %o', query.text, query.values);
            return instrumentQuery(oldQuery.call(client, query));
        }
    }
}

function instrumentQuery(query) {
    query.pipe = function (dest) {
        query.on('error', dest.emit.bind(dest, 'error'));
        query.on('row', function (row) {
            dest.write(row);
        });
        query.on('end', function (res) {
            dest.end();
        });
        return dest;
    }
    return query;
}

// A Conf object
function Conf(connStr) {
    this._connStr = connStr;
}

Conf.prototype = {
    sql: sql,
    pg: pg,

    run: function (func, callback) {
        pg.connect(this._connStr, function(err, client, done) {
            if (err) return callback(err);

            instrument(client);

            func(client, function () {
                done();
                callback.apply(null, arguments);
            })
        });
    },

    query: function (query, params, callback) {
        query = new pg.Query(query, params, callback);
        callback = query.callback;

        if (callback) {
            // Callback style
            this.run(function (client, done) {
                query.callback = done;
                client.query(query);
            }, callback);
        } else {
            // Streaming style
            this.run(function (client, done) {
                query.on('end', done);
                query.on('error', done);
                client.query(query);
            }, function () {});
        }

        return instrumentQuery(query);
    },

    transaction: function (func, callback) {
        var results;

        this.run(function (client, callback) {
            pf.serial(
                function (callback) {
                    client.query('begin', callback);
                },
                function (callback) {
                    func(client, function () {
                        // Capture func results
                        results = arguments;
                        callback.apply(null, arguments);
                    })
                },
                function (callback) {
                    client.query('commit', callback);
                }
            )(function (err) {
                if (err) return client.query('rollback', function () {
                    callback(err);
                });
                // Resend results from func
                callback.apply(null, results);
            })
        }, callback)
    }
}
// Add statement constructors to Conf object
instrument(Conf.prototype);

// Exports
exports.sql = sql;

exports.configure = function (connStr) {
    return new Conf(connStr)
}
<|endoftext|>


<commit_before>// TODO: remove when window.queueMicrotask() is well supported
const queueMicrotask = require('queue-microtask')

class ImmediateStore {
  constructor (store) {
    this.store = store
    this.chunkLength = store.chunkLength

    if (!this.store || !this.store.get || !this.store.put) {
      throw new Error('First argument must be abstract-chunk-store compliant')
    }

    this.mem = []
  }

  put (index, buf, cb) {
    this.mem[index] = buf
    this.store.put(index, buf, err => {
      this.mem[index] = null
      if (cb) cb(err)
    })
  }

  get (index, opts, cb) {
    if (typeof opts === 'function') return this.get(index, null, opts)

    const start = (opts && opts.offset) || 0
    const end = opts && opts.length && (start + opts.length)

    const buf = this.mem[index]

    // if the chunk is in the temporary memory cache
    if (buf) {
      // queueMicrotask to ensure the function is async
      queueMicrotask(() => cb(null, opts ? buf.slice(start, end) : buf))
    } else {
      this.store.get(index, opts, cb)
    }
  }

  close (cb) {
    this.store.close(cb)
  }

  destroy (cb) {
    this.store.destroy(cb)
  }
}

module.exports = ImmediateStore
<commit_msg>refactor get() for readability<commit_after>// TODO: remove when window.queueMicrotask() is well supported
const queueMicrotask = require('queue-microtask')

class ImmediateStore {
  constructor (store) {
    this.store = store
    this.chunkLength = store.chunkLength

    if (!this.store || !this.store.get || !this.store.put) {
      throw new Error('First argument must be abstract-chunk-store compliant')
    }

    this.mem = []
  }

  put (index, buf, cb) {
    this.mem[index] = buf
    this.store.put(index, buf, err => {
      this.mem[index] = null
      if (cb) cb(err)
    })
  }

  get (index, opts, cb) {
    if (typeof opts === 'function') return this.get(index, null, opts)
    if (!opts) opts = {}

    const memoryBuffer = this.mem[index]

    // if the chunk isn't in the immediate memory cache
    if (!memoryBuffer) {
      return this.store.get(index, opts, cb)
    }

    const start = opts.offset || 0
    const end = opts.length ? (start + opts.length) : memoryBuffer.length

    const slicedBuffer = memoryBuffer.slice(start, end)

    // queueMicrotask to ensure the function is async
    queueMicrotask(() => cb(null, slicedBuffer))
  }

  close (cb) {
    this.store.close(cb)
  }

  destroy (cb) {
    this.store.destroy(cb)
  }
}

module.exports = ImmediateStore
<|endoftext|>