jmespath 1.4.0 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f2d08f64e74ad4927d6323f98b91486ad7d8f79c
4
- data.tar.gz: ce7796a88dab9241efacdeac1a3b36c9083ff6ca
2
+ SHA256:
3
+ metadata.gz: 6dd359b84687e9959f5ceefc730e01783a02c3c3fd32419112c9cc68bac69fe8
4
+ data.tar.gz: 19078671387ef295d8d00dfdc6d04758be5d54974b0bf7adfad998af8c0427c1
5
5
  SHA512:
6
- metadata.gz: ca3d9a98c00cedf8b5bafdc70d3cdb8b2ee754ef85dfa270807650fa9517d50db68e513d3713d431ac8ac1b9bdb9757ca76b2758bc8ddfde1add3eedb08973e4
7
- data.tar.gz: 7c09a5ee313e2f7feba1334c240fdc2a820eb9127d5e2db3392ac1dad3b29b2b8b4c55aee4f6c4309417d857df84f8854201a79ba5fe405d724f91a44db331d3
6
+ metadata.gz: 07234d57953b71829d79eeb7862ad7b55b06f96fb6c35ba7b0764ec1339c5b4c6b632b8d3d81ec4a193300e335e371772b54eb91c1092d46eb8ab374afd598b5
7
+ data.tar.gz: acc8a1daca807053070f8487a76703e45c67da851b3d32753294e67ad67dd7a930ef8f0596ff327c2779aea61b65c2f874ff5bcd4b34df79ba2366d7b6514f43
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.6.2
data/bin/jmespath.rb ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+
6
+ require 'jmespath'
7
+ require 'json'
8
+
9
+ expression = ARGV[0]
10
+ json = JSON.parse(STDIN.read)
11
+
12
+ $stdout.puts(JSON.dump(JMESPath.search(expression, json)))
@@ -1,8 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'thread'
2
3
 
3
4
  module JMESPath
4
5
  class CachingParser
5
-
6
6
  def initialize(options = {})
7
7
  @parser = options[:parser] || Parser.new(options)
8
8
  @mutex = Mutex.new
@@ -25,6 +25,5 @@ module JMESPath
25
25
  @cache[expression] = @parser.parse(expression)
26
26
  end
27
27
  end
28
-
29
28
  end
30
29
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JMESPath
2
4
  module Errors
3
-
4
5
  class Error < StandardError; end
5
6
 
6
7
  class RuntimeError < Error; end
@@ -14,6 +15,5 @@ module JMESPath
14
15
  class InvalidArityError < Error; end
15
16
 
16
17
  class UnknownFunctionError < Error; end
17
-
18
18
  end
19
19
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'json'
2
3
  require 'set'
3
4
 
4
5
  module JMESPath
5
6
  # @api private
6
7
  class Lexer
7
-
8
8
  T_DOT = :dot
9
9
  T_STAR = :star
10
10
  T_COMMA = :comma
@@ -134,14 +134,14 @@ module JMESPath
134
134
  'w' => STATE_IDENTIFIER,
135
135
  'x' => STATE_IDENTIFIER,
136
136
  'y' => STATE_IDENTIFIER,
137
- 'z' => STATE_IDENTIFIER,
138
- }
137
+ 'z' => STATE_IDENTIFIER
138
+ }.freeze
139
139
 
140
140
  VALID_IDENTIFIERS = Set.new(%w(
141
- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
142
- a b c d e f g h i j k l m n o p q r s t u v w x y z
143
- _ 0 1 2 3 4 5 6 7 8 9
144
- ))
141
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
142
+ a b c d e f g h i j k l m n o p q r s t u v w x y z
143
+ _ 0 1 2 3 4 5 6 7 8 9
144
+ ))
145
145
 
146
146
  NUMBERS = Set.new(%w(0 1 2 3 4 5 6 7 8 9))
147
147
 
@@ -155,13 +155,12 @@ module JMESPath
155
155
  '(' => T_LPAREN,
156
156
  ')' => T_RPAREN,
157
157
  '{' => T_LBRACE,
158
- '}' => T_RBRACE,
159
- }
158
+ '}' => T_RBRACE
159
+ }.freeze
160
160
 
161
161
  # @param [String<JMESPath>] expression
162
162
  # @return [Array<Hash>]
163
163
  def tokenize(expression)
164
-
165
164
  tokens = []
166
165
  chars = CharacterStream.new(expression.chars.to_a)
167
166
 
@@ -253,7 +252,7 @@ module JMESPath
253
252
  tokens << match_or(chars, '&', '&', T_AND, T_EXPREF)
254
253
  when STATE_NOT
255
254
  # consume not equals
