jmespath 1.2.4 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of jmespath might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2892bed3a7fb6f4285e9120e0f062cde8ef8aab2
4
- data.tar.gz: 1fac588695e21b8f26ec71b286b998c2abe1f3bb
2
+ SHA256:
3
+ metadata.gz: 802d17af3f269cfbd38879ff753082257effba66f383f415667b1018d9d68c5c
4
+ data.tar.gz: 3b9ec8bf65b3dbcf00273667510385a406fa2c23cd64890557a76263944a8b0f
5
5
  SHA512:
6
- metadata.gz: f55a519231ac35c9f680d2b8db88e21fe9f7ff84ee0c189a35600e0751eb82b536193363c1f0fcbba298932b325bdefde1b209f46db9e92aac0c88b84fd2d2a2
7
- data.tar.gz: 9ff7f1d9b5774ee3229009cd0f555ff4fcf0df3bffafedd3300de7388163ba9f95617696c1efc93ca03f81b32bd251917649fc907e354c5c0768fcf696718073
6
+ metadata.gz: c95fe346be9e1e36a67869cad050a03e74ae414ceedb09049210419a9d4c5455df38e49403bcedf1434b56e8b45d6142527bdb3d2af86919cc833da021251e16
7
+ data.tar.gz: 73e3c073ccf6b57c65c2246d12fd4a3c5d5f3beb603772966c4ec92371f9ed10f4e1a10b66a1619f50fdd78137a1a6b0998f65b4e7f966a928e5fc2a8d7393be
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.5.0
@@ -243,7 +243,7 @@ module JMESPath
243
243
  token = inside(chars, '"', T_QUOTED_IDENTIFIER)
244
244
  if token.type == T_QUOTED_IDENTIFIER
245
245
  token.value = "\"#{token.value}\""
246
- token = parse_json(token)
246
+ token = parse_json(token, true)
247
247
  end
248
248
  tokens << token
249
249
  when STATE_EQ
@@ -295,13 +295,69 @@ module JMESPath
295
295
  Token.new(type, buffer.join, position)
296
296
  end
297
297
 
298
- def parse_json(token)
298
+ # Certain versions of Ruby and of the pure_json gem not support loading
299
+ # scalar JSON values, such a numbers, booleans, strings, etc. These
300
+ # simple values must be first wrapped inside a JSON object before calling
301
+ # `JSON.load`.
302
+ #
303
+ # # works in most JSON versions, raises in some versions
304
+ # JSON.load("true")
305
+ # JSON.load("123")
306
+ # JSON.load("\"abc\"")
307
+ #
308
+ # This is an known issue for:
309
+ #
310
+ # * Ruby 1.9.3 bundled v1.5.5 of json; Ruby 1.9.3 defaults to bundled
311
+ # version despite newer versions being available.
312
+ #
313
+ # * json_pure v2.0.0+
314
+ #
315
+ # It is not possible to change the version of JSON loaded in the
316
+ # user's application. Adding an explicit dependency on json gem
317
+ # causes issues in environments that cannot compile the gem. We previously
318
+ # had a direct dependency on `json_pure`, but this broke with the v2 update.
319
+ #
320
+ # This method allows us to detect how the `JSON.load` behaves so we know
321
+ # if we have to wrap scalar JSON values to parse them or not.
322
+ # @api private
323
+ def self.requires_wrapping?
299
324
  begin
300
- token.value = JSON.load(token.value)
325
+ JSON.load('false')
301
326
  rescue JSON::ParserError
