@loancrate/json-selector 3.0.0 → 4.0.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.
package/README.md CHANGED
@@ -20,7 +20,7 @@ This should be unambiguous relative to the existing grammar and semantics.
20
20
 
21
21
  In addition to the extensions above, this library offers the following features compared to [jmespath.js](https://github.com/jmespath/jmespath.js):
22
22
 
23
- - Written using Typescript and [PEG.js](https://pegjs.org/) for clarity and correctness
23
+ - Written using TypeScript with a hand-written Pratt parser
24
24
  - Type definitions for the abstract syntax tree (AST) produced by the parser
25
25
  - Typed visitor pattern for accessing AST nodes
26
26
  - Formatting of an AST back into an expression string
@@ -79,31 +79,51 @@ and the [binding power
79
79
  table](https://github.com/jmespath/jmespath.js/blob/master/jmespath.js#L474-L501)
80
80
  from the source, we can reverse-engineer the operator precedence of JMESPath.
81
81
 
82
- Essentially, the expression grammar is structured as a left-hand side (LHS)
83
- expression followed by zero or more right-hand side (RHS) expressions (which are
84
- often projections on the result of the LHS). RHS expressions are consumed by the
85
- parser and projected onto the LHS as long as they have the same or higher
86
- binding power as the LHS. RHS expressions with lower binding power are projected
87
- onto the result of the overall expression to the left, as opposed to the nearest
88
- subexpression. For example, since dot (40) has a higher binding power than left
89
- bracket (55), `a.b.c['id'].d.e` is parsed and evaluated like
90
- `((a.b.c)['id']).d.e`. Binding power and precedence can be summarized as
91
- follows, in increasing order:
82
+ The expression grammar has three categories of operators:
83
+
84
+ **Logical and comparison operators** follow traditional precedence rules (from
85
+ lowest to highest):
92
86
 
93
87
  - pipe: `|`
94
88
  - or: `||`
95
89
  - and: `&&`
96
90
  - compare: `<=`, `>=`, `<`, `>`, `==`, `!=`
97
- - not: `!`
98
- - flatten projection: `[]`
99
- - filter projection: `[?`
100
- - star/slice projection: `[*`, `[<number?>:`
101
- - index/ID access: `[<number>`, `['`
102
- - member access: `.`
103
-
104
- However, as a [special
105
- case](https://github.com/jmespath/jmespath.js/blob/master/jmespath.js#L803-L805),
106
- member access can directly follow (act as RHS) for any projection.
91
+ - not: `!` (prefix)
92
+
93
+ Higher-precedence operators bind more tightly. For example, `a || b && c`
94
+ parses as `a || (b && c)`, and `a || b.c` parses as `a || (b.c)` because
95
+ access operators have higher precedence than `||`.
96
+
97
+ **Access operators** chain left-to-right as postfix operators:
98
+
99
+ - member access: `.field`
100
+ - index access: `[0]`, `[n:m]` (slices)
101
+ - ID access: `['id']` (shorthand for `[?id == 'id'] | [0]`)
102
+
103
+ For example, `a[0].b.c['id'].d.e` parses as `(((((a[0]).b).c)['id']).d).e` -
104
+ each operator applies to the complete expression on its left, building up the
105
+ chain step by step.
106
+
107
+ **Projection operators** create projections that map over collections:
108
+
109
+ - flatten: `[]` (flatten arrays)
110
+ - filter: `[?condition]` (filter by condition)
111
+ - star: `[*]` (map over array values)
112
+
113
+ Projections terminate before logical, comparison, and pipe operators, but
114
+ continue with access operators and can chain with other projections. For
115
+ example:
116
+
117
+ - `items[*].name` - projects over items, accessing name from each
118
+ - `items[*].tags[]` - projects over items, then flattens tags arrays
119
+ - `items[*] || []` - projection completes before the `||`, result is `(items[*]) || []`
120
+
121
+ **Note on chained flattens**: Multiple flattens compound to flatten deeper
122
+ levels. For example, on data `[[[1,2]], [[3,4]]]`:
123
+
124
+ - `[]` gives `[[1,2], [3,4]]` (one level)
125
+ - `[][]` gives `[1,2,3,4]` (two levels)
126
+ - `[*][]` gives `[[1,2], [3,4]]` (projects then flattens once - not the same as `[][]`)
107
127
 
108
128
  ## License
109
129