<commit_before>'use strict'

var Qlobber = require('qlobber').Qlobber
var Packet = require('aedes-packet')
var through = require('through2')
var msgpack = require('msgpack-lite')
var callbackStream = require('callback-stream')
var pump = require('pump')
var EventEmitter = require('events').EventEmitter
var inherits = require('util').inherits
var multistream = require('multistream')

var QlobberOpts = {
  wildcard_one: '+',
  wildcard_some: '#',
  separator: '/'
}
var RETAINED = 'retained:'
var SUBSCRIPTIONS = 'subscriptions:'
var OUTGOING = 'outgoing:'
var OUTGOINGID = 'outgoing-id:'
var INCOMING = 'incoming:'
var WILL = 'will:'
var dbopts = {
  valueEncoding: msgpack
}

function LevelPersistence (db) {
  if (!(this instanceof LevelPersistence)) {
    return new LevelPersistence(db)
  }

  this._db = db
  this._trie = new Qlobber(QlobberOpts)
  this._ready = false

  var trie = this._trie
  var that = this

  pump(this._db.createValueStream({
    gt: SUBSCRIPTIONS,
    lt: SUBSCRIPTIONS + '\xff',
    valueEncoding: msgpack
  }), through.obj(function (chunk, enc, cb) {
    trie.add(chunk.topic, chunk)
    cb()
  }), function (err) {
    if (err) {
      that.emit('error', err)
      return
    }
    that._ready = true
    that.emit('ready')
  })
}

inherits(LevelPersistence, EventEmitter)

LevelPersistence.prototype.storeRetained = function (packet, cb) {
  if (packet.payload.length === 0) {
    this._db.del(RETAINED + packet.topic, cb)
  } else {
    this._db.put(RETAINED + packet.topic, packet, dbopts, cb)
  }
}

LevelPersistence.prototype.createRetainedStreamCombi = function (patterns) {
  var that = this
  var streams = patterns.map(function (p) {
    return that.createRetainedStream(p)
  })
  return multistream.obj(streams)
}

LevelPersistence.prototype.createRetainedStream = function (pattern) {
  var qlobber = new Qlobber(QlobberOpts)
  qlobber.add(pattern, true)

  var res = through.obj(function (packet, encoding, deliver) {
    if (qlobber.match(packet.topic).length) {
      deliver(null, packet)
    } else {
      deliver()
    }
  })

  pump(this._db.createValueStream({
    gt: 'retained:',
    lt: 'retained\xff',
    valueEncoding: msgpack
  }), res)

  return res
}

function withClientId (sub) {
  return {
    topic: sub.topic,
    clientId: this.id,
    qos: sub.qos
  }
}

function toSubKey (sub) {
  return SUBSCRIPTIONS + sub.clientId + ':' + sub.topic
}

function addSubToTrie (sub) {
  var add
  var matched = this.match(sub.topic)
  if (matched.length > 0) {
    add = true
    for (var i = 0; i < matched.length; i++) {
      if (matched[i].clientId === sub.clientId && matched[i].qos === sub.qos) {
        add = false
        break
      } else if (matched[i].qos !== sub.qos) {
        this.remove(matched[i].topic, matched[i])
        if (sub.qos === 0) {
          add = false
        }
      }
    }
  } else if (sub.qos > 0) {
    add = true
  }

  if (add) {
    this.add(sub.topic, sub)
  }

  return sub
}

LevelPersistence.prototype.addSubscriptions = function (client, subs, cb) {
  if (!this._ready) {
    this.once('ready', this.addSubscriptions.bind(this, client, subs, cb))
    return
  }

  subs = subs
    .map(withClientId, client)
    .map(addSubToTrie, this._trie)

  let opArray = []
  subs.forEach(function (sub) {
    let ops = {}
    ops.type = 'put'
    ops.key = toSubKey(sub)
    ops.value = sub
    opArray.push(ops)
  })

  this._db.batch(opArray, dbopts, function (err) {
    cb(err, client)
  })
}

function toSubObj (topic) {
  return {
    clientId: this.id,
    topic: topic
  }
}

function delSubFromTrie (sub) {
  this
    .match(sub.topic)
    .filter(matching, sub)
    .forEach(rmSub, this)

  return sub
}

function matching (sub) {
  return sub.topic === this.topic && sub.clientId === this.clientId
}

function rmSub (sub) {
  this.remove(sub.topic, sub)
}

LevelPersistence.prototype.removeSubscriptions = function (client, subs, cb) {
  subs = subs
    .map(toSubObj, client)
    .map(delSubFromTrie, this._trie)
  let opArray = []
  subs.forEach(function (sub) {
    let ops = {}
    ops.type = 'del'
    ops.key = toSubKey(sub)
    ops.value = sub
    opArray.push(ops)
  })
  this._db.batch(opArray, dbopts, function (err) {
    cb(err, client)
  })
}

function rmClientId (sub) {
  return {
    topic: sub.topic,
    qos: sub.qos
  }
}

LevelPersistence.prototype.subscriptionsByClient = function (client, cb) {
  this._db.createValueStream({
    gt: SUBSCRIPTIONS + client.id,
    lt: SUBSCRIPTIONS + client.id + '\xff',
    valueEncoding: msgpack
  }).pipe(callbackStream({ objectMode: true }, function (err, subs) {
    var resubs = subs.map(rmClientId)
    if (resubs.length === 0) {
      resubs = null
    }
    cb(err, resubs, client)
  }))
}

LevelPersistence.prototype.countOffline = function (cb) {
  var clients = 0
  var subs = 0
  var lastClient = null
  pump(this._db.createValueStream({
    gt: SUBSCRIPTIONS,
    lt: SUBSCRIPTIONS + '\xff',
    valueEncoding: msgpack
  }), through.obj(function (sub, enc, cb) {
    if (lastClient !== sub.clientId) {
      lastClient = sub.clientId
      clients++
    }
    if (sub.qos > 0) {
      subs++
    }
    cb()
  }), function (err) {
    cb(err, subs, clients)
  })
}

LevelPersistence.prototype.subscriptionsByTopic = function (pattern, cb) {
  if (!this._ready) {
    this.once('ready', this.subscriptionsByTopic.bind(this, pattern, cb))
    return this
  }
  cb(null, this._trie.match(pattern))
}

LevelPersistence.prototype.cleanSubscriptions = function (client, cb) {
  var that = this
  this.subscriptionsByClient(client, function (err, subs) {
    if (err || !subs) { return cb(err, client) }

    that.removeSubscriptions(client, subs.map(function (sub) {
      return sub.topic
    }), function (err) {
      cb(err, client)
    })
  })
}

LevelPersistence.prototype.outgoingEnqueue = function (sub, packet, cb) {
  var key = OUTGOING + sub.clientId + ':' + packet.brokerId + ':' + packet.brokerCounter
  this._db.put(key, new Packet(packet), dbopts, cb)
}

LevelPersistence.prototype.outgoingEnqueueCombi = function (subs, packet, cb) {
  if (!subs || subs.length === 0) {
    return cb(null, packet)
  }
  var count = 0
  for (var i = 0; i < subs.length; i++) {
    this.outgoingEnqueue(subs[i], packet, function (err) {
      if (!err) {
        count++
        if (count === subs.length) {
          cb(null, packet)
        }
      } else {
        cb(err)
      }
    })
  }
}

function updateWithBrokerData (that, client, packet, cb) {
  var prekey = OUTGOING + client.id + ':' + packet.brokerId + ':' + packet.brokerCounter
  var postkey = OUTGOINGID + client.id + ':' + packet.messageId

  that._db.get(prekey, dbopts, function (err, decoded) {
    if (err && err.notFound) {
      cb(new Error('no such packet'), client, packet)
      return
    } else if (err) {
      cb(err, client, packet)
      return
    }

    var batch = that._db.batch()

    if (decoded.messageId > 0) {
      batch.del(OUTGOINGID + client.id + ':' + decoded.messageId)
    }

    batch.put(postkey, packet, dbopts)
    batch.put(prekey, packet, dbopts)

    batch.write(function (err) {
      cb(err, client, packet)
    })
  })
}

function augmentWithBrokerData (that, client, packet, cb) {
  var postkey = OUTGOINGID + client.id + ':' + packet.messageId
  that._db.get(postkey, dbopts, function (err, decoded) {
    if (err && err.notFound) {
      return cb(new Error('no such packet'))
    } else if (err) {
      return cb(err)
    }

    packet.brokerId = decoded.brokerId
    packet.brokerCounter = decoded.brokerCounter
    cb(null)
  })
}

LevelPersistence.prototype.outgoingUpdate = function (client, packet, cb) {
  var that = this
  if (packet.brokerId) {
    updateWithBrokerData(this, client, packet, cb)
  } else {
    augmentWithBrokerData(this, client, packet, function (err) {
      if (err) { return cb(err, client, packet) }

      updateWithBrokerData(that, client, packet, cb)
    })
  }
}