302
- token.type = T_UNKNOWN
327
+ true
328
+ end
329
+ end
330
+
331
+ if requires_wrapping?
332
+ def parse_json(token, quoted = false)
333
+ begin
334
+ if quoted
335
+ token.value = JSON.load("{\"value\":#{token.value}}")['value']
336
+ else
337
+ begin
338
+ token.value = JSON.load("{\"value\":#{token.value}}")['value']
339
+ rescue
340
+ token.value = JSON.load(sprintf('{"value":"%s"}', token.value.lstrip))['value']
341
+ end
342
+ end
343
+ rescue JSON::ParserError
344
+ token.type = T_UNKNOWN
345
+ end
346
+ token
347
+ end
348
+ else
349
+ def parse_json(token, quoted = false)
350
+ begin
351
+ if quoted
352
+ token.value = JSON.load(token.value)
353
+ else
354
+ token.value = JSON.load(token.value) rescue JSON.load(sprintf('"%s"', token.value.lstrip))
355
+ end
356
+ rescue JSON::ParserError
357
+ token.type = T_UNKNOWN
358
+ end
359
+ token
303
360
  end
304
- token
305
361
  end
306
362
 
307
363
  class CharacterStream
@@ -42,37 +42,53 @@ module JMESPath
42
42
 
43
43
  class Eq < Comparator
44
44
  def check(left_value, right_value)
45
- left_value == right_value
45
+ Util.as_json(left_value) == Util.as_json(right_value)
46
46
  end
47
47
  end
48
48
 
49
49
  class Neq < Comparator
50
50
  def check(left_value, right_value)
51
- left_value != right_value
51
+ Util.as_json(left_value) != Util.as_json(right_value)
52
52
  end
53
53
  end
54
54
 
55
55
  class Gt < Comparator
56
56
  def check(left_value, right_value)
57
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && 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
58
62
  end
59
63
  end
60
64
 
61
65
  class Gte < Comparator
62
66
  def check(left_value, right_value)
63
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && 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
64
72
  end
65
73
  end
66
74
 
67
75
  class Lt < Comparator
68
76
  def check(left_value, right_value)
69
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && 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
70
82
  end
71
83
  end
72
84
 
73
85
  class Lte < Comparator
74
86
  def check(left_value, right_value)
75
- left_value.is_a?(Integer) && right_value.is_a?(Integer) && 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
76
92
  end
77
93
  end
78
94
  end
@@ -43,7 +43,7 @@ module JMESPath
43
43
  COMPARATOR_TO_CONDITION[Comparators::Eq] = self
44
44
 
45
45
  def visit(value)
46
- @left.visit(value) == @right.visit(value) ? @child.visit(value) : nil
46
+ Util.as_json(@left.visit(value)) == Util.as_json(@right.visit(value)) ? @child.visit(value) : nil
47
47
  end
48
48
 
49
49
  def optimize
@@ -62,7 +62,7 @@ module JMESPath
62
62
  end
63
63
 
64
64
  def visit(value)
65
- @left.visit(value) == @right ? @child.visit(value) : nil
65
+ Util.as_json(@left.visit(value)) == @right ? @child.visit(value) : nil
66
66
  end
67
67
  end
68
68
 
@@ -70,7 +70,7 @@ module JMESPath
70
70
  COMPARATOR_TO_CONDITION[Comparators::Neq] = self
71
71
 
72
72
  def visit(value)
73
- @left.visit(value) != @right.visit(value) ? @child.visit(value) : nil
73
+ Util.as_json(@left.visit(value)) != Util.as_json(@right.visit(value)) ? @child.visit(value) : nil
74
74
  end
75
75
 
76
76
  def optimize
@@ -89,7 +89,7 @@ module JMESPath
89
89
  end
90
90
 
91
91
  def visit(value)
92
- @left.visit(value) != @right ? @child.visit(value) : nil
92
+ Util.as_json(@left.visit(value)) != @right ? @child.visit(value) : nil
93
93
  end
94
94
  end
95
95
 
@@ -8,9 +8,10 @@ module JMESPath
8
8
  end
9
9
 
10
10
  def visit(value)
11
- if value.is_a?(Array) && @key.is_a?(Integer)
12
- value[@key]
13
- elsif value.is_a?(Hash)
11
+ if value.respond_to?(:to_ary) && @key.is_a?(Integer)
12
+ value.to_ary[@key]
13
+ elsif value.respond_to?(:to_hash)
14
+ value = value.to_hash
14
15
  if !(v = value[@key]).nil?
15
16
  v
