jmespath-ruby 0.1.2 → 0.1.3

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -1
  3. data/README.md +177 -4
  4. data/completions/_jmespath +50 -0
  5. data/completions/jmespath.bash +178 -0
  6. data/docs/guides/compilation.md +310 -0
  7. data/docs/guides/completion.md +69 -0
  8. data/docs/guides/errors.md +200 -3
  9. data/docs/guides/functions.md +33 -0
  10. data/docs/guides/search.md +23 -0
  11. data/lib/jmespath/ast.rb +6 -1
  12. data/lib/jmespath/cli/argument_parser.rb +31 -0
  13. data/lib/jmespath/cli/arguments.rb +80 -0
  14. data/lib/jmespath/cli/failure_diagnostic.rb +1 -0
  15. data/lib/jmespath/cli/function_listing.rb +48 -0
  16. data/lib/jmespath/cli/help.rb +43 -0
  17. data/lib/jmespath/cli/interactive_session.rb +106 -0
  18. data/lib/jmespath/cli.rb +112 -16
  19. data/lib/jmespath/data_access.rb +12 -9
  20. data/lib/jmespath/diagnostic.rb +4 -3
  21. data/lib/jmespath/errors.rb +14 -0
  22. data/lib/jmespath/explanation.rb +95 -0
  23. data/lib/jmespath/expression.rb +93 -7
  24. data/lib/jmespath/failure_capture.rb +65 -0
  25. data/lib/jmespath/functions/coercions.rb +12 -5
  26. data/lib/jmespath/functions/conversion.rb +19 -1
  27. data/lib/jmespath/functions/function_call.rb +1 -1
  28. data/lib/jmespath/functions/json_value.rb +50 -0
  29. data/lib/jmespath/functions/references.rb +11 -10
  30. data/lib/jmespath/functions/signature.rb +6 -4
  31. data/lib/jmespath/functions.rb +12 -6
  32. data/lib/jmespath/input.rb +37 -0
  33. data/lib/jmespath/normalizer.rb +22 -5
  34. data/lib/jmespath/parser/projections.rb +5 -5
  35. data/lib/jmespath/parser.rb +2 -2
  36. data/lib/jmespath/plan.rb +17 -2
  37. data/lib/jmespath/search_result.rb +23 -0
  38. data/lib/jmespath/syntax_diagnostic.rb +32 -0
  39. data/lib/jmespath/tracing/collector.rb +109 -0
  40. data/lib/jmespath/tracing/evaluator.rb +113 -0
  41. data/lib/jmespath/tracing/field_lookup.rb +49 -0
  42. data/lib/jmespath/version.rb +1 -1
  43. data/lib/jmespath.rb +43 -8
  44. data/sig/jmespath.rbs +47 -3
  45. metadata +17 -1
@@ -65,10 +65,10 @@ module JMESPath
65
65
  node(kind, nil, children)
66
66
  end
67
67
 
68
- def node(kind, value = nil, children = [], start: nil)
68
+ def node(kind, value = nil, children = [], start: nil, synthetic: false)
69
69
  result = AST::Node.new(
70
70
  kind: kind, value: value, children: children,
71
- start: start || children.first&.start || previous.start, finish: previous.finish
71
+ start: start || children.first&.start || previous.start, finish: previous.finish, synthetic: synthetic
72
72
  )
73
73
  syntax!("Expression exceeds nesting limit") if result.depth > @max_depth
74
74
  result
data/lib/jmespath/plan.rb CHANGED
@@ -12,12 +12,20 @@ module JMESPath
12
12
  }.freeze
13
13
 
14
14
  def self.build(node, options = Options::DEFAULT)
15
- Builder.new(options).build(node)
15
+ builder = Builder.new(options)
16
+ operation = builder.build(node)
17
+ native_functions = builder.native_functions&.freeze
18
+ builder.freeze
19
+ yield native_functions
20
+ operation
16
21
  end
17
22
 
18
23
  # @api private
19
24
  class Builder
25
+ attr_reader :native_functions
26
+
20
27
  def initialize(options)
28
+ @native_functions = nil
21
29
  @functions = options.functions
22
30
  @disable_visit_errors = options.disable_visit_errors
23
31
  @evaluator = if @functions.equal?(Functions.default) && !@disable_visit_errors
@@ -25,7 +33,6 @@ module JMESPath
25
33
  else
26
34
  Evaluator.new(functions: @functions, disable_visit_errors: @disable_visit_errors)