LevelPersistence.prototype.outgoingClearMessageId = function (client, packet, cb) {
  var that = this
  var key = OUTGOINGID + client.id + ':' + packet.messageId
  this._db.get(key, dbopts, function (err, packet) {
    if (err && err.notFound) {
      return cb(null)
    } else if (err) {
      return cb(err)
    }

    var prekey = 'outgoing:' + client.id + ':' + packet.brokerId + ':' + packet.brokerCounter
    var batch = that._db.batch()
    batch.del(key)
    batch.del(prekey)
    batch.write(function (err) {
      cb(err, packet)
    })
  })
}

LevelPersistence.prototype.outgoingStream = function (client) {
  var key = OUTGOING + client.id
  return this._db.createValueStream({
    gt: key,
    lt: key + '\xff',
    valueEncoding: msgpack
  })
}

LevelPersistence.prototype.incomingStorePacket = function (client, packet, cb) {
  var key = INCOMING + client.id + ':' + packet.messageId
  var newp = new Packet(packet)
  newp.messageId = packet.messageId
  this._db.put(key, newp, dbopts, cb)
}

LevelPersistence.prototype.incomingGetPacket = function (client, packet, cb) {
  var key = INCOMING + client.id + ':' + packet.messageId
  this._db.get(key, dbopts, function (err, decoded) {
    if (err && err.notFound) {
      cb(new Error('no such packet'), client)
    } else if (err) {
      cb(err, client)
    } else {
      cb(null, decoded, client)
    }
  })
}

LevelPersistence.prototype.incomingDelPacket = function (client, packet, cb) {
  var key = INCOMING + client.id + ':' + packet.messageId
  this._db.del(key, cb)
}

LevelPersistence.prototype.putWill = function (client, packet, cb) {
  var key = WILL + client.id

  packet.brokerId = this.broker.id
  packet.clientId = client.id

  this._db.put(key, packet, dbopts, function (err) {
    cb(err, client)
  })
}

LevelPersistence.prototype.getWill = function (client, cb) {
  var key = WILL + client.id
  this._db.get(key, dbopts, function (err, packet) {
    if (err && err.notFound) {
      cb(null, null, client)
    } else {
      cb(err, packet, client)
    }
  })
}

LevelPersistence.prototype.delWill = function (client, cb) {
  var key = WILL + client.id
  var that = this
  this._db.get(key, dbopts, function (err, packet) {
    if (err) {
      return cb(err, packet, client)
    }
    that._db.del(key, function (err) {
      cb(err, packet, client)
    })
  })
}

LevelPersistence.prototype.streamWill = function (brokers) {
  var valueStream = this._db.createValueStream({
    gt: WILL,
    lt: WILL + '\xff',
    valueEncoding: msgpack
  })

  if (!brokers) {
    return valueStream
  }

  return pump(valueStream, through.obj(function (chunk, enc, cb) {
    if (!brokers[chunk.brokerId]) {
      this.push(chunk)
    }
    cb()
  }))
}

LevelPersistence.prototype.getClientList = function (topic) {
  var valueStream = this._db.createValueStream({
    gt: SUBSCRIPTIONS,
    lt: SUBSCRIPTIONS + '\xff',
    valueEncoding: msgpack
  })

  return pump(valueStream, through.obj(function (chunk, enc, cb) {
    if (chunk.topic === topic) {
      this.push(chunk.clientId)
    }
    cb()
  }))
}

LevelPersistence.prototype.destroy = function (cb) {
  this._db.close(cb)
}

module.exports = LevelPersistence
<commit_msg>Replaced batch operations in updateWithBrokerData to normal put operations<commit_after>'use strict'

var Qlobber = require('qlobber').Qlobber
var Packet = require('aedes-packet')
var through = require('through2')
var msgpack = require('msgpack-lite')
var callbackStream = require('callback-stream')
var pump = require('pump')
var EventEmitter = require('events').EventEmitter
var inherits = require('util').inherits
var multistream = require('multistream')

var QlobberOpts = {
  wildcard_one: '+',
  wildcard_some: '#',
  separator: '/'
}
var RETAINED = 'retained:'
var SUBSCRIPTIONS = 'subscriptions:'
var OUTGOING = 'outgoing:'
var OUTGOINGID = 'outgoing-id:'
var INCOMING = 'incoming:'
var WILL = 'will:'
var dbopts = {
  valueEncoding: msgpack
}

function LevelPersistence (db) {
  if (!(this instanceof LevelPersistence)) {
    return new LevelPersistence(db)
  }

  this._db = db
  this._trie = new Qlobber(QlobberOpts)
  this._ready = false

  var trie = this._trie
  var that = this

  pump(this._db.createValueStream({
    gt: SUBSCRIPTIONS,
    lt: SUBSCRIPTIONS + '\xff',
    valueEncoding: msgpack
  }), through.obj(function (chunk, enc, cb) {
    trie.add(chunk.topic, chunk)
    cb()
  }), function (err) {
    if (err) {
      that.emit('error', err)
      return
    }
    that._ready = true
    that.emit('ready')
  })
}

inherits(LevelPersistence, EventEmitter)

LevelPersistence.prototype.storeRetained = function (packet, cb) {
  if (packet.payload.length === 0) {
    this._db.del(RETAINED + packet.topic, cb)
  } else {
    this._db.put(RETAINED + packet.topic, packet, dbopts, cb)
  }
}

LevelPersistence.prototype.createRetainedStreamCombi = function (patterns) {
  var that = this
  var streams = patterns.map(function (p) {
    return that.createRetainedStream(p)
  })
  return multistream.obj(streams)
}

LevelPersistence.prototype.createRetainedStream = function (pattern) {
  var qlobber = new Qlobber(QlobberOpts)
  qlobber.add(pattern, true)

  var res = through.obj(function (packet, encoding, deliver) {
    if (qlobber.match(packet.topic).length) {
      deliver(null, packet)
    } else {
      deliver()
    }
  })

  pump(this._db.createValueStream({
    gt: 'retained:',
    lt: 'retained\xff',
    valueEncoding: msgpack
  }), res)

  return res
}

function withClientId (sub) {
  return {
    topic: sub.topic,
    clientId: this.id,
    qos: sub.qos
  }
}

function toSubKey (sub) {
  return SUBSCRIPTIONS + sub.clientId + ':' + sub.topic
}

function addSubToTrie (sub) {
  var add
  var matched = this.match(sub.topic)
  if (matched.length > 0) {
    add = true
    for (var i = 0; i < matched.length; i++) {
      if (matched[i].clientId === sub.clientId && matched[i].qos === sub.qos) {
        add = false
        break
      } else if (matched[i].qos !== sub.qos) {
        this.remove(matched[i].topic, matched[i])
        if (sub.qos === 0) {
          add = false
        }
      }
    }
  } else if (sub.qos > 0) {
    add = true
  }

  if (add) {
    this.add(sub.topic, sub)
  }

  return sub
}

LevelPersistence.prototype.addSubscriptions = function (client, subs, cb) {
  if (!this._ready) {
    this.once('ready', this.addSubscriptions.bind(this, client, subs, cb))
    return
  }

  subs = subs
    .map(withClientId, client)
    .map(addSubToTrie, this._trie)

  let opArray = []
  subs.forEach(function (sub) {
    let ops = {}
    ops.type = 'put'
    ops.key = toSubKey(sub)
    ops.value = sub
    opArray.push(ops)
  })

  this._db.batch(opArray, dbopts, function (err) {
    cb(err, client)
  })
}

function toSubObj (topic) {
  return {
    clientId: this.id,
    topic: topic
  }
}

function delSubFromTrie (sub) {
  this
    .match(sub.topic)
    .filter(matching, sub)
    .forEach(rmSub, this)

  return sub
}

function matching (sub) {
  return sub.topic === this.topic && sub.clientId === this.clientId
}

function rmSub (sub) {
  this.remove(sub.topic, sub)
}

LevelPersistence.prototype.removeSubscriptions = function (client, subs, cb) {
  subs = subs
    .map(toSubObj, client)
    .map(delSubFromTrie, this._trie)
  let opArray = []
  subs.forEach(function (sub) {
    let ops = {}
    ops.type = 'del'
    ops.key = toSubKey(sub)
    ops.value = sub
    opArray.push(ops)
  })
  this._db.batch(opArray, dbopts, function (err) {
    cb(err, client)
  })
}

function rmClientId (sub) {
  return {
    topic: sub.topic,
    qos: sub.qos
  }
}

LevelPersistence.prototype.subscriptionsByClient = function (client, cb) {
  this._db.createValueStream({
    gt: SUBSCRIPTIONS + client.id,
    lt: SUBSCRIPTIONS + client.id + '\xff',
    valueEncoding: msgpack
  }).pipe(callbackStream({ objectMode: true }, function (err, subs) {
    var resubs = subs.map(rmClientId)
    if (resubs.length === 0) {
      resubs = null
    }
    cb(err, resubs, client)
  }))
}