16
17
  elsif @key_sym && !(v = value[@key_sym]).nil?
@@ -48,9 +49,10 @@ module JMESPath
48
49
 
49
50
  def visit(obj)
50
51
  @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)
52
+ if value.respond_to?(:to_ary) && key.is_a?(Integer)
53
+ value.to_ary[key]
54
+ elsif value.respond_to?(:to_hash)
55
+ value = value.to_hash
54
56
  if !(v = value[key]).nil?
55
57
  v
56
58
  elsif (sym = @key_syms[key]) && !(v = value[sym]).nil?
@@ -8,10 +8,10 @@ module JMESPath
8
8
 
9
9
  def visit(value)
10
10
  value = @child.visit(value)
11
- if Array === value
12
- value.each_with_object([]) do |v, values|
13
- if Array === v
14
- values.concat(v)
11
+ if value.respond_to?(:to_ary)
12
+ value.to_ary.each_with_object([]) do |v, values|
13
+ if v.respond_to?(:to_ary)
14
+ values.concat(v.to_ary)
15
15
  else
16
16
  values.push(v)
17
17
  end
@@ -50,14 +50,20 @@ module JMESPath
50
50
 
51
51
  module TypeChecker
52
52
  def get_type(value)
53
- case value
54
- when String then STRING_TYPE
55
- when true, false then BOOLEAN_TYPE
56
- when nil then NULL_TYPE
57
- when Numeric then NUMBER_TYPE
58
- when Hash, Struct then OBJECT_TYPE
59
- when Array then ARRAY_TYPE
60
- when Expression then EXPRESSION_TYPE
53
+ if value.respond_to?(:to_str)
54
+ STRING_TYPE
55
+ elsif value == true || value == false
56
+ BOOLEAN_TYPE
57
+ elsif value == nil
58
+ NULL_TYPE
59
+ elsif value.is_a?(Numeric)
60
+ NUMBER_TYPE
61
+ elsif value.respond_to?(:to_hash) || value.is_a?(Struct)
62
+ OBJECT_TYPE
63
+ elsif value.respond_to?(:to_ary)
64
+ ARRAY_TYPE
65
+ elsif value.is_a?(Expression)
66
+ EXPRESSION_TYPE
61
67
  end
62
68
  end
63
69
 
@@ -106,7 +112,9 @@ module JMESPath
106
112
  else
107
113
  return maybe_raise Errors::InvalidArityError, "function avg() expects one argument"
108
114
  end
109
- if Array === values
115
+ if values.respond_to?(:to_ary)
116
+ values = values.to_ary
117
+ return nil if values.empty?
110
118
  values.inject(0) do |total,n|
111
119
  if Numeric === n
112
120
  total + n
@@ -143,9 +151,11 @@ module JMESPath
143
151
  def call(args)
144
152
  if args.count == 2
145
153
  haystack = args[0]
146
- needle = args[1]
147
- if String === haystack || Array === haystack
148
- haystack.include?(needle)
154
+ needle = Util.as_json(args[1])
155
+ if haystack.respond_to?(:to_str)
156
+ haystack.to_str.include?(needle)
157
+ elsif haystack.respond_to?(:to_ary)
158
+ haystack.to_ary.any? { |e| Util.as_json(e) == needle }
149
159
  else
150
160
  return maybe_raise Errors::InvalidTypeError, "contains expects 2nd arg to be a list"
151
161
  end
@@ -181,9 +191,14 @@ module JMESPath
181
191
  else
182
192
  return maybe_raise Errors::InvalidArityError, "function length() expects one argument"
183
193
  end
184
- case value
185
- when Hash, Array, String then value.size
186
- else return maybe_raise Errors::InvalidTypeError, "function length() expects string, array or object"
194
+ if value.respond_to?(:to_hash)
195
+ value.to_hash.size
196
+ elsif value.respond_to?(:to_ary)
197
+ value.to_ary.size
198
+ elsif value.respond_to?(:to_str)
199
+ value.to_str.size
200
+ else
201
+ return maybe_raise Errors::InvalidTypeError, "function length() expects string, array or object"
187
202
  end
