aboutsummaryrefslogtreecommitdiff
path: root/node_modules/envify/custom.js
blob: 981ee8344dcb4ccc5c58cc36eefc0067af6f5790 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
var esprima = require('esprima')
  , through = require('through')

var processEnvPattern = /\bprocess\.env\b/

module.exports = function(rootEnv) {
  rootEnv = rootEnv || process.env || {}

  return function envify(file, argv) {
    if (/\.json$/.test(file)) return through()

    var Syntax = esprima.Syntax
    var buffer = []
    argv = argv || {}

    return through(write, flush)

    function write(data) {
      buffer.push(data)
    }

    function transform(source, envs) {
      var args  = [].concat(envs[0]._ || []).concat(envs[1]._ || [])
      var purge = args.indexOf('purge') !== -1
      var replacements = []

      function match(node) {
        return (
          node.type === Syntax.MemberExpression
          && node.object.type === Syntax.MemberExpression
          && node.object.computed === false
          && node.object.object.type === Syntax.Identifier
          && node.object.object.name === 'process'
          && node.object.property.type === Syntax.Identifier
          && node.object.property.name === 'env'
          && (node.computed ? node.property.type === Syntax.Literal : node.property.type === Syntax.Identifier)
        )
      }

      esprima.parse(source, { tolerant: true }, function(node, meta) {
        if (match(node)) {
          var key = node.property.name || node.property.value
          for (var i = 0; i < envs.length; i++) {
            var value = envs[i][key]
            if (value !== undefined) {
              replacements.push({ node: node, meta: meta, value: JSON.stringify(value) })
              return
            }
          }
          if (purge) {
            replacements.push({ node: node, meta: meta, value: undefined })
          }
        } else if (node.type === Syntax.AssignmentExpression) {
          for (var i = 0; i < replacements.length; ++i) {
            if (replacements[i].node === node.left) {
              replacements.splice(i, 1)
            }
          }
        }
      })

      var result = source
      if (replacements.length > 0) {
        replacements.sort(function (a, b) {
          return b.meta.start.offset - a.meta.start.offset
        })
        for (var i = 0; i < replacements.length; i++) {
          var r = replacements[i]
          result = result.slice(0, r.meta.start.offset) + r.value + result.slice(r.meta.end.offset)
        }
      }

      return result
    }

    function flush() {
      var source = buffer.join('')

      if (processEnvPattern.test(source)) {
        try {
          source = transform(source, [argv, rootEnv])
        } catch(err) {
          return this.emit('error', err)
        }
      }

      this.queue(source)
      this.queue(null)
    }
  }
}