256
- tokens << match_or(chars, '!', '=', T_COMPARATOR, T_NOT);
255
+ tokens << match_or(chars, '!', '=', T_COMPARATOR, T_NOT)
257
256
  else
258
257
  # either '<' or '>'
259
258
  # consume less than and greater than
@@ -298,12 +297,12 @@ module JMESPath
298
297
  # Certain versions of Ruby and of the pure_json gem not support loading
299
298
  # scalar JSON values, such a numbers, booleans, strings, etc. These
300
299
  # simple values must be first wrapped inside a JSON object before calling
301
- # `JSON.load`.
300
+ # `JSON.parse`.
302
301
  #
303
302
  # # works in most JSON versions, raises in some versions
304
- # JSON.load("true")
305
- # JSON.load("123")
306
- # JSON.load("\"abc\"")
303
+ # JSON.parse("true")
304
+ # JSON.parse("123")
305
+ # JSON.parse("\"abc\"")
307
306
  #
308
307
  # This is an known issue for:
309
308
  #
@@ -317,27 +316,25 @@ module JMESPath
317
316
  # causes issues in environments that cannot compile the gem. We previously
318
317
  # had a direct dependency on `json_pure`, but this broke with the v2 update.
319
318
  #
320
- # This method allows us to detect how the `JSON.load` behaves so we know
319
+ # This method allows us to detect how the `JSON.parse` behaves so we know
321
320
  # if we have to wrap scalar JSON values to parse them or not.
322
321
  # @api private
323
322
  def self.requires_wrapping?
324
- begin
325
- JSON.load('false')
326
- rescue JSON::ParserError
327
- true
328
- end
323
+ JSON.parse('false')
324
+ rescue JSON::ParserError
325
+ true
329
326
  end
330
327
 
331
328
  if requires_wrapping?
332
329
  def parse_json(token, quoted = false)
333
330
  begin
334
331
  if quoted
335
- token.value = JSON.load("{\"value\":#{token.value}}")['value']
332
+ token.value = JSON.parse("{\"value\":#{token.value}}")['value']
336
333
  else
337
334
  begin
338
- token.value = JSON.load("{\"value\":#{token.value}}")['value']
335
+ token.value = JSON.parse("{\"value\":#{token.value}}")['value']
339
336
  rescue
340
- token.value = JSON.load(sprintf('{"value":"%s"}', token.value.lstrip))['value']
337
+ token.value = JSON.parse(sprintf('{"value":"%s"}', token.value.lstrip))['value']
341
338
  end
342
339
  end
343
340
  rescue JSON::ParserError
@@ -349,9 +346,13 @@ module JMESPath
349
346
  def parse_json(token, quoted = false)
350
347
  begin
351
348
  if quoted
352
- token.value = JSON.load(token.value)
349
+ token.value = JSON.parse(token.value)
353
350
  else
354
- token.value = JSON.load(token.value) rescue JSON.load(sprintf('"%s"', token.value.lstrip))
351
+ token.value = begin
352
+ JSON.parse(token.value)
353
+ rescue
354
+ JSON.parse(sprintf('"%s"', token.value.lstrip))
355
+ end
355
356
  end
356
357
  rescue JSON::ParserError
357
358
  token.type = T_UNKNOWN
@@ -361,7 +362,6 @@ module JMESPath
361
362
  end
362
363
 
363
364
  class CharacterStream
364
-
365
365
  def initialize(chars)
366
366
  @chars = chars
367
367
  @position = 0
@@ -376,10 +376,7 @@ module JMESPath
376
376
  @chars[@position]
377
377
  end
378
378
 
379
- def position
380
- @position
381
- end
382
-
379
+ attr_reader :position
383
380
  end
384
381
  end
385
382
  end
@@ -1,7 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  module JMESPath
2
3
  module Nodes
3
4
  class And < Node
4
-
5
5
  def initialize(left, right)
6
6
  @left = left
7
7
  @right = right
@@ -19,7 +19,6 @@ module JMESPath
19
19
  def optimize
20
20
  self.class.new(@left.optimize, @right.optimize)
21
21
  end
22
-
23
22
  end
24
23
  end
25
24
  end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  module JMESPath
2
3
  # @api private
3
4
  module Nodes
4
5
  class Comparator < Node
6
+ COMPARABLE_TYPES = [Numeric, String].freeze
7
+
5
8
  attr_reader :left, :right
6
9
 
7
10
  def initialize(left, right)
@@ -33,62 +36,51 @@ module JMESPath
33
36
 
34
37
  private
35
38
 
36
- def check(left_value, right_value)
39
+ def check(_left_value, _right_value)
37
40
  nil
38
41
  end