188
203
  end
189
204
  end
@@ -201,13 +216,13 @@ module JMESPath
201
216
  else
202
217
  return maybe_raise Errors::InvalidTypeError, "function map() expects the first argument to be an expression"
203
218
  end
204
- if Array === args[1]
205
- list = args[1]
219
+ if args[1].respond_to?(:to_ary)
220
+ list = args[1].to_ary
206
221
  else
207
222
  return maybe_raise Errors::InvalidTypeError, "function map() expects the second argument to be an list"
208
223
  end
209
224
  list.map { |value| expr.eval(value) }
210
- end
225
+ end
211
226
 
212
227
  end
213
228
 
@@ -222,7 +237,8 @@ module JMESPath
222
237
  else
223
238
  return maybe_raise Errors::InvalidArityError, "function max() expects one argument"
224
239
  end
225
- if Array === values
240
+ if values.respond_to?(:to_ary)
241
+ values = values.to_ary
226
242
  return nil if values.empty?
227
243
  first = values.first
228
244
  first_type = get_type(first)
@@ -257,7 +273,8 @@ module JMESPath
257
273
  else
258
274
  return maybe_raise Errors::InvalidArityError, "function min() expects one argument"
259
275
  end
260
- if Array === values
276
+ if values.respond_to?(:to_ary)
277
+ values = values.to_ary
261
278
  return nil if values.empty?
262
279
  first = values.first
263
280
  first_type = get_type(first)
@@ -301,12 +318,10 @@ module JMESPath
301
318
  def call(args)
302
319
  if args.count == 1
303
320
  value = args.first
304
- if hash_like?(value)
305
- case value
306
- when Hash then value.keys.map(&:to_s)
307
- when Struct then value.members.map(&:to_s)
308
- else raise NotImplementedError
309
- end
321
+ if value.respond_to?(:to_hash)
322
+ value.to_hash.keys.map(&:to_s)
323
+ elsif value.is_a?(Struct)
324
+ value.members.map(&:to_s)
310
325
  else
311
326
  return maybe_raise Errors::InvalidTypeError, "function keys() expects a hash"
312
327
  end
@@ -322,10 +337,12 @@ module JMESPath
322
337
  def call(args)
323
338
  if args.count == 1
324
339
  value = args.first
325
- if hash_like?(value)
340
+ if value.respond_to?(:to_hash)
341
+ value.to_hash.values
342
+ elsif value.is_a?(Struct)
326
343
  value.values
327
- elsif Array === value
328
- value
344
+ elsif value.respond_to?(:to_ary)
345
+ value.to_ary
329
346
  else
330
347
  return maybe_raise Errors::InvalidTypeError, "function values() expects an array or a hash"
331
348
  end
@@ -342,10 +359,10 @@ module JMESPath
342
359
  if args.count == 2
343
360
  glue = args[0]
344
361
  values = args[1]
345
- if !(String === glue)
362
+ if !glue.respond_to?(:to_str)
346
363
  return maybe_raise Errors::InvalidTypeError, "function join() expects the first argument to be a string"
347
- elsif Array === values && values.all? { |v| String === v }
348
- values.join(glue)
364
+ elsif values.respond_to?(:to_ary) && values.to_ary.all? { |v| v.respond_to?(:to_str) }
365
+ values.to_ary.join(glue)
349
366
  else
350
367
  return maybe_raise Errors::InvalidTypeError, "function join() expects values to be an array of strings"
351
368
  end
@@ -361,7 +378,7 @@ module JMESPath
361
378
  def call(args)
362
379
  if args.count == 1
363
380
  value = args.first
364
- String === value ? value : JSON.dump(value)
381
+ value.respond_to?(:to_str) ? value.to_str : value.to_json
365
382
  else
366
383
  return maybe_raise Errors::InvalidArityError, "function to_string() expects one argument"
367
384
  end
@@ -389,8 +406,8 @@ module JMESPath
389
406
  FUNCTIONS['sum'] = self