27
35
  end
28
- freeze
29
36
  end
30
37
 
31
38
  def build(node)
@@ -110,6 +117,14 @@ module JMESPath
110
117
  return function_call(name, node.children, source_range)
111
118
  end
112
119
 
120
+ build_native_string(node, name, source_range)
121
+ end
122
+
123
+ def build_native_string(node, name, source_range)
124
+ # @type var native_functions: Array[AST::Node]
125
+ native_functions = @native_functions || []
126
+ native_functions << node
127
+ @native_functions = native_functions
113
128
  string_function(name, build(node.children.fetch(0)), source_range)
114
129
  end
115
130
 
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JMESPath
4
+ # Immutable outcome of an expression search, retaining the original value or error.
5
+ class SearchResult
6
+ # @return [Object] the successful value, or nil on failure
7
+ attr_reader :value
8
+ # @return [StandardError, nil] the original library-owned failure
9
+ attr_reader :error
10
+
11
+ # @api private
12
+ def initialize(value:, error:)
13
+ @value = value
14
+ @error = error
15
+ freeze
16
+ end
17
+
18
+ # @return [Boolean] whether evaluation succeeded, including a null result
19
+ def success?
20
+ error.nil?
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JMESPath
4
+ # Immutable syntax failure data returned by {JMESPath.validate}.
5
+ class SyntaxDiagnostic
6
+ # @return [String] reason without coordinates
7
+ attr_reader :reason
8
+ # @return [String] expression stored by the parser
9
+ attr_reader :expression
10
+ # @return [Integer, nil] zero-based byte offset, or nil for unknown locations
11
+ attr_reader :position
12
+ # @return [Integer, nil] one-based line, or nil for unknown locations
13
+ attr_reader :line
14
+ # @return [Integer, nil] one-based Unicode character column, or nil for unknown locations
15
+ attr_reader :column
16
+
17
+ # @api private
18
+ def initialize(error)
19
+ @reason = error.reason.dup.freeze
20
+ @expression = error.expression.dup.freeze
21
+ @position = error.position if error.location_known?
22
+ @line = error.line if error.location_known?
23
+ @column = error.column if error.location_known?
24
+ freeze
25
+ end
26
+
27
+ # @return [Boolean] whether parsing reported a source location
28
+ def location_known?
29
+ !position.nil?
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JMESPath
4
+ # @api private
5
+ module Tracing
6
+ # @api private
7
+ class Collector
8
+ def initialize(root:, limit:)
9
+ @ids = {} # : Hash[AST::Node, Integer]
10
+ .compare_by_identity
11
+ index(root)
12
+ @limit = limit
13
+ @events = []
14
+ @contexts = {}
15
+ @references = {}
16
+ @truncated = false
17
+ @closed = false
18
+ @mutex = Mutex.new
19
+ end
20
+
21
+ def operation_id(node)
22
+ @ids.fetch(node)
23
+ end
24
+
25
+ def within(node, index)
26
+ thread = Thread.current
27
+ stack = @mutex.synchronize do
28
+ unless @closed
29
+ context = (@contexts[thread] ||= [])
30
+ # @type var frame: trace_context
31
+ frame = { operation_id: operation_id(node), index: index }.freeze
32
+ context << frame
33
+ context
34
+ end
35
+ end
36
+ return yield unless stack
37
+
38
+ begin
39
+ yield
40
+ ensure
41
+ @mutex.synchronize do
42
+ stack.pop
43
+ @contexts.delete(thread) if stack.empty?
44
+ end
45
+ end
46
+ end
47
+
48
+ def reference(node, &)
49
+ index = @mutex.synchronize do
50
+ unless @closed
51
+ id = operation_id(node)
52
+ count = @references.fetch(id, 0)
53
+ @references[id] = count + 1
54
+ count
55
+ end
56
+ end
57
+ return yield if index.nil?
58
+
59
+ within(node, index, &)
60
+ end
61
+
62
+ def emit(type, node, details = {})
63
+ @mutex.synchronize do
64
+ return if @closed
65
+
66
+ if @events.length >= @limit
67
+ @truncated = true
68
+ return
69
+ end
70
+ # @type var event: trace_event
71
+ event = {
72
+ type: type.dup.freeze, operation_id: operation_id(node),
73
+ context: @contexts.fetch(Thread.current, []).dup.freeze,
74
+ details: details.transform_values { |value| value.dup.freeze }.freeze
75
+ }.freeze
76
+ @events << event
77
+ end
78
+ end
79
+
80
+ def finish(value)
81
+ @mutex.synchronize do
82
+ # @type var report: trace_report
83
+ report = { value: value, events: @events.freeze, truncated: @truncated }.freeze
84
+ clear
85
+ report
86
+ end
87
+ end
88
+
89
+ def close
90
+ @mutex.synchronize { clear }
91
+ end
92
+
93
+ private
94
+
95
+ def index(node)
96
+ @ids[node] = @ids.length
97
+ Explanation.syntax_children(node).each { |child| index(child) }
98
+ end
99
+
100
+ def clear
101
+ @closed = true
102
+ @ids.clear
103
+ @contexts.clear
104
+ @references.clear
105
+ @events = []
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JMESPath
4
+ module Tracing
5
+ # @api private
6
+ class Evaluator < JMESPath::Evaluator
7
+ def initialize(config:, collector:, root:, planned:, native_functions:)
8
+ @collector = collector
9
+ @native_functions = planned ? native_functions : nil
10
+ @compiled_functions = {} # : Hash[AST::Node, bool]
11
+ .compare_by_identity
12
+ index_plan(root) if planned
13
+ @compiled_functions.freeze
14
+ super(functions: config.functions, disable_visit_errors: config.disable_visit_errors)
15
+ end
16
+
17
+ def evaluate(node, data)
18
+ return super unless node.kind == :field
19
+
20
+ result, reason = FieldLookup.call(data, node.value.to_s)
21
+ @collector.emit("field_null", node, name: node.value.to_s, reason: reason) if reason
22
+ result
23
+ end
24
+
25
+ private
26
+
27
+ def index_plan(node)
28
+ return unless Plan::BUILDERS.key?(node.kind)
29
+
30
+ @compiled_functions[node] = true if node.kind == :function
31
+ node.children.each { |child| index_plan(child) }
32
+ end
33
+
34
+ def function(node, data)
35
+ return super unless @compiled_functions.key?(node) && !@disable_visit_errors
36
+
37
+ arguments = node.children.map { |child| evaluate(child, data) }
38
+ return native_string(node, arguments.fetch(0)) if @native_functions&.include?(node)
39
+
40
+ @functions.call_with_context(node.value.to_s, arguments, source_range: node.start...node.finish)
41
+ end
42
+
43
+ def native_string(node, value)
44
+ if value.is_a?(String)
45
+ node.value == "length" ? value.length : value.reverse
46
+ else
47
+ Functions.default.call_with_context(node.value.to_s, [value], source_range: node.start...node.finish)
48
+ end
49
+ end
50
+
51
+ def reference(node, _data)
52
+ ExpressionReference.new do |value|
53
+ @collector.reference(node) { evaluate(node.children.fetch(0), value) }
54
+ end
55
+ end
56
+
57
+ def project(node, values)
58
+ return nil unless values
59
+
60
+ index = -1
61
+ child = node.children.fetch(1)
62
+ result = values.map do |value|
63
+ index += 1
64
+ project_item(node, child, value, index)
65
+ end
66
+ result.compact!
67
+ result
68
+ end
69
+
70
+ def project_item(node, child, value, index)
71
+ @collector.within(node, index) do
72
+ result = evaluate(child, value)
73
+ @collector.emit("projection_omission", node) if nil.equal?(result)
74
+ result
75
+ end
76
+ end
77
+
78
+ def filter_projection(node, data)
79
+ values = DataAccess.array(evaluate(node.children.fetch(0), data))
80
+ indexes = [] # : Array[Integer]
81
+ index = -1
82
+ selected = values&.reject do |value|
83
+ index += 1
84
+ rejected = filter_rejected?(node, value, index)
85
+ indexes << index unless rejected
86
+ rejected
87
+ end
88
+ return nil unless selected
89
+
90
+ project_selected(node, selected, indexes)
91
+ end
92
+
93
+ def filter_rejected?(node, value, index)
94
+ @collector.within(node, index) do
95
+ rejected = Types.falsey?(evaluate(node.children.fetch(2), value))
96
+ @collector.emit("filter_exclusion", node) if rejected
97
+ rejected
98
+ end
99
+ end
100
+
101
+ def project_selected(node, selected, indexes)
102
+ position = -1
103
+ child = node.children.fetch(1)
104
+ selected.map! do |value|
105
+ position += 1
106
+ project_item(node, child, value, indexes.fetch(position))
107
+ end
108
+ selected.compact!
109
+ selected
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JMESPath
4
+ module Tracing
5
+ # @api private
6
+ module FieldLookup
7
+ def self.call(value, name)
8
+ mapping = value.is_a?(Hash) ? value : DataAccess.object(value)
9
+ return [nil, "non_object"] unless mapping
10
+
11
+ initial = mapping[name]
12
+ return [initial, nil] unless initial.nil?
13
+
14
+ result, reason = fallback(mapping, name)
15
+ return [result, nil] unless nil.equal?(result)
16
+
17
+ [nil, classify(mapping, initial, reason)]
18
+ end
19
+
20
+ def self.fallback(mapping, name)
21
+ present = false
22
+ mapping.each_key do |key|
23
+ return [mapping[key], "null"] if key.is_a?(Symbol) && key.name == name
24
+
25
+ # Core checks avoid invoking custom key predicates or equality methods.
26
+ # rubocop:disable-next Style/CaseEquality
27
+ present = true if String === key && String.instance_method(:==).bind_call(key, name)
28
+ end
29
+ [nil, present ? "null" : "missing"]
30
+ end
31
+
32
+ def self.classify(mapping, initial, reason)
33
+ nil.equal?(initial) && native_lookup?(mapping) ? reason : "unknown"
34
+ end
35
+
36
+ def self.native_lookup?(mapping)
37
+ # A Struct can return a duck mapping; avoid invoking its own type predicate.
38
+ # rubocop:disable-next Style/CaseEquality
39
+ return false unless Hash === mapping
40
+
41
+ return false if Hash.instance_method(:compare_by_identity?).bind_call(mapping)
42
+
43
+ %i[[] each_key].all? do |name|
44
+ Object.instance_method(:method).bind_call(mapping, name).owner == Hash
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -3,5 +3,5 @@
3
3
  # Queries JSON-compatible Ruby values using JMESPath expressions.