42
+
43
+ def comparable?(left_value, right_value)
44
+ COMPARABLE_TYPES.any? do |type|
45
+ left_value.is_a?(type) && right_value.is_a?(type)
46
+ end
47
+ end
39
48
  end
40
49
 
41
50
  module Comparators
42
-
43
51
  class Eq < Comparator
44
52
  def check(left_value, right_value)
45
- left_value == right_value
53
+ Util.as_json(left_value) == Util.as_json(right_value)
46
54
  end
47
55
  end
48
56
 
49
57
  class Neq < Comparator
50
58
  def check(left_value, right_value)
51
- left_value != right_value
59
+ Util.as_json(left_value) != Util.as_json(right_value)
52
60
  end
53
61
  end
54
62
 
55
63
  class Gt < Comparator
56
64
  def check(left_value, right_value)
57
- if left_value.is_a?(Numeric) && right_value.is_a?(Numeric)
58
- left_value > right_value
59
- else
60
- nil
61
- end
65
+ left_value > right_value if comparable?(left_value, right_value)
62
66
  end
63
67
  end
64
68
 
65
69
  class Gte < Comparator
66
70
  def check(left_value, right_value)
67
- if left_value.is_a?(Numeric) && right_value.is_a?(Numeric)
68
- left_value >= right_value
69
- else
70
- nil
71
- end
71
+ left_value >= right_value if comparable?(left_value, right_value)
72
72
  end
73
73
  end
74
74
 
75
75
  class Lt < Comparator
76
76
  def check(left_value, right_value)
77
- if left_value.is_a?(Numeric) && right_value.is_a?(Numeric)
78
- left_value < right_value
79
- else
80
- nil
81
- end
77
+ left_value < right_value if comparable?(left_value, right_value)
82
78
  end
83
79
  end
84
80
 
85
81
  class Lte < Comparator
86
82
  def check(left_value, right_value)
87
- if left_value.is_a?(Numeric) && right_value.is_a?(Numeric)
88
- left_value <= right_value
89
- else
90
- nil
91
- end
83
+ left_value <= right_value if comparable?(left_value, right_value)
92
84
  end
93
85
  end
94
86
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module JMESPath
2
3
  # @api private
3
4
  module Nodes
@@ -27,6 +28,7 @@ module JMESPath
27
28
 
28
29
  class ComparatorCondition < Node
29
30
  COMPARATOR_TO_CONDITION = {}
31
+ COMPARABLE_TYPES = [Numeric, String].freeze
30
32
 
31
33
  def initialize(left, right, child)
32
34
  @left = left
@@ -34,16 +36,24 @@ module JMESPath
34
36
  @child = child
35
37
  end
36
38
 
37
- def visit(value)
39
+ def visit(_value)
38
40
  nil
39
41
  end
42
+
43
+ private
44
+
45
+ def comparable?(left_value, right_value)
46
+ COMPARABLE_TYPES.any? do |type|
47
+ left_value.is_a?(type) && right_value.is_a?(type)
48
+ end
49
+ end
40
50
  end
41
51
 
42
52
  class EqCondition < ComparatorCondition
43
53
  COMPARATOR_TO_CONDITION[Comparators::Eq] = self
44
54
 
45
55
  def visit(value)
46
- @left.visit(value) == @right.visit(value) ? @child.visit(value) : nil
56
+ Util.as_json(@left.visit(value)) == Util.as_json(@right.visit(value)) ? @child.visit(value) : nil
47
57
  end
48
58
 
49
59
  def optimize
@@ -62,7 +72,7 @@ module JMESPath
62
72
  end
63
73
 
64
74
  def visit(value)
65
- @left.visit(value) == @right ? @child.visit(value) : nil
75
+ Util.as_json(@left.visit(value)) == @right ? @child.visit(value) : nil
66
76
  end
67
77
  end
68
78
 
@@ -70,7 +80,7 @@ module JMESPath
70
80
  COMPARATOR_TO_CONDITION[Comparators::Neq] = self
71
81
 
72
82
  def visit(value)
73
- @left.visit(value) != @right.visit(value) ? @child.visit(value) : nil
83
+ Util.as_json(@left.visit(value)) != Util.as_json(@right.visit(value)) ? @child.visit(value) : nil
74
84
  end
75
85
 
76
86
  def optimize
@@ -89,7 +99,7 @@ module JMESPath
89
99
  end
90
100
 
91
101
  def visit(value)
92
- @left.visit(value) != @right ? @child.visit(value) : nil
102
+ Util.as_json(@left.visit(value)) != @right ? @child.visit(value) : nil
93
103
  end
94
104
  end
95
105
 
@@ -99,7 +109,7 @@ module JMESPath
99
109
  def visit(value)
100
110
  left_value = @left.visit(value)
101
111
  right_value = @right.visit(value)
102
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && left_value > right_value ? @child.visit(value) : nil
112
+ comparable?(left_value, right_value) && left_value > right_value ? @child.visit(value) : nil
103
113
  end
104
114
  end
105
115
 
@@ -109,7 +119,7 @@ module JMESPath
109
119
  def visit(value)
110
120
  left_value = @left.visit(value)
111
121
  right_value = @right.visit(value)
112
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && left_value >= right_value ? @child.visit(value) : nil
122
+ comparable?(left_value, right_value) && left_value >= right_value ? @child.visit(value) : nil
113
123
  end
114
124
  end
115
125
 
@@ -119,7 +129,7 @@ module JMESPath
119
129
  def visit(value)
120
130
  left_value = @left.visit(value)
121
131
  right_value = @right.visit(value)
122
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && left_value < right_value ? @child.visit(value) : nil
132
+ comparable?(left_value, right_value) && left_value < right_value ? @child.visit(value) : nil
123
133
  end
124
134
  end
125
135
 
@@ -129,7 +139,7 @@ module JMESPath
129
139
  def visit(value)
130
140
  left_value = @left.visit(value)
131
141
  right_value = @right.visit(value)
132
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && left_value <= right_value ? @child.visit(value) : nil
142
+ comparable?(left_value, right_value) && left_value <= right_value ? @child.visit(value) : nil
133
143
  end
134
144
  end
135
145
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module JMESPath
2
3
  # @api private
3
4
  module Nodes
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module JMESPath
2
3
  # @api private
3
4
  module Nodes
@@ -8,7 +9,7 @@ module JMESPath
8
9
  @expression = expression
9
10
  end
10
11
 
11
- def visit(value)
12
+ def visit(_value)
12
13
  self
13
14
  end
14
15
 
@@ -22,4 +23,3 @@ module JMESPath
22
23
  end
23
24
  end
24
25
  end
25
-
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module JMESPath
2
3
  # @api private
3
4
  module Nodes
@@ -8,9 +9,10 @@ module JMESPath
8
9
  end
9
10
 
10
11
  def visit(value)
11
- if value.is_a?(Array) && @key.is_a?(Integer)
12
- value[@key]
13
- elsif value.is_a?(Hash)
12
+ if value.respond_to?(:to_ary) && @key.is_a?(Integer)
13
+ value.to_ary[@key]
14
+ elsif value.respond_to?(:to_hash)
15
+ value = value.to_hash
14
16
  if !(v = value[@key]).nil?
15
17
  v
16
18
  elsif @key_sym && !(v = value[@key_sym]).nil?
@@ -40,17 +42,16 @@ module JMESPath
40
42
  def initialize(keys)
41
43
  @keys = keys
42
44
  @key_syms = keys.each_with_object({}) do |k, syms|
43
- if k.respond_to?(:to_sym)
44
- syms[k] = k.to_sym
45
- end
45
+ syms[k] = k.to_sym if k.respond_to?(:to_sym)
46
46
  end
47
47
  end
48
48
 
49
49
  def visit(obj)
50
50
  @keys.reduce(obj) do |value, key|
51
- if value.is_a?(Array) && key.is_a?(Integer)
52
- value[key]
53
- elsif value.is_a?(Hash)
51
+ if value.respond_to?(:to_ary) && key.is_a?(Integer)
52
+ value.to_ary[key]
53
+ elsif value.respond_to?(:to_hash)
54
+ value = value.to_hash
54
55
  if !(v = value[key]).nil?
55
56
  v
56
57
  elsif (sym = @key_syms[key]) && !(v = value[sym]).nil?
@@ -68,10 +69,7 @@ module JMESPath
68
69
 
69
70
  private
70
71
 
71
- def keys
72
- @keys
73
- end
74
-
72
+ attr_reader :keys
75
73
  end
76
74
  end
77
75
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module JMESPath
2
3
  # @api private
3
4
  module Nodes
@@ -8,16 +9,14 @@ module JMESPath
8
9
 
9
10
  def visit(value)
10
11
  value = @child.visit(value)
11
- if Array === value
12
- value.each_with_object([]) do |v, values|
13
- if Array === v
14
- values.concat(v)
12
+ if value.respond_to?(:to_ary)
13
+ value.to_ary.each_with_object([]) do |v, values|
14
+ if v.respond_to?(:to_ary)
15
+ values.concat(v.to_ary)
15
16
  else
16
17
  values.push(v)
17
18
  end
18
19
  end
19
- else
20
- nil
21
20
  end
22
21
  end
23
22