390
407
 
391
408
  def call(args)
392
- if args.count == 1 && Array === args.first
393
- args.first.inject(0) do |sum,n|
409
+ if args.count == 1 && args.first.respond_to?(:to_ary)
410
+ args.first.to_ary.inject(0) do |sum,n|
394
411
  if Numeric === n
395
412
  sum + n
396
413
  else
@@ -423,15 +440,24 @@ module JMESPath
423
440
  def call(args)
424
441
  if args.count == 1
425
442
  value = args.first
426
- if Array === value
427
- value.sort do |a, b|
428
- a_type = get_type(a)
429
- b_type = get_type(b)
430
- if (a_type == STRING_TYPE || a_type == NUMBER_TYPE) && a_type == b_type
431
- a <=> b
432
- else
433
- return maybe_raise Errors::InvalidTypeError, "function sort() expects values to be an array of numbers or integers"
443
+ if value.respond_to?(:to_ary)
444
+ value = value.to_ary
445
+ # every element in the list must be of the same type
446
+ array_type = get_type(value[0])
447
+ if array_type == STRING_TYPE || array_type == NUMBER_TYPE || value.size == 0
448
+ # stable sort
449
+ n = 0
450
+ value.sort_by do |v|
451
+ value_type = get_type(v)
452
+ if value_type != array_type
453
+ msg = "function sort() expects values to be an array of only numbers, or only integers"
454
+ return maybe_raise Errors::InvalidTypeError, msg
455
+ end
456
+ n += 1
457
+ [v, n]
434
458
  end
459
+ else
460
+ return maybe_raise Errors::InvalidTypeError, "function sort() expects values to be an array of numbers or integers"
435
461
  end
436
462
  else
437
463
  return maybe_raise Errors::InvalidTypeError, "function sort() expects values to be an array of numbers or integers"
@@ -450,18 +476,24 @@ module JMESPath
450
476
  def call(args)
451
477
  if args.count == 2
452
478
  if get_type(args[0]) == ARRAY_TYPE && get_type(args[1]) == EXPRESSION_TYPE
453
- values = args[0]
479
+ values = args[0].to_ary
454
480
  expression = args[1]
455
- values.sort do |a,b|
456
- a_value = expression.eval(a)
457
- b_value = expression.eval(b)
458
- a_type = get_type(a_value)
459
- b_type = get_type(b_value)
460
- if (a_type == STRING_TYPE || a_type == NUMBER_TYPE) && a_type == b_type
461
- a_value <=> b_value
462
- else
463
- return maybe_raise Errors::InvalidTypeError, "function sort() expects values to be an array of numbers or integers"
481
+ array_type = get_type(expression.eval(values[0]))
482
+ if array_type == STRING_TYPE || array_type == NUMBER_TYPE || values.size == 0
483
+ # stable sort the list
484
+ n = 0
485
+ values.sort_by do |value|
486
+ value = expression.eval(value)
487
+ value_type = get_type(value)
488
+ if value_type != array_type
489
+ msg = "function sort() expects values to be an array of only numbers, or only integers"
490
+ return maybe_raise Errors::InvalidTypeError, msg
491
+ end
492
+ n += 1
493
+ [value, n]
464
494
  end
495
+ else
496
+ return maybe_raise Errors::InvalidTypeError, "function sort() expects values to be an array of numbers or integers"
465
497
  end
466
498
  else
467
499
  return maybe_raise Errors::InvalidTypeError, "function sort_by() expects an array and an expression"
@@ -480,6 +512,7 @@ module JMESPath
480
512
  values = args[0]
481
513
  expression = args[1]
482
514
  if get_type(values) == ARRAY_TYPE && get_type(expression) == EXPRESSION_TYPE
515
+ values = values.to_ary
483
516
  type = get_type(expression.eval(values.first))
484
517
  if type != NUMBER_TYPE && type != STRING_TYPE
485
518
  msg = "function #{mode}() expects values to be strings or numbers"