4
4
  module JMESPath
5
5
  # The semantic version of this implementation.
6
- VERSION = "0.1.2"
6
+ VERSION = "0.1.3"
7
7
  end
data/lib/jmespath.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require_relative "jmespath/version"
4
4
  require_relative "jmespath/errors"
5
+ require_relative "jmespath/failure_capture"
6
+ require_relative "jmespath/syntax_diagnostic"
5
7
  require_relative "jmespath/diagnostic"
6
8
  require_relative "jmespath/token"
7
9
  require_relative "jmespath/lexer"
@@ -20,7 +22,12 @@ require_relative "jmespath/options"
20
22
  require_relative "jmespath/input"
21
23
  require_relative "jmespath/cache"
22
24
  require_relative "jmespath/plan"
25
+ require_relative "jmespath/explanation"
26
+ require_relative "jmespath/search_result"
23
27
  require_relative "jmespath/expression"
28
+ require_relative "jmespath/tracing/collector"
29
+ require_relative "jmespath/tracing/field_lookup"
30
+ require_relative "jmespath/tracing/evaluator"
24
31
 
25
32
  # Search JSON-compatible Ruby values with JMESPath expressions.
26
33
  module JMESPath
@@ -44,15 +51,17 @@ module JMESPath
44
51
  # JMESPath.search("items[*].name", {items: [{name: "Ada"}]}) #=> ["Ada"]