LevelPersistence.prototype.countOffline = function (cb) {
  var clients = 0
  var subs = 0
  var lastClient = null
  pump(this._db.createValueStream({
    gt: SUBSCRIPTIONS,
    lt: SUBSCRIPTIONS + '\xff',
    valueEncoding: msgpack
  }), through.obj(function (sub, enc, cb) {
    if (lastClient !== sub.clientId) {
      lastClient = sub.clientId
      clients++
    }
    if (sub.qos > 0) {
      subs++
    }
    cb()
  }), function (err) {
    cb(err, subs, clients)
  })
}

LevelPersistence.prototype.subscriptionsByTopic = function (pattern, cb) {
  if (!this._ready) {
    this.once('ready', this.subscriptionsByTopic.bind(this, pattern, cb))
    return this
  }
  cb(null, this._trie.match(pattern))
}

LevelPersistence.prototype.cleanSubscriptions = function (client, cb) {
  var that = this
  this.subscriptionsByClient(client, function (err, subs) {
    if (err || !subs) { return cb(err, client) }

    that.removeSubscriptions(client, subs.map(function (sub) {
      return sub.topic
    }), function (err) {
      cb(err, client)
    })
  })
}

LevelPersistence.prototype.outgoingEnqueue = function (sub, packet, cb) {
  var key = OUTGOING + sub.clientId + ':' + packet.brokerId + ':' + packet.brokerCounter
  this._db.put(key, new Packet(packet), dbopts, cb)
}

LevelPersistence.prototype.outgoingEnqueueCombi = function (subs, packet, cb) {
  if (!subs || subs.length === 0) {
    return cb(null, packet)
  }
  var count = 0
  for (var i = 0; i < subs.length; i++) {
    this.outgoingEnqueue(subs[i], packet, function (err) {
      if (!err) {
        count++
        if (count === subs.length) {
          cb(null, packet)
        }
      } else {
        cb(err)
      }
    })
  }
}

function updateWithBrokerData (that, client, packet, cb) {
  var prekey = OUTGOING + client.id + ':' + packet.brokerId + ':' + packet.brokerCounter
  var postkey = OUTGOINGID + client.id + ':' + packet.messageId

  that._db.get(prekey, dbopts, function (err, decoded) {
    if (err && err.notFound) {
      cb(new Error('no such packet'), client, packet)
      return
    } else if (err) {
      cb(err, client, packet)
      return
    }

    if (decoded.messageId > 0) {
      that._db.del(OUTGOINGID + client.id + ':' + decoded.messageId)
    }

    that._db.put(postkey, packet, dbopts, function (err) {
      if (err) {
        cb(err, client, packet)
      } else {
        that._db.put(prekey, packet, dbopts, function (err) {
          cb(err, client, packet)
        })
      }
    })
  })
}

function augmentWithBrokerData (that, client, packet, cb) {
  var postkey = OUTGOINGID + client.id + ':' + packet.messageId
  that._db.get(postkey, dbopts, function (err, decoded) {
    if (err && err.notFound) {
      return cb(new Error('no such packet'))
    } else if (err) {
      return cb(err)
    }

    packet.brokerId = decoded.brokerId
    packet.brokerCounter = decoded.brokerCounter
    cb(null)
  })
}

LevelPersistence.prototype.outgoingUpdate = function (client, packet, cb) {
  var that = this
  if (packet.brokerId) {
    updateWithBrokerData(this, client, packet, cb)
  } else {
    augmentWithBrokerData(this, client, packet, function (err) {
      if (err) { return cb(err, client, packet) }

      updateWithBrokerData(that, client, packet, cb)
    })
  }
}

LevelPersistence.prototype.outgoingClearMessageId = function (client, packet, cb) {
  var that = this
  var key = OUTGOINGID + client.id + ':' + packet.messageId
  this._db.get(key, dbopts, function (err, packet) {
    if (err && err.notFound) {
      return cb(null)
    } else if (err) {
      return cb(err)
    }

    var prekey = 'outgoing:' + client.id + ':' + packet.brokerId + ':' + packet.brokerCounter
    var batch = that._db.batch()
    batch.del(key)
    batch.del(prekey)
    batch.write(function (err) {
      cb(err, packet)
    })
  })
}

LevelPersistence.prototype.outgoingStream = function (client) {
  var key = OUTGOING + client.id
  return this._db.createValueStream({
    gt: key,
    lt: key + '\xff',
    valueEncoding: msgpack
  })
}

LevelPersistence.prototype.incomingStorePacket = function (client, packet, cb) {
  var key = INCOMING + client.id + ':' + packet.messageId
  var newp = new Packet(packet)
  newp.messageId = packet.messageId
  this._db.put(key, newp, dbopts, cb)
}

LevelPersistence.prototype.incomingGetPacket = function (client, packet, cb) {
  var key = INCOMING + client.id + ':' + packet.messageId
  this._db.get(key, dbopts, function (err, decoded) {
    if (err && err.notFound) {
      cb(new Error('no such packet'), client)
    } else if (err) {
      cb(err, client)
    } else {
      cb(null, decoded, client)
    }
  })
}

LevelPersistence.prototype.incomingDelPacket = function (client, packet, cb) {
  var key = INCOMING + client.id + ':' + packet.messageId
  this._db.del(key, cb)
}

LevelPersistence.prototype.putWill = function (client, packet, cb) {
  var key = WILL + client.id

  packet.brokerId = this.broker.id
  packet.clientId = client.id

  this._db.put(key, packet, dbopts, function (err) {
    cb(err, client)
  })
}

LevelPersistence.prototype.getWill = function (client, cb) {
  var key = WILL + client.id
  this._db.get(key, dbopts, function (err, packet) {
    if (err && err.notFound) {
      cb(null, null, client)
    } else {
      cb(err, packet, client)
    }
  })
}

LevelPersistence.prototype.delWill = function (client, cb) {
  var key = WILL + client.id
  var that = this
  this._db.get(key, dbopts, function (err, packet) {
    if (err) {
      return cb(err, packet, client)
    }
    that._db.del(key, function (err) {
      cb(err, packet, client)
    })
  })
}

LevelPersistence.prototype.streamWill = function (brokers) {
  var valueStream = this._db.createValueStream({
    gt: WILL,
    lt: WILL + '\xff',
    valueEncoding: msgpack
  })

  if (!brokers) {
    return valueStream
  }

  return pump(valueStream, through.obj(function (chunk, enc, cb) {
    if (!brokers[chunk.brokerId]) {
      this.push(chunk)
    }
    cb()
  }))
}

LevelPersistence.prototype.getClientList = function (topic) {
  var valueStream = this._db.createValueStream({
    gt: SUBSCRIPTIONS,
    lt: SUBSCRIPTIONS + '\xff',
    valueEncoding: msgpack
  })

  return pump(valueStream, through.obj(function (chunk, enc, cb) {
    if (chunk.topic === topic) {
      this.push(chunk.clientId)
    }
    cb()
  }))
}

LevelPersistence.prototype.destroy = function (cb) {
  this._db.close(cb)
}

module.exports = LevelPersistence
<|endoftext|>


<commit_before>module("Ember.DeferredMixin");

test("can resolve deferred", function() {
  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function(a) {
    count++;
  });

  Ember.run(function() {
    deferred.resolve();
  });

  equal(count, 1, "was fulfilled");
});

test("can reject deferred", function() {

  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {}, function() {
    count++;
  });

  Ember.run(function() {
    deferred.reject();
  });

  equal(count, 1, "fail callback was called");
});

test("can resolve with then", function() {

  var deferred, count1 = 0 ,count2 = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    count1++;
  }, function() {
    count2++;
  });

  Ember.run(function() {
    deferred.resolve();
  });

  equal(count1, 1, "then were resolved");
  equal(count2, 0, "then was not rejected");
});

test("can reject with then", function() {

  var deferred, count1 = 0 ,count2 = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    count1++;
  }, function() {
    count2++;
  });

  Ember.run(function() {
    deferred.reject();
  });

  equal(count1, 0, "then was not resolved");
  equal(count2, 1, "then were rejected");
});

test("can call resolve multiple times", function() {

  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    count++;
  });

  Ember.run(function() {
    deferred.resolve();
    deferred.resolve();
    deferred.resolve();
  });

  equal(count, 1, "calling resolve multiple times has no effect");
});

test("resolve prevent reject", function() {
  var deferred, resolved = false, rejected = false, progress = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    resolved = true;
  }, function() {
    rejected = true;
  });

  Ember.run(function() {
    deferred.resolve();
  });

  Ember.run(function() {
    deferred.reject();
  });

  equal(resolved, true, "is resolved");
  equal(rejected, false, "is not rejected");
});

test("reject prevent resolve", function() {
  var deferred, resolved = false, rejected = false, progress = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    resolved = true;
  }, function() {
    rejected = true;
  });

  Ember.run(function() {
    deferred.reject();
  });
  Ember.run(function() {
    deferred.resolve();
  });

  equal(resolved, false, "is not resolved");
  equal(rejected, true, "is rejected");
});