@@ -601,8 +634,10 @@ module JMESPath
601
634
  return maybe_raise Errors::InvalidArityError, msg
602
635
  end
603
636
  value = args.first
604
- if Array === value || String === value
605
- value.reverse
637
+ if value.respond_to?(:to_ary)
638
+ value.to_ary.reverse
639
+ elsif value.respond_to?(:to_str)
640
+ value.to_str.reverse
606
641
  else
607
642
  msg = "function reverse() expects an array or string"
608
643
  return maybe_raise Errors::InvalidTypeError, msg
@@ -615,7 +650,7 @@ module JMESPath
615
650
 
616
651
  def call(args)
617
652
  value = args.first
618
- Array === value ? value : [value]
653
+ value.respond_to?(:to_ary) ? value.to_ary : [value]
619
654
  end
620
655
  end
621
656
  end
@@ -45,8 +45,8 @@ module JMESPath
45
45
 
46
46
  class ArrayProjection < Projection
47
47
  def extract_targets(target)
48
- if Array === target
49
- target
48
+ if target.respond_to?(:to_ary)
49
+ target.to_ary
50
50
  else
51
51
  nil
52
52
  end
@@ -63,7 +63,9 @@ module JMESPath
63
63
 
64
64
  class ObjectProjection < Projection
65
65
  def extract_targets(target)
66
- if hash_like?(target)
66
+ if target.respond_to?(:to_hash)
67
+ target.to_hash.values
68
+ elsif target.is_a?(Struct)
67
69
  target.values
68
70
  else
69
71
  nil
@@ -10,7 +10,7 @@ module JMESPath
10
10
  end
11
11
 
12
12
  def visit(value)
13
- if String === value || Array === value
13
+ if (value = value.respond_to?(:to_str) ? value.to_str : value.respond_to?(:to_ary) ? value.to_ary : nil)
14
14
  start, stop, step = adjust_slice(value.size, @start, @stop, @step)
15
15
  result = []
16
16
  if step > 0
@@ -26,7 +26,7 @@ module JMESPath
26
26
  i += step
27
27
  end
28
28
  end
29
- String === value ? result.join : result
29
+ value.respond_to?(:to_str) ? result.join : result
30
30
  else
31
31
  nil
32
32
  end
@@ -80,7 +80,7 @@ module JMESPath
80
80
  end
81
81
 
82
82
  def visit(value)
83
- if String === value || Array === value
83
+ if (value = value.respond_to?(:to_str) ? value.to_str : value.respond_to?(:to_ary) ? value.to_ary : nil)
84
84
  value[@start, @stop - @start]
85
85
  else
86
86
  nil
@@ -5,10 +5,6 @@ module JMESPath
5
5
  def visit(value)
6
6
  end
7
7
 
8
- def hash_like?(value)
9
- Hash === value || Struct === value
10
- end
11
-
12
8
  def optimize
13
9
  self
14
10
  end
@@ -17,28 +13,29 @@ module JMESPath
17
13
  false
18
14
  end
19
15
  end
16
+
17
+ require 'jmespath/nodes/subexpression'
18
+ require 'jmespath/nodes/and'
19
+ require 'jmespath/nodes/comparator'
20
+ require 'jmespath/nodes/comparator'
21
+ require 'jmespath/nodes/condition'
22
+ require 'jmespath/nodes/current'
23
+ require 'jmespath/nodes/expression'
24
+ require 'jmespath/nodes/field'
25
+ require 'jmespath/nodes/flatten'
26
+ require 'jmespath/nodes/function'
27
+ require 'jmespath/nodes/index'
28
+ require 'jmespath/nodes/literal'
29
+ require 'jmespath/nodes/multi_select_hash'
30
+ require 'jmespath/nodes/multi_select_list'
31
+ require 'jmespath/nodes/not'
32
+ require 'jmespath/nodes/or'
33
+ require 'jmespath/nodes/pipe'
34
+ require 'jmespath/nodes/projection'
35
+ require 'jmespath/nodes/projection'
36
+ require 'jmespath/nodes/projection'
37
+ require 'jmespath/nodes/slice'
20
38
 
