runFilter() {

    // Set filter here so this function can be called externally
    const filter = this.filter.val()

    // Ignore empty filters
    if (!filter || !filter.length) {
      this.emit('filter-empty')
      return
    }

    // Use the JavaScript vm to evaluate the filter with this context
    const script = `result = x${filter}`
    const context = {
      x: this.data,
      result: null
    }

    try {
      new vm.Script(script).runInNewContext(context)
      if (typeof context.result !== 'undefined') {
        this.emit('filter-valid', {
          result: context.result,
          type: 'js'
        })
      } else {
        this.emit('filter-invalid')
      }
    } catch (e) {
      fs.writeFileSync(this.tmp, JSON.stringify(this.data))

      // If JavaScript filter fails, run through jq
      jq.run(filter, this.tmp, {
        input: 'file',
        output: 'json'
      }).then((result) => {
        if (result === null) {

          // jq returns null for incorrect keys, but we will count them as
          // invalid
          this.emit('filter-invalid')
        } else {

          // The jq filter worked
          this.emit('filter-valid', {
            type: 'jq',
            result
          })
        }
      }).catch(() => {

        // jq filter failed
        this.emit('filter-invalid')
      })
    }
  }
Parse raw input as JavaScript first, then JQ