test("will call callbacks if they are added after resolution", function() {

  var deferred, count1 = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  Ember.run(function() {
    deferred.resolve('toto');
  });

  Ember.run(function() {
    deferred.then(function(context) {
      if (context === 'toto') {
        count1++;
      }
    });

    deferred.then(function(context) {
      if (context === 'toto') {
        count1++;
      }
    });
  });

  equal(count1, 2, "callbacks called after resolution");
});

test("then is chainable", function() {
  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    eval('error'); // Use eval to pass JSHint
  }).then(null, function() {
    count++;
  });

  Ember.run(function() {
    deferred.resolve();
  });

  equal(count, 1, "chained callback was called");
});
<commit_msg>Add tests to deferred mixin<commit_after>module("Ember.DeferredMixin");

test("can resolve deferred", function() {
  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function(a) {
    count++;
  });

  Ember.run(function() {
    deferred.resolve(deferred);
  });

  equal(count, 1, "was fulfilled");
});

test("can reject deferred", function() {

  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {}, function() {
    count++;
  });

  Ember.run(function() {
    deferred.reject();
  });

  equal(count, 1, "fail callback was called");
});

test("can resolve with then", function() {

  var deferred, count1 = 0 ,count2 = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    count1++;
  }, function() {
    count2++;
  });

  Ember.run(function() {
    deferred.resolve(deferred);
  });

  equal(count1, 1, "then were resolved");
  equal(count2, 0, "then was not rejected");
});

test("can reject with then", function() {

  var deferred, count1 = 0 ,count2 = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    count1++;
  }, function() {
    count2++;
  });

  Ember.run(function() {
    deferred.reject();
  });

  equal(count1, 0, "then was not resolved");
  equal(count2, 1, "then were rejected");
});

test("can call resolve multiple times", function() {

  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    count++;
  });

  Ember.run(function() {
    deferred.resolve(deferred);
    deferred.resolve(deferred);
    deferred.resolve(deferred);
  });

  equal(count, 1, "calling resolve multiple times has no effect");
});

test("resolve prevent reject", function() {
  var deferred, resolved = false, rejected = false, progress = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    resolved = true;
  }, function() {
    rejected = true;
  });

  Ember.run(function() {
    deferred.resolve(deferred);
  });

  Ember.run(function() {
    deferred.reject();
  });

  equal(resolved, true, "is resolved");
  equal(rejected, false, "is not rejected");
});

test("reject prevent resolve", function() {
  var deferred, resolved = false, rejected = false, progress = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    resolved = true;
  }, function() {
    rejected = true;
  });

  Ember.run(function() {
    deferred.reject();
  });
  Ember.run(function() {
    deferred.resolve(deferred);
  });

  equal(resolved, false, "is not resolved");
  equal(rejected, true, "is rejected");
});

test("will call callbacks if they are added after resolution", function() {

  var deferred, count1 = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  Ember.run(function() {
    deferred.resolve('toto');
  });

  Ember.run(function() {
    deferred.then(function(context) {
      if (context === 'toto') {
        count1++;
      }
    });

    deferred.then(function(context) {
      if (context === 'toto') {
        count1++;
      }
    });
  });

  equal(count1, 2, "callbacks called after resolution");
});

test("then is chainable", function() {
  var deferred, count = 0;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function() {
    eval('error'); // Use eval to pass JSHint
  }).then(null, function() {
    count++;
  });

  Ember.run(function() {
    deferred.resolve(deferred);
  });

  equal(count, 1, "chained callback was called");
});

test("can self fulfill", function() {
  expect(1);
  var deferred;

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function(value) {
    equal(value, deferred, "successfully resolved to itself");
  });

  Ember.run(function() {
    deferred.resolve(deferred);
  });
});

test("can fulfill to a custom value", function() {
  expect(1);
  var deferred, obj = {};

  Ember.run(function() {
    deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  deferred.then(function(value) {
    equal(value, obj, "successfully resolved to given value");
  });

  Ember.run(function() {
    deferred.resolve(obj);
  });
});

test("can chain self fulfilling objects", function() {
  expect(2);
  var firstDeferred, secondDeferred;

  Ember.run(function() {
    firstDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
    secondDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  firstDeferred.then(function(value) {
    equal(value, firstDeferred, "successfully resolved to the first deferred");
    return secondDeferred;
  })
  .then(function(value) {
    equal(value, secondDeferred, "successfully resolved to the second deferred");
  });

  Ember.run(function() {
    firstDeferred.resolve(firstDeferred);
    secondDeferred.resolve(secondDeferred);
  });
});

test("can do multi level assimilation", function() {
  expect(1);
  var firstDeferred, secondDeferred, firstDeferredResolved = false;

  Ember.run(function() {
    firstDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
    secondDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);
  });

  firstDeferred.then(function() {
    firstDeferredResolved = true;
  });

  secondDeferred.then(function() {
    ok(firstDeferredResolved, "first deferred already resolved");
  });

  Ember.run(function() {
    secondDeferred.resolve(firstDeferred);
  });

  Ember.run(function() {
    firstDeferred.resolve(firstDeferred);
  });
});

<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import warning from 'warning';

import {
  ListRow,
  Button,
  Icon,
  Text,
  TextLabel,
} from '@ichef/gypcrete';

import Popover from '@ichef/gypcrete/lib/Popover';
import prefixClass from '@ichef/gypcrete/lib/utils/prefixClass';
import icBEM from '@ichef/gypcrete/lib/utils/icBEM';

import SelectList from './SelectList';

import parseSelectOptions from './utils/parseSelectOptions';
import formRow, { rowPropTypes } from './mixins/formRow';
import './styles/SelectRow.scss';

export const COMPONENT_NAME = prefixClass('form-select');
const ROOT_BEM = icBEM(COMPONENT_NAME);
export const BEM = {
  root: ROOT_BEM,
  popover: ROOT_BEM.element('popover'),
  placeholder: ROOT_BEM.element('placeholder'),
};

const CLOSABLE_CONFIG = {
  onEscape: true,
  onClickOutside: true,
  onClickInside: false,
};

/**
 * Generate a value-label map from all `<SelectOption>`s.
 *
 * @param {array} fromOptions
 * @return {Map}
 */
function getValueToLabelAvatarMap(fromChildren = []) {
  const resultMap = new Map();
  const options = parseSelectOptions(fromChildren);

  options.forEach(
    (option) => {
      const { label, avatar } = option;
      resultMap.set(option.value, {
        label,
        avatar,
      });
    }
  );
  return resultMap;
}

class SelectRow extends PureComponent {
    static propTypes = {
      label: PropTypes.node.isRequired,
      asideAllLabel: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.bool, // can pass false to disable 'All' label
      ]),
      asideNoneLabel: PropTypes.string,
      asideSeparator: PropTypes.string,
      disabled: PropTypes.bool,
      renderRowValueLabel: PropTypes.func,
      // <SelectList> props
      multiple: SelectList.propTypes.multiple,
      value: SelectList.propTypes.value,
      defaultValue: SelectList.propTypes.defaultValue,
      onChange: PropTypes.func,
      // from formRow()
      ineditable: PropTypes.bool,
      rowProps: rowPropTypes,
    };

    static defaultProps = {
      asideAllLabel: 'All',
      asideNoneLabel: '(Unset)',
      asideSeparator: ', ',
      disabled: false,
      renderRowValueLabel: undefined,
      // <SelectList> props
      multiple: SelectList.defaultProps.multiple,
      value: SelectList.defaultProps.value,
      defaultValue: SelectList.defaultProps.defaultValue,
      onChange: () => {},
      // from formRow()
      ineditable: false,
      rowProps: {},
    };

    state = {
      isPopoverOpen: false,
      valueLabelMap: getValueToLabelAvatarMap(this.props.children),
      cachedValue: this.getInitialValue(),
    };

    // eslint-disable-next-line react/no-deprecated
    componentWillReceiveProps(nextProps) {
      this.setState({
        valueLabelMap: getValueToLabelAvatarMap(nextProps.children),
      });

      warning(
        this.getIsControlled(this.props) === this.getIsControlled(nextProps),
        '<SelectRow> should not switch from controlled to uncontrolled (or vice versa).'
      );

      if (this.getIsControlled(nextProps)) {
        this.setState({ cachedValue: nextProps.value });
      } else if (this.props.multiple !== nextProps.multiple) {
        warning(false, '<SelectRow>: you should not change `multiple` prop while it is uncontrolled. Its value will be reset now.');
        this.setState({ cachedValue: (nextProps.multiple) ? [] : null });
      }
    }

    getInitialValue() {
      const { value, defaultValue, multiple } = this.props;

      if (value !== undefined) {
        return value;
      }

      if (multiple && defaultValue === undefined) {
        return [];
      }

      return defaultValue;
    }

    getIsControlled(fromProps = this.props) {
      return fromProps.value !== undefined;
    }

    getCacheValueArray = () => {
      const { multiple } = this.props;
      const { cachedValue } = this.state;
      return (multiple) ? cachedValue : [cachedValue].filter(val => val !== undefined);
    }

    handleButtonClick = () => {
      this.setState({ isPopoverOpen: true });
    }

    handlePopoverClose = () => {
      this.setState({ isPopoverOpen: false });
    }

    handleSelectChange = (nextValue) => {
      if (!this.getIsControlled()) {
        this.setState({ cachedValue: nextValue });
      }
      this.props.onChange(nextValue);

      if (!this.props.multiple) {
        this.handlePopoverClose();
      }
    }

    renderPopover(selectListProps) {
      return (
        <Popover
          anchor={this.anchorNode}
          className={BEM.popover.toString()}
          closable={CLOSABLE_CONFIG}
          onClose={this.handlePopoverClose}
        >
          <SelectList
            value={this.state.cachedValue}
            onChange={this.handleSelectChange}
            {...selectListProps}
          />
        </Popover>
      );
    }

    renderRowValueLabel() {
      const {
        multiple,
        asideAllLabel,
        asideNoneLabel,
        asideSeparator,
        renderRowValueLabel,
      } = this.props;
      const { cachedValue, valueLabelMap } = this.state;

      if (typeof renderRowValueLabel === 'function') {
        return renderRowValueLabel({ values: cachedValue, valueLabelMap });
      }

      const isSingleEmptyValue = cachedValue === undefined || cachedValue === '';
      const isMultipleEmptyValue = multiple && cachedValue.length === 0;

      if (isSingleEmptyValue || isMultipleEmptyValue) {
        return {asideNoneLabel};
      }

      if (multiple) {
        // Can turn off 'All' display by passing `false`.
        if (asideAllLabel && cachedValue.length === valueLabelMap.size) {
          return asideAllLabel;
        }
      }

      return this.getCacheValueArray()
        .map((value) => {
          const valueMap = valueLabelMap.get(value) || {};
          return valueMap.label;
        })
        .filter(label => Boolean(label))
        .join(asideSeparator);
    }

    renderAvatar() {
      const { valueLabelMap } = this.state;
      return this.getCacheValueArray()
        .map((value) => {
          const valueMap = valueLabelMap.get(value) || {};
          return (
            <React.Fragment key={value}>
              {valueMap.avatar}
            </React.Fragment>
          );
        });
    }

    render() {
      const {
        label,
        asideAllLabel,
        asideNoneLabel,
        asideSeparator,
        disabled,
        // <ListRow> props (intercepted from it)
        // multiple,
        value,
        defaultValue,
        onChange,
        // from formRow()
        ineditable,
        rowProps,
        // React props
        className,
        ...selectListProps
      } = this.props;
      const { isPopoverOpen } = this.state;

      const wrapperClassName = classNames(
        COMPONENT_NAME,
        className,
      );

      const Content = ineditable ? TextLabel : Button;
      const contentProps = ineditable ? {} : {
        onClick: this.handleButtonClick,
      };

      return (
        <ListRow className={wrapperClassName} {...rowProps}>
          {this.renderAvatar()}
          <Content minified={false} disabled={disabled} {...contentProps}>
            <Text
              verticalOrder="reverse"
              bold={!ineditable}
              basic={this.renderRowValueLabel()}
              aside={label}
            />

             { this.anchorNode = ref; }}>
              <Icon type="dropdown" />

            {isPopoverOpen && this.renderPopover(selectListProps)}
          </Content>
        </ListRow>
      );
    }
}