21
- autoload :And, 'jmespath/nodes/and'
22
- autoload :Comparator, 'jmespath/nodes/comparator'
23
- autoload :Comparators, 'jmespath/nodes/comparator'
24
- autoload :Condition, 'jmespath/nodes/condition'
25
- autoload :Current, 'jmespath/nodes/current'
26
- autoload :Expression, 'jmespath/nodes/expression'
27
- autoload :Field, 'jmespath/nodes/field'
28
- autoload :Flatten, 'jmespath/nodes/flatten'
29
- autoload :Function, 'jmespath/nodes/function'
30
- autoload :Index, 'jmespath/nodes/index'
31
- autoload :Literal, 'jmespath/nodes/literal'
32
- autoload :MultiSelectHash, 'jmespath/nodes/multi_select_hash'
33
- autoload :MultiSelectList, 'jmespath/nodes/multi_select_list'
34
- autoload :Not, 'jmespath/nodes/not'
35
- autoload :Or, 'jmespath/nodes/or'
36
- autoload :Pipe, 'jmespath/nodes/pipe'
37
- autoload :Projection, 'jmespath/nodes/projection'
38
- autoload :ArrayProjection, 'jmespath/nodes/projection'
39
- autoload :ObjectProjection, 'jmespath/nodes/projection'
40
- autoload :Slice, 'jmespath/nodes/slice'
41
- autoload :Subexpression, 'jmespath/nodes/subexpression'
42
39
 
43
40
  end
44
41
  end
@@ -46,7 +46,7 @@ module JMESPath
46
46
 
47
47
  # @api private
48
48
  def method_missing(method_name, *args)
49
- if matches = method_name.match(/^(nud_|led_)(.*)/)
49
+ if matches = method_name.to_s.match(/^(nud_|led_)(.*)/)
50
50
  raise Errors::SyntaxError, "unexpected token #{matches[2]}"
51
51
  else
52
52
  super
@@ -59,7 +59,7 @@ module JMESPath
59
59
  # @param [Integer] rbp Right binding power
60
60
  def expr(stream, rbp = 0)
61
61
  left = send("nud_#{stream.token.type}", stream)
62
- while rbp < stream.token.binding_power
62
+ while rbp < (stream.token.binding_power || 0)
63
63
  left = send("led_#{stream.token.type}", stream, left)
64
64
  end
65
65
  left
@@ -155,6 +155,10 @@ module JMESPath
155
155
  parse_wildcard_object(stream, CURRENT_NODE)
156
156
  end
157
157
 
158
+ def nud_unknown(stream)
159
+ raise Errors::SyntaxError, "unknown token #{stream.token.value.inspect}"
160
+ end
161
+
158
162
  def led_comparator(stream, left)
159
163
  token = stream.token
160
164
  stream.next
data/lib/jmespath/util.rb CHANGED
@@ -8,15 +8,27 @@ module JMESPath
8
8
  # https://github.com/jmespath/jmespath.site/blob/master/docs/proposals/improved-filters.rst#and-expressions-1
9
9
  #
10
10
  def falsey?(value)
11
- value.nil? ||
12
- value === false ||
13
- value == '' ||
14
- value == {} ||
15
- value == [] ||
16
- (value.respond_to?(:entries) && value.entries.compact.empty?)
11
+ !value ||
12
+ (value.respond_to?(:to_ary) && value.to_ary.empty?) ||
13
+ (value.respond_to?(:to_hash) && value.to_hash.empty?) ||
14
+ (value.respond_to?(:to_str) && value.to_str.empty?) ||
15
+ (value.respond_to?(:entries) && !value.entries.any?)
17
16
  # final case necessary to support Enumerable and Struct
18
17
  end
19
18
 
