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 +5 -5
- data/VERSION +1 -0
- data/lib/jmespath/lexer.rb +61 -5
- data/lib/jmespath/nodes/comparator.rb +22 -6
- data/lib/jmespath/nodes/condition.rb +4 -4
- data/lib/jmespath/nodes/field.rb +8 -6
- data/lib/jmespath/nodes/flatten.rb +4 -4
- data/lib/jmespath/nodes/function.rb +91 -56
- data/lib/jmespath/nodes/projection.rb +5 -3
- data/lib/jmespath/nodes/slice.rb +3 -3
- data/lib/jmespath/nodes.rb +22 -25
- data/lib/jmespath/parser.rb +6 -2
- data/lib/jmespath/util.rb +18 -6
- data/lib/jmespath/version.rb +1 -1
- data/lib/jmespath.rb +11 -26
- metadata +9 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 802d17af3f269cfbd38879ff753082257effba66f383f415667b1018d9d68c5c
|
4
|
+
data.tar.gz: 3b9ec8bf65b3dbcf00273667510385a406fa2c23cd64890557a76263944a8b0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c95fe346be9e1e36a67869cad050a03e74ae414ceedb09049210419a9d4c5455df38e49403bcedf1434b56e8b45d6142527bdb3d2af86919cc833da021251e16
|
7
|
+
data.tar.gz: 73e3c073ccf6b57c65c2246d12fd4a3c5d5f3beb603772966c4ec92371f9ed10f4e1a10b66a1619f50fdd78137a1a6b0998f65b4e7f966a928e5fc2a8d7393be
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.5.0
|
data/lib/jmespath/lexer.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
325
|
+
JSON.load('false')
|
301
326
|
rescue JSON::ParserError
|
302
|
-
|
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?(
|
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?(
|
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?(
|
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?(
|
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
|
|
data/lib/jmespath/nodes/field.rb
CHANGED
@@ -8,9 +8,10 @@ module JMESPath
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def visit(value)
|
11
|
-
if value.
|
12
|
-
value[@key]
|
13
|
-
elsif value.
|
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.
|
52
|
-
value[key]
|
53
|
-
elsif value.
|
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
|
12
|
-
value.each_with_object([]) do |v, values|
|
13
|
-
if
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
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
|
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
|
-
|
185
|
-
|
186
|
-
|
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
|
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
|
-
|
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
|
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
|
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
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
340
|
+
if value.respond_to?(:to_hash)
|
341
|
+
value.to_hash.values
|
342
|
+
elsif value.is_a?(Struct)
|
326
343
|
value.values
|
327
|
-
elsif
|
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 !(
|
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
|
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
|
-
|
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 &&
|
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
|
427
|
-
value
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
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
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
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
|
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
|
-
|
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
|
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
|
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
|
data/lib/jmespath/nodes/slice.rb
CHANGED
@@ -10,7 +10,7 @@ module JMESPath
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def visit(value)
|
13
|
-
if
|
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
|
-
|
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
|
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
|
data/lib/jmespath/nodes.rb
CHANGED
@@ -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
|
data/lib/jmespath/parser.rb
CHANGED
@@ -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
|
12
|
-
value
|
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
|
data/lib/jmespath/version.rb
CHANGED
data/lib/jmespath.rb
CHANGED
@@ -1,34 +1,19 @@
|
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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.
|
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:
|
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
|
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
|
-
|
83
|
-
|
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:
|