45
52
  # @return [Object] the query result, including nil
46
53
  def search(expression, data, options = Options::EMPTY, **keywords)
47
- config = if options.equal?(Options::EMPTY) && keywords.empty?
48
- Options::DEFAULT
49
- else
50
- Options.new(options, keywords)
51
- end
52
- raise ArgumentError, "Expression must be a String" unless expression.is_a?(String)
54
+ FailureCapture.application do
55
+ config = if options.equal?(Options::EMPTY) && keywords.empty?
56
+ Options::DEFAULT
57
+ else
58
+ Options.new(options, keywords)
59
+ end
60
+ raise ArgumentError, "Expression must be a String" unless expression.is_a?(String)
53
61
 
54
- compiled = compile_syntax(expression, config.cache_expressions, config.max_depth)
55
- compiled.evaluate(Input.load(data), config)
62
+ compiled = compile_syntax(expression, config.cache_expressions, config.max_depth)
63
+ compiled.evaluate(Input.load(data), config)
64
+ end
56
65
  end
57
66
 
58
67
  # Parse an expression for repeated searches.
@@ -75,6 +84,32 @@ module JMESPath
75
84
  config.equal?(Options::DEFAULT) ? compiled : compiled.configured(config)
76
85
  end
77
86
 
87
+ # Validate syntax without evaluating data or checking function availability.
88
+ # @param expression [String] query text
89
+ # @param max_depth [Integer] maximum nesting from 1 through 128
90
+ # @raise [ArgumentError] expression type or depth is invalid
91
+ # @example Validate syntax without an input document
92
+ # JMESPath.validate("items[*].name") #=> []
93
+ # failure = JMESPath.validate("items[?active").fetch(0)
94
+ # failure.reason #=> "Expected rbracket, received eof"
95
+ # failure.position #=> 13
96
+ # failure.line #=> 1
97
+ # failure.column #=> 14
98
+ # @return [Array<SyntaxDiagnostic>] frozen array containing zero or one immutable diagnostic
99
+ def validate(expression, max_depth: 128)
100
+ raise ArgumentError, "Expression must be a String" unless expression.is_a?(String)
101
+ unless max_depth.is_a?(Integer) && (1..128).cover?(max_depth)
102
+ raise ArgumentError, "max_depth must be an integer from 1 through 128"
103
+ end
104
+
105
+ Parser.new(expression, max_depth: max_depth).parse
106
+ # @type var diagnostics: Array[SyntaxDiagnostic]
107
+ diagnostics = []
108
+ diagnostics.freeze
109
+ rescue Errors::SyntaxError => e
110
+ [SyntaxDiagnostic.new(e)].freeze
111
+ end
112
+
78
113
  private
79
114
 
80
115
  def compile_syntax(expression, cache, depth)
data/sig/jmespath.rbs CHANGED
@@ -1,16 +1,44 @@
1
1
  module JMESPath
2
+ type trace_context = { operation_id: Integer, index: Integer }
3
+ type trace_event = { type: String, operation_id: Integer, context: Array[trace_context], details: Hash[Symbol, json] }
4
+ type trace_report = { value: value, events: Array[trace_event], truncated: bool }
2
5
  VERSION: String
3
6
  type value = Object?
4
7
  type json = nil | bool | Integer | Float | String | Array[json] | Hash[String, json]
8
+ type explanation_details = Hash[Symbol, json]
9
+ type explanation_child = { role: String, node: explanation_node }
10
+ type explanation_node = {
11
+ id: Integer,
12
+ operation: String,
13
+ source_range: [Integer, Integer]?,
14
+ details: explanation_details,
15
+ children: Array[explanation_child]
16
+ }
17
+ type explanation = { source: String, root: explanation_node }
5
18
 
6
19
  def self.search: (String, value, ?Hash[Symbol, value], **value) -> value
7
20
  def self.compile: (String, ?cache_expressions: bool, ?max_depth: Integer, ?functions: Functions, ?disable_visit_errors: bool) -> Expression
21
+ def self.validate: (String, ?max_depth: Integer) -> Array[SyntaxDiagnostic]
22
+
23
+ class SyntaxDiagnostic
24
+ attr_reader reason: String
25
+ attr_reader expression: String
26
+ attr_reader position: Integer?
27
+ attr_reader line: Integer?
28
+ attr_reader column: Integer?
29
+ def initialize: (Errors::SyntaxError) -> void
30
+ def location_known?: () -> bool
31
+ end
8
32
 
9
33
  module Errors
10
34
  class Error < StandardError
11
35
  end
12
36
  class RuntimeError < Error
13
37
  end
38
+ class NullResultError < RuntimeError
39
+ attr_reader expression: String
40
+ def initialize: (expression: String) -> void
41
+ end
14
42
  class SyntaxError < Error
15
43
  attr_reader reason: String
16
44
  attr_reader expression: String
@@ -53,13 +81,23 @@ module JMESPath
53
81
  end
54
82
 
55
83
  module Diagnostic
56
- def self.format: (Errors::SyntaxError) -> String
84
+ def self.format: (Errors::SyntaxError | SyntaxDiagnostic) -> String
85
+ end
86
+
87
+ class SearchResult
88
+ attr_reader value: value
89
+ attr_reader error: StandardError?
90
+ def success?: () -> bool
57
91
  end
58
92
 
59
93
  class Expression
60
94
  attr_reader source: String
61
95
  def search: (value, ?Hash[Symbol, value], **value) -> value
96
+ def try_search: (value, ?Hash[Symbol, value], **value) -> SearchResult
97
+ def fetch: (value, ?Hash[Symbol, value], **value) -> Object
98
+ def trace: (value, ?Hash[Symbol, value], ?limit: Integer, **value) -> trace_report
62
99
  alias call search
100
+ def explain: () -> explanation
63
101
  end
64
102
 
65
103
  class Functions
@@ -82,11 +120,17 @@ module JMESPath
82
120
  interface _Reader
83
121
  def read: () -> String?
84
122
  end
85
- # Output stream protocol used by CLI.run.
123
+ # Input stream protocol for CLI.run in JSON Lines and interactive modes.
124
+ # Interactive readers may expose tty?; only terminal input receives prompts.
125
+ interface _LineReader
126
+ def gets: () -> String?
127
+ end
128
+ # Output stream protocol used by CLI.run. Interactive mode uses optional flush.
129
+ # Terminal prompts require print and flush on the diagnostic stream.
86
130
  interface _Writer
87
131
  def puts: (String) -> void
88
132
  end
89
133
  module CLI
90
- def self.run: (Array[String], ?stdin: _Reader, ?stdout: _Writer, ?stderr: _Writer) -> Integer
134
+ def self.run: (Array[String], ?stdin: _Reader | _LineReader, ?stdout: _Writer, ?stderr: _Writer) -> Integer
91
135
  end
92
136
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jmespath-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leonid Svyatov
@@ -64,9 +64,12 @@ files:
64
64
  - README.md
65
65
  - SECURITY.md
66
66
  - VERSIONING.md
67
+ - completions/_jmespath
68
+ - completions/jmespath.bash
67
69
  - docs/guides/comparison.md
68
70
  - docs/guides/compatibility.md
69
71
  - docs/guides/compilation.md
72
+ - docs/guides/completion.md
70
73
  - docs/guides/errors.md
71
74
  - docs/guides/functions.md
72
75
  - docs/guides/performance.md
@@ -77,7 +80,12 @@ files:
77
80
  - lib/jmespath/ast.rb
78
81
  - lib/jmespath/cache.rb
79
82
  - lib/jmespath/cli.rb
83
+ - lib/jmespath/cli/argument_parser.rb
84
+ - lib/jmespath/cli/arguments.rb
80
85
  - lib/jmespath/cli/failure_diagnostic.rb
86
+ - lib/jmespath/cli/function_listing.rb
87
+ - lib/jmespath/cli/help.rb
88
+ - lib/jmespath/cli/interactive_session.rb
81
89
  - lib/jmespath/data_access.rb
82
90
  - lib/jmespath/diagnostic.rb
83
91
  - lib/jmespath/errors.rb
@@ -87,13 +95,16 @@ files:
87
95
  - lib/jmespath/evaluation/scalars.rb
88
96
  - lib/jmespath/evaluation/slices.rb
89
97
  - lib/jmespath/evaluator.rb
98
+ - lib/jmespath/explanation.rb
90
99
  - lib/jmespath/expression.rb
91
100
  - lib/jmespath/expression_reference.rb
101
+ - lib/jmespath/failure_capture.rb
92
102
  - lib/jmespath/functions.rb
93
103
  - lib/jmespath/functions/coercions.rb
94
104
  - lib/jmespath/functions/collections.rb
95
105
  - lib/jmespath/functions/conversion.rb
96
106
  - lib/jmespath/functions/function_call.rb
107
+ - lib/jmespath/functions/json_value.rb
97
108
  - lib/jmespath/functions/references.rb
98
109
  - lib/jmespath/functions/scalar.rb
99
110
  - lib/jmespath/functions/signature.rb
@@ -107,7 +118,12 @@ files:
107
118
  - lib/jmespath/parser/expressions.rb
108
119
  - lib/jmespath/parser/projections.rb
109
120
  - lib/jmespath/plan.rb
121
+ - lib/jmespath/search_result.rb
122
+ - lib/jmespath/syntax_diagnostic.rb
110
123
  - lib/jmespath/token.rb
124
+ - lib/jmespath/tracing/collector.rb
125
+ - lib/jmespath/tracing/evaluator.rb
126
+ - lib/jmespath/tracing/field_lookup.rb
111
127
  - lib/jmespath/types.rb
112
128
  - lib/jmespath/version.rb
113
129
  - sig/jmespath.rbs