19
+ def as_json(value)
20
+ if value.respond_to?(:to_ary)
21
+ value.to_ary.map { |e| as_json(e) }
22
+ elsif value.respond_to?(:to_hash)
23
+ hash = {}
24
+ value.to_hash.each_pair { |k, v| hash[k] = as_json(v) }
25
+ hash
26
+ elsif value.respond_to?(:to_str)
27
+ value.to_str
28
+ else
29
+ value
30
+ end
31
+ end
20
32
  end
21
33
  end
22
34
  end
@@ -1,3 +1,3 @@
1
1
  module JMESPath
2
- VERSION = '1.2.4'
2
+ VERSION = File.read(File.expand_path('../../../VERSION', __FILE__)).strip
3
3
  end
data/lib/jmespath.rb CHANGED
@@ -1,34 +1,19 @@
1
- if Object.const_defined?(:JSON) && JSON::VERSION < '1.8.1'
2
- warn("WARNING: jmespath gem requires json gem >= 1.8.1; json #{JSON::VERSION} already loaded")
3
- else
4
- begin
5
- # Attempt to load the native version if available, not availble
6
- # by default for Ruby 1.9.3.
7
- gem('json', '>= 1.8.1')
8
- require 'json'
9
- rescue Gem::LoadError
10
- # Fallback on the json_pure gem dependency.
11
- gem('json_pure', '>= 1.8.1')
12
- require 'json'
13
- end
14
- end
15
-
1
+ require 'json'
16
2
  require 'stringio'
17
3
  require 'pathname'
18
4
 
19
5
  module JMESPath
20
6
 
21
- autoload :CachingParser, 'jmespath/caching_parser'
22
- autoload :Errors, 'jmespath/errors'
23
- autoload :ExprNode, 'jmespath/expr_node'
24
- autoload :Lexer, 'jmespath/lexer'
25
- autoload :Nodes, 'jmespath/nodes'
26
- autoload :Parser, 'jmespath/parser'
27
- autoload :Runtime, 'jmespath/runtime'
28
- autoload :Token, 'jmespath/token'
29
- autoload :TokenStream, 'jmespath/token_stream'
30
- autoload :Util, 'jmespath/util'
31
- autoload :VERSION, 'jmespath/version'
7
+ require 'jmespath/caching_parser'
8
+ require 'jmespath/errors'
9
+ require 'jmespath/lexer'
10
+ require 'jmespath/nodes'
11
+ require 'jmespath/parser'
12
+ require 'jmespath/runtime'
13
+ require 'jmespath/token'
14
+ require 'jmespath/token_stream'
15
+ require 'jmespath/util'
16
+ require 'jmespath/version'
32
17
 
33
18
  class << self
34
19
 
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jmespath
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trevor Rowe
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-06 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: json_pure
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 1.8.1
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: 1.8.1
11
+ date: 2022-01-10 00:00:00.000000000 Z
12
+ dependencies: []
27
13
  description: Implements JMESPath for Ruby
28
14
  email: trevorrowe@gmail.com
29
15
  executables: []
@@ -31,6 +17,7 @@ extensions: []
31
17
  extra_rdoc_files: []
32
18
  files:
33
19
  - LICENSE.txt
20
+ - VERSION
34
21
  - lib/jmespath.rb
35
22
  - lib/jmespath/caching_parser.rb
36
23
  - lib/jmespath/errors.rb
@@ -62,9 +49,9 @@ files:
62
49
  - lib/jmespath/version.rb
63
50
  homepage: http://github.com/trevorrowe/jmespath.rb
64
51
  licenses:
65
- - Apache 2.0
52
+ - Apache-2.0
66
53
  metadata: {}
67
- post_install_message:
54
+ post_install_message:
68
55
  rdoc_options: []
69
56
  require_paths:
70
57
  - lib
@@ -79,10 +66,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
66
  - !ruby/object:Gem::Version
80
67
  version: '0'
81
68
  requirements: []
82
- rubyforge_project:
83
- rubygems_version: 2.4.5
84
- signing_key:
69
+ rubygems_version: 3.2.7
70
+ signing_key:
85
71
  specification_version: 4
86
72
  summary: JMESPath - Ruby Edition
87
73
  test_files: []
88
- has_rdoc: