jmespath-ruby 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +18 -0
- data/CONTRIBUTING.md +57 -0
- data/LICENSE +21 -0
- data/LICENSES/python-MIT.txt +21 -0
- data/LICENSES/ruby-Apache-2.0.txt +174 -0
- data/README.md +122 -0
- data/SECURITY.md +16 -0
- data/VERSIONING.md +12 -0
- data/docs/guides/compatibility.md +84 -0
- data/docs/guides/compilation.md +63 -0
- data/docs/guides/errors.md +30 -0
- data/docs/guides/functions.md +65 -0
- data/docs/guides/performance.md +237 -0
- data/docs/guides/search.md +56 -0
- data/exe/jmespath +5 -0
- data/exe/jmespath.rb +5 -0
- data/lib/jmespath/ast.rb +43 -0
- data/lib/jmespath/cache.rb +53 -0
- data/lib/jmespath/cli.rb +36 -0
- data/lib/jmespath/data_access.rb +66 -0
- data/lib/jmespath/errors.rb +53 -0
- data/lib/jmespath/evaluation/construction.rb +20 -0
- data/lib/jmespath/evaluation/logic.rb +42 -0
- data/lib/jmespath/evaluation/projections.rb +43 -0
- data/lib/jmespath/evaluation/scalars.rb +49 -0
- data/lib/jmespath/evaluation/slices.rb +50 -0
- data/lib/jmespath/evaluator.rb +37 -0
- data/lib/jmespath/expression.rb +63 -0
- data/lib/jmespath/expression_reference.rb +15 -0
- data/lib/jmespath/functions/coercions.rb +41 -0
- data/lib/jmespath/functions/collections.rb +84 -0
- data/lib/jmespath/functions/conversion.rb +32 -0
- data/lib/jmespath/functions/function_call.rb +32 -0
- data/lib/jmespath/functions/references.rb +62 -0
- data/lib/jmespath/functions/scalar.rb +74 -0
- data/lib/jmespath/functions/signature.rb +77 -0
- data/lib/jmespath/functions.rb +73 -0
- data/lib/jmespath/input.rb +19 -0
- data/lib/jmespath/lexer.rb +132 -0
- data/lib/jmespath/normalizer.rb +53 -0
- data/lib/jmespath/options.rb +67 -0
- data/lib/jmespath/parser/expressions.rb +70 -0
- data/lib/jmespath/parser/projections.rb +91 -0
- data/lib/jmespath/parser.rb +119 -0
- data/lib/jmespath/plan.rb +153 -0
- data/lib/jmespath/token.rb +6 -0
- data/lib/jmespath/types.rb +84 -0
- data/lib/jmespath/version.rb +7 -0
- data/lib/jmespath.rb +100 -0
- data/sig/jmespath.rbs +55 -0
- metadata +135 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JMESPath
|
|
4
|
+
# @api private
|
|
5
|
+
module Plan
|
|
6
|
+
BUILDERS = {
|
|
7
|
+
field: :field, current: :current, group: :group,
|
|
8
|
+
subexpression: :sequence, pipe: :sequence, index: :index,
|
|
9
|
+
multi_select_list: :list, projection: :projection,
|
|
10
|
+
value_projection: :value_projection, slice: :slice, function: :function,
|
|
11
|
+
expression_reference: :reference
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
def self.build(node, options = Options::DEFAULT)
|
|
15
|
+
Builder.new(options).build(node)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @api private
|
|
19
|
+
class Builder
|
|
20
|
+
def initialize(options)
|
|
21
|
+
@functions = options.functions
|
|
22
|
+
@disable_visit_errors = options.disable_visit_errors
|
|
23
|
+
@evaluator = if @functions.equal?(Functions.default) && !@disable_visit_errors
|
|
24
|
+
Expression::DEFAULT_EVALUATOR
|
|
25
|
+
else
|
|
26
|
+
Evaluator.new(functions: @functions, disable_visit_errors: @disable_visit_errors)
|
|
27
|
+
end
|
|
28
|
+
freeze
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def build(node)
|
|
32
|
+
builder = BUILDERS[node.kind]
|
|
33
|
+
(builder ? send(builder, node) : fallback(node)).freeze
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def field(node)
|
|
39
|
+
DataAccess::FieldReader.new(node.value.to_s)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def current(_node)
|
|
43
|
+
->(data) { data }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def group(node)
|
|
47
|
+
build(node.children.fetch(0))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def sequence(node)
|
|
51
|
+
children = node.children.map { |child| build(child) }.freeze
|
|
52
|
+
lambda do |data|
|
|
53
|
+
children.each { |child| data = child.call(data) }
|
|
54
|
+
data
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def index(node)
|
|
59
|
+
child = build(node.children.fetch(0))
|
|
60
|
+
position = Integer(node.value) # : Integer
|
|
61
|
+
lambda do |data|
|
|
62
|
+
values = DataAccess.array(child.call(data))
|
|
63
|
+
values[position] if values && position.between?(-values.length, values.length - 1)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def list(node)
|
|
68
|
+
children = node.children.map { |child| build(child) }.freeze
|
|
69
|
+
->(data) { children.map { |child| child.call(data) } unless data.nil? }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def projection(node)
|
|
73
|
+
child = build(node.children.fetch(0))
|
|
74
|
+
project = projector(node.children.fetch(1))
|
|
75
|
+
->(data) { project.call(DataAccess.array(child.call(data))) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def value_projection(node)
|
|
79
|
+
child = build(node.children.fetch(0))
|
|
80
|
+
project = projector(node.children.fetch(1))
|
|
81
|
+
->(data) { project.call(DataAccess.object(child.call(data))&.values) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def projector(node)
|
|
85
|
+
child = build(node)
|
|
86
|
+
lambda do |values|
|
|
87
|
+
if values
|
|
88
|
+
result = values.map { |value| child.call(value) }
|
|
89
|
+
result.compact!
|
|
90
|
+
result
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def slice(node)
|
|
96
|
+
child = build(node.children.fetch(0))
|
|
97
|
+
start, stop, step = Array(node.value).map { |part| part.nil? ? nil : Integer(part) }
|
|
98
|
+
slice = Slice.new(start: start, stop: stop, step: step).freeze
|
|
99
|
+
lambda do |data|
|
|
100
|
+
values = DataAccess.array(child.call(data))
|
|
101
|
+
slice.apply(values) if values
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def function(node)
|
|
106
|
+
name = node.value.to_s
|
|
107
|
+
unless !@disable_visit_errors && %w[length reverse].include?(name) && node.children.length == 1 &&
|
|
108
|
+
native_function?(name)
|
|
109
|
+
return function_call(name, node.children)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
string_function(name, build(node.children.fetch(0)))
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def native_function?(name)
|
|
116
|
+
@functions.instance_of?(Functions) && @functions.definition(name).equal?(Functions.default.definition(name))
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def string_function(name, child)
|
|
120
|
+
lambda do |data|
|
|
121
|
+
value = child.call(data)
|
|
122
|
+
if value.is_a?(String)
|
|
123
|
+
name == "length" ? value.length : value.reverse
|
|
124
|
+
else
|
|
125
|
+
Functions.default.call(name, [value])
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def fallback(node)
|
|
131
|
+
evaluator = @evaluator
|
|
132
|
+
->(data) { evaluator.evaluate(node, data) }
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def function_call(name, nodes)
|
|
136
|
+
arguments = nodes.map { |node| build(node) }.freeze
|
|
137
|
+
functions = @functions
|
|
138
|
+
if @disable_visit_errors
|
|
139
|
+
lambda do |data|
|
|
140
|
+
functions.call(name, arguments.map { |argument| argument.call(data) }, disable_visit_errors: true)
|
|
141
|
+
end
|
|
142
|
+
else
|
|
143
|
+
->(data) { functions.call(name, arguments.map { |argument| argument.call(data) }) }
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def reference(node)
|
|
148
|
+
operation = build(node.children.fetch(0))
|
|
149
|
+
->(_data) { ExpressionReference.new { |value| operation.call(value) } }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JMESPath
|
|
4
|
+
# @api private
|
|
5
|
+
module Types
|
|
6
|
+
class << self
|
|
7
|
+
def name(value)
|
|
8
|
+
case value
|
|
9
|
+
when Integer then :number
|
|
10
|
+
when String then :string
|
|
11
|
+
when NilClass then :null
|
|
12
|
+
when TrueClass, FalseClass then :boolean
|
|
13
|
+
else other_name(value)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def number?(value)
|
|
18
|
+
value.is_a?(Integer) || (value.is_a?(Float) && value.finite?)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def falsey?(value)
|
|
22
|
+
return true if value.nil? || value.equal?(false)
|
|
23
|
+
return false if value.equal?(true)
|
|
24
|
+
|
|
25
|
+
collection = DataAccess.string(value) || DataAccess.array(value) || DataAccess.object(value)
|
|
26
|
+
collection ? collection.empty? : false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def equal?(left, right)
|
|
30
|
+
pending = [[normalize(left), normalize(right)]]
|
|
31
|
+
while (pair = pending.pop)
|
|
32
|
+
return false unless matching?(pair.fetch(0), pair.fetch(1), pending)
|
|
33
|
+
end
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def normalize(value)
|
|
38
|
+
Normalizer.new.call(value)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def other_name(value)
|
|
44
|
+
return :number if number?(value)
|
|
45
|
+
return :expref if value.is_a?(ExpressionReference)
|
|
46
|
+
|
|
47
|
+
collection_name(value)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def collection_name(value)
|
|
51
|
+
return :string if DataAccess.string(value)
|
|
52
|
+
return :array if DataAccess.array(value)
|
|
53
|
+
return :object if DataAccess.object(value)
|
|
54
|
+
|
|
55
|
+
:unknown
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def matching?(left, right, pending)
|
|
59
|
+
case left
|
|
60
|
+
when Array then arrays_match?(left, right, pending)
|
|
61
|
+
when Hash then objects_match?(left, right, pending)
|
|
62
|
+
else left == right
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def arrays_match?(left, right, pending)
|
|
67
|
+
return false unless right.is_a?(Array) && left.length == right.length
|
|
68
|
+
|
|
69
|
+
left.each_with_index { |value, index| pending << [value, right[index]] }
|
|
70
|
+
true
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def objects_match?(left, right, pending)
|
|
74
|
+
return false unless right.is_a?(Hash) && left.length == right.length
|
|
75
|
+
return false unless left.each_key.all? { |key| right.key?(key) }
|
|
76
|
+
|
|
77
|
+
left.each { |key, value| pending << [value, right[key]] }
|
|
78
|
+
true
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
require_relative "normalizer"
|
data/lib/jmespath.rb
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "jmespath/version"
|
|
4
|
+
require_relative "jmespath/errors"
|
|
5
|
+
require_relative "jmespath/token"
|
|
6
|
+
require_relative "jmespath/lexer"
|
|
7
|
+
require_relative "jmespath/expression_reference"
|
|
8
|
+
require_relative "jmespath/data_access"
|
|
9
|
+
require_relative "jmespath/types"
|
|
10
|
+
require_relative "jmespath/ast"
|
|
11
|
+
require_relative "jmespath/parser"
|
|
12
|
+
require_relative "jmespath/functions"
|
|
13
|
+
require_relative "jmespath/evaluator"
|
|
14
|
+
require_relative "jmespath/functions/scalar"
|
|
15
|
+
require_relative "jmespath/functions/collections"
|
|
16
|
+
require_relative "jmespath/functions/function_call"
|
|
17
|
+
require_relative "jmespath/options"
|
|
18
|
+
require_relative "jmespath/input"
|
|
19
|
+
require_relative "jmespath/cache"
|
|
20
|
+
require_relative "jmespath/plan"
|
|
21
|
+
require_relative "jmespath/expression"
|
|
22
|
+
|
|
23
|
+
# Search JSON-compatible Ruby values with JMESPath expressions.
|
|
24
|
+
module JMESPath
|
|
25
|
+
# @api private
|
|
26
|
+
CACHE = Cache.new
|
|
27
|
+
private_constant :CACHE
|
|
28
|
+
|
|
29
|
+
class << self
|
|
30
|
+
# Search Ruby data using a JMESPath expression.
|
|
31
|
+
# @param expression [String] query text
|
|
32
|
+
# @param data [Object] Ruby values, Pathname, IO, or StringIO
|
|
33
|
+
# @param options [Hash] positional compatibility options
|
|
34
|
+
# @param keywords [Hash] keyword evaluation options
|
|
35
|
+
# @option options [Boolean] :cache_expressions (true) reuse cached syntax
|
|
36
|
+
# @option options [Boolean] :disable_visit_errors (false) suppress argument type and arity failures
|
|
37
|
+
# @option options [Functions] :functions (Functions.default) registry for this search
|
|
38
|
+
# @option options [Integer] :max_depth (128) maximum expression nesting
|
|
39
|
+
# @raise [ArgumentError] options or expression type are invalid
|
|
40
|
+
# @raise [Errors::Error] the query cannot be parsed or evaluated
|
|
41
|
+
# @example Project a field from each item
|
|
42
|
+
# JMESPath.search("items[*].name", {items: [{name: "Ada"}]}) #=> ["Ada"]
|
|
43
|
+
# @return [Object] the query result, including nil
|
|
44
|
+
def search(expression, data, options = Options::EMPTY, **keywords)
|
|
45
|
+
config = if options.equal?(Options::EMPTY) && keywords.empty?
|
|
46
|
+
Options::DEFAULT
|
|
47
|
+
else
|
|
48
|
+
Options.new(options, keywords)
|
|
49
|
+
end
|
|
50
|
+
raise ArgumentError, "Expression must be a String" unless expression.is_a?(String)
|
|
51
|
+
|
|
52
|
+
compiled = compile_syntax(expression, config.cache_expressions, config.max_depth)
|
|
53
|
+
compiled.evaluate(Input.load(data), config)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Parse an expression for repeated searches.
|
|
57
|
+
# @param expression [String] query text
|
|
58
|
+
# @param cache_expressions [Boolean] reuse bounded cached syntax
|
|
59
|
+
# @param max_depth [Integer] maximum nesting from 1 through 128
|
|
60
|
+
# @param functions [Functions] default registry for searches with this expression
|
|
61
|
+
# @param disable_visit_errors [Boolean] default suppression of argument type and arity failures
|
|
62
|
+
# @raise [ArgumentError] expression type or options are invalid
|
|
63
|
+
# @raise [Errors::SyntaxError] the expression is invalid or exceeds its nesting limit
|
|
64
|
+
# @example Reuse parsed syntax
|
|
65
|
+
# JMESPath.compile("name").search({name: "Ada"}) #=> "Ada"
|
|
66
|
+
# @return [Expression] immutable reusable syntax
|
|
67
|
+
def compile(expression, cache_expressions: true, max_depth: 128,
|
|
68
|
+
functions: Functions.default, disable_visit_errors: false)
|
|
69
|
+
raise ArgumentError, "Expression must be a String" unless expression.is_a?(String)
|
|
70
|
+
|
|
71
|
+
config = compilation_options(cache_expressions, max_depth, functions, disable_visit_errors)
|
|
72
|
+
compiled = compile_syntax(expression, cache_expressions, max_depth)
|
|
73
|
+
config.equal?(Options::DEFAULT) ? compiled : compiled.configured(config)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def compile_syntax(expression, cache, depth)
|
|
79
|
+
if cache
|
|
80
|
+
CACHE.fetch(expression, max_depth: depth) { |source| build_expression(source, depth) }
|
|
81
|
+
else
|
|
82
|
+
build_expression(expression, depth)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def compilation_options(cache, depth, functions, suppress)
|
|
87
|
+
if cache.equal?(true) && depth.equal?(128) && functions.equal?(Functions.default) && suppress.equal?(false)
|
|
88
|
+
return Options::DEFAULT
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
Options.new({ cache_expressions: cache, max_depth: depth,
|
|
92
|
+
functions: functions, disable_visit_errors: suppress })
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def build_expression(expression, max_depth)
|
|
96
|
+
source = expression.dup.freeze
|
|
97
|
+
Expression.new(source, Parser.new(source, max_depth: max_depth).parse, max_depth: max_depth)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
data/sig/jmespath.rbs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module JMESPath
|
|
2
|
+
VERSION: String
|
|
3
|
+
type value = Object?
|
|
4
|
+
type json = nil | bool | Integer | Float | String | Array[json] | Hash[String, json]
|
|
5
|
+
|
|
6
|
+
def self.search: (String, value, ?Hash[Symbol, value], **value) -> value
|
|
7
|
+
def self.compile: (String, ?cache_expressions: bool, ?max_depth: Integer, ?functions: Functions, ?disable_visit_errors: bool) -> Expression
|
|
8
|
+
|
|
9
|
+
module Errors
|
|
10
|
+
class Error < StandardError
|
|
11
|
+
end
|
|
12
|
+
class RuntimeError < Error
|
|
13
|
+
end
|
|
14
|
+
class SyntaxError < Error
|
|
15
|
+
attr_reader expression: String
|
|
16
|
+
attr_reader position: Integer
|
|
17
|
+
def initialize: (String, ?expression: String, ?position: Integer) -> void
|
|
18
|
+
def line: () -> Integer
|
|
19
|
+
def column: () -> Integer
|
|
20
|
+
end
|
|
21
|
+
class InvalidTypeError < RuntimeError
|
|
22
|
+
end
|
|
23
|
+
class InvalidValueError < RuntimeError
|
|
24
|
+
end
|
|
25
|
+
class InvalidArityError < RuntimeError
|
|
26
|
+
end
|
|
27
|
+
class UnknownFunctionError < RuntimeError
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Expression
|
|
32
|
+
attr_reader source: String
|
|
33
|
+
def search: (value, ?Hash[Symbol, value], **value) -> value
|
|
34
|
+
alias call search
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Functions
|
|
38
|
+
def initialize: () -> void
|
|
39
|
+
def self.default: () -> Functions
|
|
40
|
+
def with: (String, signature: Array[Array[Symbol]], ?variadic: bool, ?override: bool) ?{ (*value) -> value } -> Functions
|
|
41
|
+
def call: (String, Array[value], ?disable_visit_errors: bool) -> value
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Input stream protocol used by CLI.run.
|
|
45
|
+
interface _Reader
|
|
46
|
+
def read: () -> String?
|
|
47
|
+
end
|
|
48
|
+
# Output stream protocol used by CLI.run.
|
|
49
|
+
interface _Writer
|
|
50
|
+
def puts: (String) -> void
|
|
51
|
+
end
|
|
52
|
+
module CLI
|
|
53
|
+
def self.run: (Array[String], ?stdin: _Reader, ?stdout: _Writer, ?stderr: _Writer) -> Integer
|
|
54
|
+
end
|
|
55
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jmespath-ruby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Leonid Svyatov
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: json
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.7'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '4'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '2.7'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '4'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: stringio
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '3.0'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '4'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '3.0'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '4'
|
|
52
|
+
description: Search structured Ruby data with reusable JMESPath expressions.
|
|
53
|
+
executables:
|
|
54
|
+
- jmespath
|
|
55
|
+
- jmespath.rb
|
|
56
|
+
extensions: []
|
|
57
|
+
extra_rdoc_files: []
|
|
58
|
+
files:
|
|
59
|
+
- CHANGELOG.md
|
|
60
|
+
- CONTRIBUTING.md
|
|
61
|
+
- LICENSE
|
|
62
|
+
- LICENSES/python-MIT.txt
|
|
63
|
+
- LICENSES/ruby-Apache-2.0.txt
|
|
64
|
+
- README.md
|
|
65
|
+
- SECURITY.md
|
|
66
|
+
- VERSIONING.md
|
|
67
|
+
- docs/guides/compatibility.md
|
|
68
|
+
- docs/guides/compilation.md
|
|
69
|
+
- docs/guides/errors.md
|
|
70
|
+
- docs/guides/functions.md
|
|
71
|
+
- docs/guides/performance.md
|
|
72
|
+
- docs/guides/search.md
|
|
73
|
+
- exe/jmespath
|
|
74
|
+
- exe/jmespath.rb
|
|
75
|
+
- lib/jmespath.rb
|
|
76
|
+
- lib/jmespath/ast.rb
|
|
77
|
+
- lib/jmespath/cache.rb
|
|
78
|
+
- lib/jmespath/cli.rb
|
|
79
|
+
- lib/jmespath/data_access.rb
|
|
80
|
+
- lib/jmespath/errors.rb
|
|
81
|
+
- lib/jmespath/evaluation/construction.rb
|
|
82
|
+
- lib/jmespath/evaluation/logic.rb
|
|
83
|
+
- lib/jmespath/evaluation/projections.rb
|
|
84
|
+
- lib/jmespath/evaluation/scalars.rb
|
|
85
|
+
- lib/jmespath/evaluation/slices.rb
|
|
86
|
+
- lib/jmespath/evaluator.rb
|
|
87
|
+
- lib/jmespath/expression.rb
|
|
88
|
+
- lib/jmespath/expression_reference.rb
|
|
89
|
+
- lib/jmespath/functions.rb
|
|
90
|
+
- lib/jmespath/functions/coercions.rb
|
|
91
|
+
- lib/jmespath/functions/collections.rb
|
|
92
|
+
- lib/jmespath/functions/conversion.rb
|
|
93
|
+
- lib/jmespath/functions/function_call.rb
|
|
94
|
+
- lib/jmespath/functions/references.rb
|
|
95
|
+
- lib/jmespath/functions/scalar.rb
|
|
96
|
+
- lib/jmespath/functions/signature.rb
|
|
97
|
+
- lib/jmespath/input.rb
|
|
98
|
+
- lib/jmespath/lexer.rb
|
|
99
|
+
- lib/jmespath/normalizer.rb
|
|
100
|
+
- lib/jmespath/options.rb
|
|
101
|
+
- lib/jmespath/parser.rb
|
|
102
|
+
- lib/jmespath/parser/expressions.rb
|
|
103
|
+
- lib/jmespath/parser/projections.rb
|
|
104
|
+
- lib/jmespath/plan.rb
|
|
105
|
+
- lib/jmespath/token.rb
|
|
106
|
+
- lib/jmespath/types.rb
|
|
107
|
+
- lib/jmespath/version.rb
|
|
108
|
+
- sig/jmespath.rbs
|
|
109
|
+
homepage: https://github.com/svyatov/jmespath-ruby
|
|
110
|
+
licenses:
|
|
111
|
+
- MIT
|
|
112
|
+
metadata:
|
|
113
|
+
rubygems_mfa_required: 'true'
|
|
114
|
+
allowed_push_host: https://rubygems.org
|
|
115
|
+
source_code_uri: https://github.com/svyatov/jmespath-ruby
|
|
116
|
+
bug_tracker_uri: https://github.com/svyatov/jmespath-ruby/issues
|
|
117
|
+
changelog_uri: https://github.com/svyatov/jmespath-ruby/blob/main/CHANGELOG.md
|
|
118
|
+
rdoc_options: []
|
|
119
|
+
require_paths:
|
|
120
|
+
- lib
|
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
|
+
requirements:
|
|
123
|
+
- - ">="
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '3.3'
|
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - ">="
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '0'
|
|
131
|
+
requirements: []
|
|
132
|
+
rubygems_version: 4.0.20
|
|
133
|
+
specification_version: 4
|
|
134
|
+
summary: A typed Ruby implementation of the JMESPath query language
|
|
135
|
+
test_files: []
|