export { SelectRow as PureSelectRow };
export default formRow()(SelectRow);
<commit_msg>fix: wont pass renderRowValueLabel<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import warning from 'warning';

import {
  ListRow,
  Button,
  Icon,
  Text,
  TextLabel,
} from '@ichef/gypcrete';

import Popover from '@ichef/gypcrete/lib/Popover';
import prefixClass from '@ichef/gypcrete/lib/utils/prefixClass';
import icBEM from '@ichef/gypcrete/lib/utils/icBEM';

import SelectList from './SelectList';

import parseSelectOptions from './utils/parseSelectOptions';
import formRow, { rowPropTypes } from './mixins/formRow';
import './styles/SelectRow.scss';

export const COMPONENT_NAME = prefixClass('form-select');
const ROOT_BEM = icBEM(COMPONENT_NAME);
export const BEM = {
  root: ROOT_BEM,
  popover: ROOT_BEM.element('popover'),
  placeholder: ROOT_BEM.element('placeholder'),
};

const CLOSABLE_CONFIG = {
  onEscape: true,
  onClickOutside: true,
  onClickInside: false,
};

/**
 * Generate a value-label map from all `<SelectOption>`s.
 *
 * @param {array} fromOptions
 * @return {Map}
 */
function getValueToLabelAvatarMap(fromChildren = []) {
  const resultMap = new Map();
  const options = parseSelectOptions(fromChildren);

  options.forEach(
    (option) => {
      const { label, avatar } = option;
      resultMap.set(option.value, {
        label,
        avatar,
      });
    }
  );
  return resultMap;
}

class SelectRow extends PureComponent {
    static propTypes = {
      label: PropTypes.node.isRequired,
      asideAllLabel: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.bool, // can pass false to disable 'All' label
      ]),
      asideNoneLabel: PropTypes.string,
      asideSeparator: PropTypes.string,
      disabled: PropTypes.bool,
      renderRowValueLabel: PropTypes.func,
      // <SelectList> props
      multiple: SelectList.propTypes.multiple,
      value: SelectList.propTypes.value,
      defaultValue: SelectList.propTypes.defaultValue,
      onChange: PropTypes.func,
      // from formRow()
      ineditable: PropTypes.bool,
      rowProps: rowPropTypes,
    };

    static defaultProps = {
      asideAllLabel: 'All',
      asideNoneLabel: '(Unset)',
      asideSeparator: ', ',
      disabled: false,
      renderRowValueLabel: undefined,
      // <SelectList> props
      multiple: SelectList.defaultProps.multiple,
      value: SelectList.defaultProps.value,
      defaultValue: SelectList.defaultProps.defaultValue,
      onChange: () => {},
      // from formRow()
      ineditable: false,
      rowProps: {},
    };

    state = {
      isPopoverOpen: false,
      valueLabelMap: getValueToLabelAvatarMap(this.props.children),
      cachedValue: this.getInitialValue(),
    };

    // eslint-disable-next-line react/no-deprecated
    componentWillReceiveProps(nextProps) {
      this.setState({
        valueLabelMap: getValueToLabelAvatarMap(nextProps.children),
      });

      warning(
        this.getIsControlled(this.props) === this.getIsControlled(nextProps),
        '<SelectRow> should not switch from controlled to uncontrolled (or vice versa).'
      );

      if (this.getIsControlled(nextProps)) {
        this.setState({ cachedValue: nextProps.value });
      } else if (this.props.multiple !== nextProps.multiple) {
        warning(false, '<SelectRow>: you should not change `multiple` prop while it is uncontrolled. Its value will be reset now.');
        this.setState({ cachedValue: (nextProps.multiple) ? [] : null });
      }
    }

    getInitialValue() {
      const { value, defaultValue, multiple } = this.props;

      if (value !== undefined) {
        return value;
      }

      if (multiple && defaultValue === undefined) {
        return [];
      }

      return defaultValue;
    }

    getIsControlled(fromProps = this.props) {
      return fromProps.value !== undefined;
    }

    getCacheValueArray = () => {
      const { multiple } = this.props;
      const { cachedValue } = this.state;
      return (multiple) ? cachedValue : [cachedValue].filter(val => val !== undefined);
    }

    handleButtonClick = () => {
      this.setState({ isPopoverOpen: true });
    }

    handlePopoverClose = () => {
      this.setState({ isPopoverOpen: false });
    }

    handleSelectChange = (nextValue) => {
      if (!this.getIsControlled()) {
        this.setState({ cachedValue: nextValue });
      }
      this.props.onChange(nextValue);

      if (!this.props.multiple) {
        this.handlePopoverClose();
      }
    }

    renderPopover(selectListProps) {
      return (
        <Popover
          anchor={this.anchorNode}
          className={BEM.popover.toString()}
          closable={CLOSABLE_CONFIG}
          onClose={this.handlePopoverClose}
        >
          <SelectList
            value={this.state.cachedValue}
            onChange={this.handleSelectChange}
            {...selectListProps}
          />
        </Popover>
      );
    }

    renderRowValueLabel() {
      const {
        multiple,
        asideAllLabel,
        asideNoneLabel,
        asideSeparator,
        renderRowValueLabel,
      } = this.props;
      const { cachedValue, valueLabelMap } = this.state;

      if (typeof renderRowValueLabel === 'function') {
        return renderRowValueLabel({ values: cachedValue, valueLabelMap });
      }

      const isSingleEmptyValue = cachedValue === undefined || cachedValue === '';
      const isMultipleEmptyValue = multiple && cachedValue.length === 0;

      if (isSingleEmptyValue || isMultipleEmptyValue) {
        return {asideNoneLabel};
      }

      if (multiple) {
        // Can turn off 'All' display by passing `false`.
        if (asideAllLabel && cachedValue.length === valueLabelMap.size) {
          return asideAllLabel;
        }
      }

      return this.getCacheValueArray()
        .map((value) => {
          const valueMap = valueLabelMap.get(value) || {};
          return valueMap.label;
        })
        .filter(label => Boolean(label))
        .join(asideSeparator);
    }

    renderAvatar() {
      const { valueLabelMap } = this.state;
      return this.getCacheValueArray()
        .map((value) => {
          const valueMap = valueLabelMap.get(value) || {};
          return (
            <React.Fragment key={value}>
              {valueMap.avatar}
            </React.Fragment>
          );
        });
    }

    render() {
      const {
        label,
        asideAllLabel,
        asideNoneLabel,
        asideSeparator,
        disabled,
        renderRowValueLabel,
        // <ListRow> props (intercepted from it)
        // multiple,
        value,
        defaultValue,
        onChange,
        // from formRow()
        ineditable,
        rowProps,
        // React props
        className,
        ...selectListProps
      } = this.props;
      const { isPopoverOpen } = this.state;

      const wrapperClassName = classNames(
        COMPONENT_NAME,
        className,
      );

      const Content = ineditable ? TextLabel : Button;
      const contentProps = ineditable ? {} : {
        onClick: this.handleButtonClick,
      };

      return (
        <ListRow className={wrapperClassName} {...rowProps}>
          {this.renderAvatar()}
          <Content minified={false} disabled={disabled} {...contentProps}>
            <Text
              verticalOrder="reverse"
              bold={!ineditable}
              basic={this.renderRowValueLabel()}
              aside={label}
            />

             { this.anchorNode = ref; }}>
              <Icon type="dropdown" />

            {isPopoverOpen && this.renderPopover(selectListProps)}
          </Content>
        </ListRow>
      );
    }
}

export { SelectRow as PureSelectRow };
export default formRow()(SelectRow);
<|endoftext|>


<commit_before>// Users

Meteor.publish('users', function() {
  return Meteor.users.find({}, {fields: {emails: false}});
});
// Posts

Posts = new Meteor.Collection('posts');

Meteor.publish('posts', function() {
  return Posts.find({}, {sort: {score: -1}});
});

// FIXME -- check all docs, not just the first one.
Meteor.startup(function(){
  Posts.allow({
      insert: function(userId, doc){
        console.log(userId);
        if(userId){
          doc.userId = userId;
          return true;
        }
        return false;
      }
    , update: function(userId, docs, fields, modifier){
      console.log(docs);
        console.log("Document's user: "+docs[0].user_id+" | Current user: "+userId);
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return false;
      }
    , remove: function(userId, docs){
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return false; }
  });
});

// Comments

Comments = new Meteor.Collection('comments');

Meteor.publish('comments', function() {
  return Comments.find();
});

Meteor.startup(function(){
  Comments.allow({
      insert: function(userId, doc){
        console.log(userId);
        if(userId){
          return true;
        }
        return false;
      }
    , update: function(userId, docs, fields, modifier){
        console.log("Document's user: "+docs[0].user_id+" | Current user: "+userId);
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return false;
      }
    , remove: function(userId, docs){
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return false;
      }
  });
});

// MyVotes

MyVotes = new Meteor.Collection('myvotes');

Meteor.publish('myvotes', function() {
  return MyVotes.find();
});

Meteor.startup(function(){
  MyVotes.allow({
      insert: function(){ return false; }
    , update: function(){ return false; }
    , remove: function(){ return false; }
  });
});

// Settings

Settings = new Meteor.Collection('settings');

Meteor.publish('settings', function() {
  return Settings.find();
});

Meteor.startup(function(){
  Settings.allow({
      insert: function(){ return true; }
    , update: function(){ return true; }
    , remove: function(){ return true; }
  });
});<commit_msg>temporarily enabling unsecured post removal<commit_after>// Users

Meteor.publish('users', function() {
  return Meteor.users.find({}, {fields: {emails: false}});
});
// Posts

Posts = new Meteor.Collection('posts');

Meteor.publish('posts', function() {
  return Posts.find({}, {sort: {score: -1}});
});

// FIXME -- check all docs, not just the first one.
Meteor.startup(function(){
  Posts.allow({
      insert: function(userId, doc){
        console.log(userId);
        if(userId){
          doc.userId = userId;
          return true;
        }
        return false;
      }
    , update: function(userId, docs, fields, modifier){
      console.log(docs);
        console.log("Document's user: "+docs[0].user_id+" | Current user: "+userId);
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return false;
      }
    , remove: function(userId, docs){
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return true; }
  });
});

// Comments

Comments = new Meteor.Collection('comments');

Meteor.publish('comments', function() {
  return Comments.find();
});

Meteor.startup(function(){
  Comments.allow({
      insert: function(userId, doc){
        console.log(userId);
        if(userId){
          return true;
        }
        return false;
      }
    , update: function(userId, docs, fields, modifier){
        console.log("Document's user: "+docs[0].user_id+" | Current user: "+userId);
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return false;
      }
    , remove: function(userId, docs){
        if(docs[0].user_id && docs[0].user_id==userId){
          return true;
        }
        return false;
      }
  });
});

// MyVotes

MyVotes = new Meteor.Collection('myvotes');

Meteor.publish('myvotes', function() {
  return MyVotes.find();
});

Meteor.startup(function(){
  MyVotes.allow({
      insert: function(){ return false; }
    , update: function(){ return false; }
    , remove: function(){ return false; }
  });
});

// Settings

Settings = new Meteor.Collection('settings');

Meteor.publish('settings', function() {
  return Settings.find();
});

Meteor.startup(function(){
  Settings.allow({
      insert: function(){ return true; }
    , update: function(){ return true; }
    , remove: function(){ return true; }
  });
});<|endoftext|>


<commit_before>'use strict';

var RESULT_SUCCESS = "SUCCESS";
var RESULT_ERROR = "ERROR";
var ROLE_USER = "user";
var ROLE_TECH = "tech";
var ROLE_ADMIN = "admin";

/**
 *  Provides user modules rights and actions from user role
 *  returns a PROMISE with the result
 */

exports.getUserModules = function (role) {

  function getActionsOnIncidences (role) {
    if (role === ROLE_USER){
      return ['find', 'list', 'create'];
    }
      else if (role === ROLE_TECH){
      return ['create', 'find', 'list'];
    }
    else if (role === ROLE_ADMIN){
      return ['find', 'list', 'report'];
    }
  }

  function getActionsOnInventory (role) {
    if (role === ROLE_ADMIN){
      return [];
    }
    else if (role === ROLE_TECH){
      return ['create', 'list'];
    }
  }

  function getActionsOnAccounts (role) {
    if (role === ROLE_ADMIN){
      return ['create', 'import', 'list'];
    }
  }

  function getActionsOnSchools (role) {
    if (role === ROLE_ADMIN){
      return ['create', 'find', 'list'];
    }
  }

  function getModules (role) {
    if(role === ROLE_USER)
      return ['Incidences'];
    else if(role === ROLE_TECH)
      return ['Incidences', 'Inventory'];
    else if(role === ROLE_ADMIN)
      return ['Incidences', 'Schools', 'Accounts'];
  }

  if(role != null){
    var userModules = [];
    var actions = [];
    var modules = getModules(role);
    for (var i=0; i<modules.length; i++){
      if (modules[i] == 'Home'){
        actions = getActionsOnHome(role);
        userModules.push({module: 'Home', actions: actions});
      }
      else if (modules[i] == 'Incidences'){
        actions = getActionsOnIncidences(role);
        userModules.push({module: 'Incidences', actions: actions});
      }
      else if(modules[i] == 'Inventory'){
        actions = getActionsOnInventory(role);
        userModules.push({module: 'Inventory', actions: actions});
      }
      else if (modules[i] == 'Schools'){
        actions = getActionsOnSchools(role);
        userModules.push({module: 'Schools', actions: actions});
      }
      else if (modules[i] == 'Accounts'){
        actions = getActionsOnAccounts(role);
        userModules.push({module: 'Accounts', actions: actions});
      }
    }
    return {status: RESULT_SUCCESS, modules: userModules};
  }
  else return {status: RESULT_ERROR, modules: null};
}
<commit_msg>no import from csv on accounts menu<commit_after>'use strict';

var RESULT_SUCCESS = "SUCCESS";
var RESULT_ERROR = "ERROR";
var ROLE_USER = "user";
var ROLE_TECH = "tech";
var ROLE_ADMIN = "admin";

/**
 *  Provides user modules rights and actions from user role
 *  returns a PROMISE with the result
 */

exports.getUserModules = function (role) {

  function getActionsOnIncidences (role) {
    if (role === ROLE_USER){
      return ['find', 'list', 'create'];
    }
      else if (role === ROLE_TECH){
      return ['create', 'find', 'list'];
    }
    else if (role === ROLE_ADMIN){
      return ['find', 'list', 'report'];
    }
  }

  function getActionsOnInventory (role) {
    if (role === ROLE_ADMIN){
      return [];
    }
    else if (role === ROLE_TECH){
      return ['create', 'list'];
    }
  }

  function getActionsOnAccounts (role) {
    if (role === ROLE_ADMIN){
      return ['create', 'list'];
    }
  }

  function getActionsOnSchools (role) {
    if (role === ROLE_ADMIN){
      return ['create', 'find', 'list'];
    }
  }

  function getModules (role) {
    if(role === ROLE_USER)
      return ['Incidences'];
    else if(role === ROLE_TECH)
      return ['Incidences', 'Inventory'];
    else if(role === ROLE_ADMIN)
      return ['Incidences', 'Schools', 'Accounts'];
  }

  if(role != null){
    var userModules = [];
    var actions = [];
    var modules = getModules(role);
    for (var i=0; i<modules.length; i++){
      if (modules[i] == 'Home'){
        actions = getActionsOnHome(role);
        userModules.push({module: 'Home', actions: actions});
      }
      else if (modules[i] == 'Incidences'){
        actions = getActionsOnIncidences(role);
        userModules.push({module: 'Incidences', actions: actions});
      }
      else if(modules[i] == 'Inventory'){
        actions = getActionsOnInventory(role);
        userModules.push({module: 'Inventory', actions: actions});
      }
      else if (modules[i] == 'Schools'){
        actions = getActionsOnSchools(role);
        userModules.push({module: 'Schools', actions: actions});
      }
      else if (modules[i] == 'Accounts'){
        actions = getActionsOnAccounts(role);
        userModules.push({module: 'Accounts', actions: actions});
      }
    }
    return {status: RESULT_SUCCESS, modules: userModules};
  }
  else return {status: RESULT_ERROR, modules: null};
}
<|endoftext|>


<commit_before>'use strict';

/**
  * Module depedencies.
  */

var mongoose = require('mongoose'),
  Project = mongoose.model('Project');

exports.all = function (req, res) {
	Project.find().exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});
};

exports.show = function (req, res) {
	var project_id = req.params.project_id;
	console.log('project_id ' + project_id);
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	}); //MONGODB

};

exports.edit = function (req, res) {
	var project_id = req.params.project_id;
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result, 'Successfully edited phase');
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});

};

exports.addProject = function (req, res) {
    var project = new Project();
    project.name = req.body.name;
    if (req.body.startDate) project.startDate = req.body.startDate;
    project.endDate = req.body.endDate;
    project.phases = [];
    project.admin = req.body.user;
    project.members = [];
    project.messages = [];
    project.save();
    return res.json(201);
};

exports.remove = function (req, res) {
	Project
	  .remove()
	  .exec(function(err) {
	  	if (err) return res.status(400).send(err);
	  	else return res.status(200).send('Test database cleared.');
	  });
};
<commit_msg>Working on delete project<commit_after>'use strict';

/**
  * Module depedencies.
  */

var mongoose = require('mongoose'),
  Project = mongoose.model('Project');

exports.all = function (req, res) {
	Project.find().exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});
};

exports.show = function (req, res) {
	var project_id = req.params.project_id;
	console.log('project_id ' + project_id);
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	}); //MONGODB

};

exports.edit = function (req, res) {
	var project_id = req.params.project_id;
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result, 'Successfully edited phase');
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});

};

exports.addProject = function (req, res) {
    var project = new Project();
    project.name = req.body.name;
    if (req.body.startDate) project.startDate = req.body.startDate;
    project.endDate = req.body.endDate;
    project.phases = [];
    project.admin = req.body.user;
    project.members = [];
    project.messages = [];
    project.save();
    return res.json(201);
};

exports.remove = function (req, res) {
//var project = Project.findOne({'id': req.params.project_id});
//var admin = project.admin
//if rec.user.id === admin
// else res.json('You do not have permission";
	Project
	  .remove()
	  .exec(function(err) {
	  	if (err) return res.status(400).send(err);
	  	else return res.status(200).send('Test database cleared.');
	  });
};
<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

// MODULES //

var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/random/base/randu' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var EPS = require( '@stdlib/constants/math/float64-eps' );
var pkg = require( './../package.json' ).name;
var uniform = require( './../lib' );

// MAIN //

bench( pkg, function benchmark( assert ) {
	var a;
	var b;
	var z;
	var i;

	assert.tic();
	for ( i = 0; i < assert.iterations; i++ ) {
		a = randu() * 100.0;
		b = ( randu()*100.0 ) + a + EPS;
		z = uniform( a, b );
		if ( isnan( z ) ) {
			assert.fail( 'should not return NaN' );
		}
	}
	assert.toc();
	if ( isnan( z ) ) {
		assert.fail( 'should not return NaN' );
	}
	assert.pass( 'benchmark finished' );
	assert.end();
});

bench( pkg+':factory', function benchmark( assert ) {
	var rand;
	var a;
	var b;
	var z;
	var i;

	a = 0.0;
	b = 10.0;
	rand = uniform.factory( a, b );

	assert.tic();
	for ( i = 0; i < assert.iterations; i++ ) {
		z = rand();
		if ( isnan( z ) ) {
			assert.fail( 'should not return NaN' );
		}
	}
	assert.toc();
	if ( isnan( z ) ) {
		assert.fail( 'should not return NaN' );
	}
	assert.pass( 'benchmark finished' );
	assert.end();
});
<commit_msg>Update benchmarks<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

// MODULES //

var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/random/base/randu' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var EPS = require( '@stdlib/constants/math/float64-eps' );
var pkg = require( './../package.json' ).name;
var uniform = require( './../lib' );

// MAIN //

bench( pkg, function benchmark( assert ) {
	var a;
	var b;
	var z;
	var i;

	assert.tic();
	for ( i = 0; i < assert.iterations; i++ ) {
		a = randu() * 100.0;
		b = ( randu()*100.0 ) + a + EPS;
		z = uniform( a, b );
		if ( isnan( z ) ) {
			assert.fail( 'should not return NaN' );
		}
	}
	assert.toc();
	if ( isnan( z ) ) {
		assert.fail( 'should not return NaN' );
	}
	assert.pass( 'benchmark finished' );
	assert.end();
});

bench( pkg+'::factory', function benchmark( assert ) {
	var rand;
	var a;
	var b;
	var z;
	var i;

	a = 0.0;
	b = 10.0;
	rand = uniform.factory( a, b );

	assert.tic();
	for ( i = 0; i < assert.iterations; i++ ) {
		z = rand();
		if ( isnan( z ) ) {
			assert.fail( 'should not return NaN' );
		}
	}
	assert.toc();
	if ( isnan( z ) ) {
		assert.fail( 'should not return NaN' );
	}
	assert.pass( 'benchmark finished' );
	assert.end();
});

bench( pkg+'::factory,arguments', function benchmark( assert ) {
	var rand;
	var a;
	var b;
	var z;
	var i;

	a = 0.0;
	b = 10.0;
	rand = uniform.factory();

	assert.tic();
	for ( i = 0; i < assert.iterations; i++ ) {
		z = rand( a, b );
		if ( isnan( z ) ) {
			assert.fail( 'should not return NaN' );
		}
	}
	assert.toc();
	if ( isnan( z ) ) {
		assert.fail( 'should not return NaN' );
	}
	assert.pass( 'benchmark finished' );
	assert.end();
});
<|endoftext|>


<commit_before>var sockjs = require('sockjs'),
	nodehun = require('nodehun');
var arrDictionaries = {};

// Add en_US
arrDictionaries["1033"] = new nodehun.Dictionary(__dirname + './../Dictionaries/en_US/en_US.aff',
	__dirname + './../Dictionaries/en_US/en_US.dic');
// Add ru_RU
arrDictionaries["1049"] = new nodehun.Dictionary(__dirname + './../Dictionaries/ru_RU/ru_RU.aff',
	__dirname + './../Dictionaries/ru_RU/ru_RU.dic');
// Add de_DE_frami
arrDictionaries["1031"] = new nodehun.Dictionary(__dirname + './../Dictionaries/de_DE_frami/de_DE_frami.aff',
	__dirname + './../Dictionaries/de_DE_frami/de_DE_frami.dic');

var logger = require('./../../Common/sources/logger');

exports.install = function (server, callbackFunction) {
	'use strict';
	var sockjs_opts = {sockjs_url:"http://cdn.sockjs.org/sockjs-0.3.min.js"},
		sockjs_echo = sockjs.createServer(sockjs_opts),
		dataHandler;

	sockjs_echo.on('connection', function (conn) {
		if (null == conn) {
			logger.error ("null == conn");
			return;
		}
		conn.on('data', function (message) {
			try {
				var data = JSON.parse(message);
				dataHandler[data.type](conn, data);
			} catch (e) {
				logger.error("error receiving response:" + e);
			}

		});
		conn.on('error', function () {
			logger.error("On error");
		});
		conn.on('close', function () {
			logger.info("Connection closed or timed out");
		});
	});

	function sendData(conn, data) {
		conn.write(JSON.stringify(data));
	}

	dataHandler = (function () {
		function spellCheck(conn, data) {
			function checkEnd() {
				if (0 === data.usrWordsLength) {
					//data.end = new Date();
					//console.log("time - " + (data.end.getTime() - data.start.getTime()));
					sendData(conn, { type:"spellCheck", spellCheckData:JSON.stringify(data) });
				}
			}
			function spellSuggest(index, word, lang) {
				var oDictionary = arrDictionaries[lang];
				if (undefined === oDictionary) {
					data.usrCorrect[index] = false;
					--data.usrWordsLength;
					checkEnd();
				}

				if ("spell" === data.type) {
					oDictionary.spellSuggest(word, function (a, b) {
						data.usrCorrect[index] = a;
						--data.usrWordsLength;
						checkEnd();
					});
				} else if ("suggest" === data.type) {
					oDictionary.spellSuggestions(word, function (a, b) {
						data.usrSuggest[index] = b;
						--data.usrWordsLength;
						checkEnd();
					});
				}
			}

			data = JSON.parse(data.spellCheckData);
			// Ответ
			data.usrCorrect = [];
			data.usrSuggest = [];
			data.usrWordsLength = data.usrWords.length;

			//data.start = new Date();
			for (var i = 0, length = data.usrWords.length; i < length; ++i) {
				spellSuggest(i, data.usrWords[i], data.usrLang[i]);
			}
		}

		return {
			spellCheck:spellCheck
		};
	}());

	sockjs_echo.installHandlers(server, {prefix:'/doc/[0-9-.a-zA-Z_=]*/c', log:function (severity, message) {
		//TODO: handle severity
		logger.info(message);
	}});

	callbackFunction();
};<commit_msg>add es_ES language<commit_after>var sockjs = require('sockjs'),
	nodehun = require('nodehun');
var arrDictionaries = {};

// Add en_US
arrDictionaries["1033"] = new nodehun.Dictionary(__dirname + './../Dictionaries/en_US/en_US.aff',
	__dirname + './../Dictionaries/en_US/en_US.dic');
// Add ru_RU
arrDictionaries["1049"] = new nodehun.Dictionary(__dirname + './../Dictionaries/ru_RU/ru_RU.aff',
	__dirname + './../Dictionaries/ru_RU/ru_RU.dic');
// Add de_DE_frami
arrDictionaries["1031"] = new nodehun.Dictionary(__dirname + './../Dictionaries/de_DE_frami/de_DE_frami.aff',
	__dirname + './../Dictionaries/de_DE_frami/de_DE_frami.dic');
// Add es_ES
arrDictionaries["3082"] = new nodehun.Dictionary(__dirname + './../Dictionaries/es_ES/es_ES.aff',
	__dirname + './../Dictionaries/es_ES/es_ES.dic');

var logger = require('./../../Common/sources/logger');

exports.install = function (server, callbackFunction) {
	'use strict';
	var sockjs_opts = {sockjs_url:"http://cdn.sockjs.org/sockjs-0.3.min.js"},
		sockjs_echo = sockjs.createServer(sockjs_opts),
		dataHandler;

	sockjs_echo.on('connection', function (conn) {
		if (null == conn) {
			logger.error ("null == conn");
			return;
		}
		conn.on('data', function (message) {
			try {
				var data = JSON.parse(message);
				dataHandler[data.type](conn, data);
			} catch (e) {
				logger.error("error receiving response:" + e);
			}

		});
		conn.on('error', function () {
			logger.error("On error");
		});
		conn.on('close', function () {
			logger.info("Connection closed or timed out");
		});
	});

	function sendData(conn, data) {
		conn.write(JSON.stringify(data));
	}

	dataHandler = (function () {
		function spellCheck(conn, data) {
			function checkEnd() {
				if (0 === data.usrWordsLength) {
					//data.end = new Date();
					//console.log("time - " + (data.end.getTime() - data.start.getTime()));
					sendData(conn, { type:"spellCheck", spellCheckData:JSON.stringify(data) });
				}
			}
			function spellSuggest(index, word, lang) {
				var oDictionary = arrDictionaries[lang];
				if (undefined === oDictionary) {
					data.usrCorrect[index] = false;
					--data.usrWordsLength;
					checkEnd();
				}

				if ("spell" === data.type) {
					oDictionary.spellSuggest(word, function (a, b) {
						data.usrCorrect[index] = a;
						--data.usrWordsLength;
						checkEnd();
					});
				} else if ("suggest" === data.type) {
					oDictionary.spellSuggestions(word, function (a, b) {
						data.usrSuggest[index] = b;
						--data.usrWordsLength;
						checkEnd();
					});
				}
			}

			data = JSON.parse(data.spellCheckData);
			// Ответ
			data.usrCorrect = [];
			data.usrSuggest = [];
			data.usrWordsLength = data.usrWords.length;

			//data.start = new Date();
			for (var i = 0, length = data.usrWords.length; i < length; ++i) {
				spellSuggest(i, data.usrWords[i], data.usrLang[i]);
			}
		}

		return {
			spellCheck:spellCheck
		};
	}());

	sockjs_echo.installHandlers(server, {prefix:'/doc/[0-9-.a-zA-Z_=]*/c', log:function (severity, message) {
		//TODO: handle severity
		logger.info(message);
	}});

	callbackFunction();
};<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const paths = require('./paths');

// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];

const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
  throw new Error(
    'The NODE_ENV environment variable is required but was not specified.'
  );
}

// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
const dotenvFiles = [
  `${paths.dotenv}.${NODE_ENV}.local`,
  `${paths.dotenv}.${NODE_ENV}`,
  // Don't include `.env.local` for `test` environment
  // since normally you expect tests to produce the same
  // results for everyone
  NODE_ENV !== 'test' && `${paths.dotenv}.local`,
  paths.dotenv,
].filter(Boolean);

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
dotenvFiles.forEach(dotenvFile => {
  if (fs.existsSync(dotenvFile)) {
    require('dotenv').config({
      path: dotenvFile,
    });
  }
});

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
const REACT_APP = /^REACT_APP_/i;

const getClientEnvironment = publicUrl => {
  const raw = Object.keys(process.env)
    .filter(key => REACT_APP.test(key))
    .reduce(
      (env, key) => {
        env[key] = process.env[key];
        return env;
      },
      {
        // Useful for determining whether we're running in production mode.
        // Most importantly, it switches React into the correct mode.
        NODE_ENV: process.env.NODE_ENV || 'development',
        // Useful for resolving the correct path to static assets in `public`.
        // For example, .
        // This should only be used as an escape hatch. Normally you would put
        // images into the `src` and `import` them in code to get their paths.
        PUBLIC_URL: publicUrl,
      }
    );
  // Stringify all values so we can feed into Webpack DefinePlugin
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {}),
  };

  return { raw, stringified };
}

// Resolve import paths starting from the src directory.
process.env.NODE_PATH = paths.appSrc;

module.exports = getClientEnvironment;
<commit_msg>Use TRACKER_* environment variables<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const paths = require('./paths');

// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];

const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
  throw new Error(
    'The NODE_ENV environment variable is required but was not specified.'
  );
}

// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
const dotenvFiles = [
  `${paths.dotenv}.${NODE_ENV}.local`,
  `${paths.dotenv}.${NODE_ENV}`,
  // Don't include `.env.local` for `test` environment
  // since normally you expect tests to produce the same
  // results for everyone
  NODE_ENV !== 'test' && `${paths.dotenv}.local`,
  paths.dotenv,
].filter(Boolean);

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
dotenvFiles.forEach(dotenvFile => {
  if (fs.existsSync(dotenvFile)) {
    require('dotenv').config({
      path: dotenvFile,
    });
  }
});

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

// Grab NODE_ENV and TRACKER_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
const TRACKER = /^TRACKER_/i;

const getClientEnvironment = publicUrl => {
  const raw = Object.keys(process.env)
    .filter(key => TRACKER.test(key))
    .reduce(
      (env, key) => {
        env[key] = process.env[key];
        return env;
      },
      {
        // Useful for determining whether we're running in production mode.
        // Most importantly, it switches React into the correct mode.
        NODE_ENV: process.env.NODE_ENV || 'development',
        // Useful for resolving the correct path to static assets in `public`.
        // For example, .
        // This should only be used as an escape hatch. Normally you would put
        // images into the `src` and `import` them in code to get their paths.
        PUBLIC_URL: publicUrl,
      }
    );
  // Stringify all values so we can feed into Webpack DefinePlugin
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {}),
  };

  return { raw, stringified };
}

// Resolve import paths starting from the src directory.
process.env.NODE_PATH = paths.appSrc;

module.exports = getClientEnvironment;
<|endoftext|>