@jmespath-community/jmespath 1.2.0 → 1.4.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 +228 -12
- package/dist/cli.cjs +2816 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.mjs +2794 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.cjs +2699 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +464 -0
- package/dist/index.d.ts +464 -0
- package/dist/index.esm.js +2707 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.esm.min.js +6 -0
- package/dist/index.esm.min.js.map +1 -0
- package/dist/index.mjs +2697 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.umd.js +2712 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/index.umd.min.js +6 -0
- package/dist/index.umd.min.js.map +1 -0
- package/package.json +68 -11
- package/dist/jmespath.esm.js +0 -2369
- package/dist/jmespath.esm.min.js +0 -2
- package/dist/jmespath.esm.min.js.map +0 -1
- package/dist/jmespath.umd.js +0 -2398
- package/dist/jmespath.umd.min.js +0 -2
- package/dist/jmespath.umd.min.js.map +0 -1
- package/dist/lib/bin/jp.js +0 -127
- package/dist/lib/bin/jp.js.map +0 -1
- package/dist/lib/package.json +0 -70
- package/dist/lib/src/AST.type.js +0 -3
- package/dist/lib/src/AST.type.js.map +0 -1
- package/dist/lib/src/JSON.type.js +0 -3
- package/dist/lib/src/JSON.type.js.map +0 -1
- package/dist/lib/src/Lexer.js +0 -327
- package/dist/lib/src/Lexer.js.map +0 -1
- package/dist/lib/src/Lexer.type.js +0 -46
- package/dist/lib/src/Lexer.type.js.map +0 -1
- package/dist/lib/src/Parser.js +0 -468
- package/dist/lib/src/Parser.js.map +0 -1
- package/dist/lib/src/Parser.type.js +0 -3
- package/dist/lib/src/Parser.type.js.map +0 -1
- package/dist/lib/src/Runtime.js +0 -924
- package/dist/lib/src/Runtime.js.map +0 -1
- package/dist/lib/src/Scope.js +0 -29
- package/dist/lib/src/Scope.js.map +0 -1
- package/dist/lib/src/TreeInterpreter.js +0 -319
- package/dist/lib/src/TreeInterpreter.js.map +0 -1
- package/dist/lib/src/index.js +0 -65
- package/dist/lib/src/index.js.map +0 -1
- package/dist/lib/src/utils/index.js +0 -145
- package/dist/lib/src/utils/index.js.map +0 -1
- package/dist/lib/src/utils/strings.js +0 -92
- package/dist/lib/src/utils/strings.js.map +0 -1
- package/dist/lib/src/utils/text.js +0 -45
- package/dist/lib/src/utils/text.js.map +0 -1
- package/dist/types/bin/jp.d.ts +0 -2
- package/dist/types/src/AST.type.d.ts +0 -104
- package/dist/types/src/JSON.type.d.ts +0 -10
- package/dist/types/src/Lexer.d.ts +0 -19
- package/dist/types/src/Lexer.type.d.ts +0 -51
- package/dist/types/src/Parser.d.ts +0 -33
- package/dist/types/src/Parser.type.d.ts +0 -4
- package/dist/types/src/Runtime.d.ts +0 -87
- package/dist/types/src/Scope.d.ts +0 -8
- package/dist/types/src/TreeInterpreter.d.ts +0 -22
- package/dist/types/src/index.d.ts +0 -45
- package/dist/types/src/utils/index.d.ts +0 -16
- package/dist/types/src/utils/strings.d.ts +0 -11
- package/dist/types/src/utils/text.d.ts +0 -11
package/README.md
CHANGED
|
@@ -8,29 +8,91 @@ JMESPath is a query language for JSON. It will take a JSON document
|
|
|
8
8
|
as input and transform it into another JSON document
|
|
9
9
|
given a JMESPath expression.
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Usage](#usage)
|
|
15
|
+
- [ESM (Node.js)](#esm-nodejs)
|
|
16
|
+
- [CommonJS (Node.js)](#commonjs-nodejs)
|
|
17
|
+
- [Browser (UMD)](#browser-umd)
|
|
18
|
+
- [API](#api)
|
|
19
|
+
- [`search(data, expression, options)`](#searchdata-d-expression-string-options-options-t)
|
|
20
|
+
- [`searchStream(source, expression, options)`](#searchstreamsource-expression-options-asyncgenerator)
|
|
21
|
+
- [`compile(expression)`](#compileexpression-string-expressionnodetree)
|
|
22
|
+
- [`compileQuery(expression, options)`](#compilequeryexpression-string-options-options-compiledquery)
|
|
23
|
+
- [`validate(expression, options)`](#validateexpression-string-options-options-validationresult)
|
|
24
|
+
- [Extensions](#extensions-to-original-spec)
|
|
25
|
+
- [More Resources](#more-resources)
|
|
26
|
+
- [Experimental Features](#experimental-features)
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
14
31
|
npm install @jmespath-community/jmespath
|
|
15
32
|
```
|
|
16
33
|
|
|
17
|
-
##
|
|
34
|
+
## Usage
|
|
18
35
|
|
|
19
|
-
###
|
|
36
|
+
### ESM (Node.js)
|
|
20
37
|
|
|
21
38
|
```javascript
|
|
22
39
|
import { search } from "@jmespath-community/jmespath";
|
|
23
40
|
|
|
24
|
-
|
|
41
|
+
const data = { foo: { bar: { baz: [0, 1, 2, 3, 4] } } };
|
|
42
|
+
const result = search(data, "foo.bar.baz[2]");
|
|
25
43
|
|
|
26
|
-
|
|
44
|
+
console.log(result);
|
|
45
|
+
// Outputs: 2
|
|
27
46
|
```
|
|
28
47
|
|
|
48
|
+
### CommonJS (Node.js)
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const { search } = require("@jmespath-community/jmespath");
|
|
52
|
+
|
|
53
|
+
const data = { foo: { bar: { baz: [0, 1, 2, 3, 4] } } };
|
|
54
|
+
const result = search(data, "foo.bar.baz[2]");
|
|
55
|
+
|
|
56
|
+
console.log(result);
|
|
57
|
+
// Outputs: 2
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Browser (UMD)
|
|
61
|
+
|
|
62
|
+
You can include the UMD build directly in your HTML file. The library will be available under the `jmespath` global variable.
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<script src="https://unpkg.com/@jmespath-community/jmespath/dist/index.umd.min.js"></script>
|
|
66
|
+
<script>
|
|
67
|
+
const data = { foo: { bar: { baz: [0, 1, 2, 3, 4] } } };
|
|
68
|
+
const result = jmespath.search(data, "foo.bar.baz[2]");
|
|
69
|
+
console.log(result);
|
|
70
|
+
// Outputs: 2
|
|
71
|
+
</script>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## API
|
|
75
|
+
|
|
76
|
+
### `search<T = JSONValue, D = unknown>(data: D, expression: string, options?: Options): T`
|
|
77
|
+
|
|
29
78
|
In the example we gave the `search` function input data of
|
|
30
79
|
`{foo: {bar: {baz: [0, 1, 2, 3, 4]}}}` as well as the JMESPath
|
|
31
80
|
expression `foo.bar.baz[2]`, and the `search` function evaluated
|
|
32
81
|
the expression against the input data to produce the result `2`.
|
|
33
82
|
|
|
83
|
+
Accepts custom TypeScript interfaces directly without casting:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface User {
|
|
87
|
+
name: string;
|
|
88
|
+
age: number;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const user: User = { name: "Alice", age: 30 };
|
|
92
|
+
const name = search<string>(user, "name");
|
|
93
|
+
// name is typed as string
|
|
94
|
+
```
|
|
95
|
+
|
|
34
96
|
The JMESPath language can do _a lot_ more than select an element
|
|
35
97
|
from a list. Here are a few more examples:
|
|
36
98
|
|
|
@@ -72,6 +134,61 @@ search(JSON_DOCUMENT, "foo[?age > `30`]");
|
|
|
72
134
|
// OUTPUTS: [ { age: 35 }, { age: 40 } ]
|
|
73
135
|
```
|
|
74
136
|
|
|
137
|
+
#### Automatic Type Inference
|
|
138
|
+
|
|
139
|
+
Literal path queries automatically infer property types without requiring manual type parameters or type assertions:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
const user = {
|
|
143
|
+
profile: { name: "Alice", email: "alice@example.com" },
|
|
144
|
+
tags: ["admin", "dev"],
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const name = search(user, "profile.name"); // inferred as string
|
|
148
|
+
const tag = search(user, "tags[0]"); // inferred as string
|
|
149
|
+
const tags = search(user, "tags[*]"); // inferred as string[]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Runtime Security Options
|
|
153
|
+
|
|
154
|
+
Pass `options` to restrict execution limits on untrusted queries:
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
search(data, expression, {
|
|
158
|
+
maxDepth: 32, // expression and evaluation recursion limit
|
|
159
|
+
maxNodes: 128, // maximum AST node count
|
|
160
|
+
maxOutputSize: 1000, // maximum elements or characters in results
|
|
161
|
+
allowedFunctions: ['length', 'contains'], // allow-list specific built-ins
|
|
162
|
+
disallowedFunctions: ['custom_heavy'], // deny-list specific built-ins
|
|
163
|
+
timeoutMs: 100, // query execution time limit in ms
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### `searchStream<T = JSONValue, D = unknown>(source: StreamSource<D>, expression: string | ExpressionNode, options?: StreamOptions): AsyncGenerator<T, void, unknown>`
|
|
168
|
+
|
|
169
|
+
Evaluates a JMESPath expression incrementally over an `AsyncIterable`, `ReadableStream`, or Node.js `stream.Readable`, yielding matching results without buffering large datasets in memory:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import jmespath from "@jmespath-community/jmespath";
|
|
173
|
+
|
|
174
|
+
async function* getEvents() {
|
|
175
|
+
yield { id: 1, level: "info", message: "connected" };
|
|
176
|
+
yield { id: 2, level: "error", message: "disk full" };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
for await (const msg of jmespath.searchStream(getEvents(), "[?level == 'error'].message")) {
|
|
180
|
+
console.log(msg); // "disk full"
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Supports automatic NDJSON / JSON lines chunk decoding (`parseJson: 'auto'`), chunk flattening, precompiled ASTs, and early termination:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
for await (const item of jmespath.searchStream(logStream, "[:10]", { limit: 10 })) {
|
|
188
|
+
console.log(item);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
75
192
|
### `compile(expression: string): ExpressionNodeTree`
|
|
76
193
|
|
|
77
194
|
You can precompile all your expressions ready for use later on. The `compile`
|
|
@@ -83,19 +200,48 @@ import { compile, TreeInterpreter } from "@jmespath-community/jmespath";
|
|
|
83
200
|
|
|
84
201
|
const ast = compile("foo.bar");
|
|
85
202
|
|
|
86
|
-
TreeInterpreter.search(ast, { foo: { bar: "BAZ" } });
|
|
203
|
+
const result = TreeInterpreter.search(ast, { foo: { bar: "BAZ" } });
|
|
87
204
|
// RETURNS: "BAZ"
|
|
88
205
|
```
|
|
89
206
|
|
|
207
|
+
### `compileQuery<T = JSONValue, D = unknown>(expression: string, options?: Options): CompiledQuery<T, D>`
|
|
208
|
+
|
|
209
|
+
Precompiles an expression into a reusable, callable function:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { compileQuery } from "@jmespath-community/jmespath";
|
|
213
|
+
|
|
214
|
+
const getName = compileQuery<string, { user: { name: string } }>("user.name");
|
|
215
|
+
|
|
216
|
+
const result = getName({ user: { name: "Alice" } });
|
|
217
|
+
// Outputs: "Alice"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### `validate(expression: string, options?: Options): ValidationResult`
|
|
221
|
+
|
|
222
|
+
Validates an expression without throwing exceptions, checking syntax and security options:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
import { validate } from "@jmespath-community/jmespath";
|
|
226
|
+
|
|
227
|
+
const result = validate("foo.bar");
|
|
228
|
+
// { valid: true, ast: { type: 'Subexpression', ... } }
|
|
229
|
+
|
|
230
|
+
const invalid = validate("foo.", { maxNodes: 10 });
|
|
231
|
+
// { valid: false, error: 'Syntax error: ...' }
|
|
232
|
+
```
|
|
233
|
+
|
|
90
234
|
---
|
|
91
235
|
|
|
92
236
|
## EXTENSIONS TO ORIGINAL SPEC
|
|
93
237
|
|
|
94
|
-
1. ### Register
|
|
238
|
+
1. ### Register your own custom functions
|
|
95
239
|
|
|
96
|
-
####
|
|
240
|
+
#### Enhanced Function Registry API
|
|
97
241
|
|
|
98
|
-
|
|
242
|
+
The library provides both backward-compatible and enhanced APIs for registering custom functions with improved developer experience, type safety, and flexible override behavior.
|
|
243
|
+
|
|
244
|
+
##### Basic Usage (Backward Compatible)
|
|
99
245
|
|
|
100
246
|
```javascript
|
|
101
247
|
import { search, registerFunction, TYPE_NUMBER } from "@jmespath-community/jmespath";
|
|
@@ -117,6 +263,76 @@ TreeInterpreter.search(ast, { foo: { bar: "BAZ" } });
|
|
|
117
263
|
// OUTPUTS: 6
|
|
118
264
|
```
|
|
119
265
|
|
|
266
|
+
##### Enhanced Registry API with Type Safety
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { register, search, TYPE_NUMBER } from "@jmespath-community/jmespath";
|
|
270
|
+
|
|
271
|
+
// TypeScript prevents registering built-in functions at compile time
|
|
272
|
+
// register('sum', myFunc, signature); // TypeScript error!
|
|
273
|
+
|
|
274
|
+
// Enhanced registration with better error handling
|
|
275
|
+
const result = register('multiply', ([a, b]) => a * b, [
|
|
276
|
+
{ types: [TYPE_NUMBER] },
|
|
277
|
+
{ types: [TYPE_NUMBER] }
|
|
278
|
+
]);
|
|
279
|
+
|
|
280
|
+
if (result.success) {
|
|
281
|
+
console.log(result.message); // "Function multiply() registered successfully"
|
|
282
|
+
} else {
|
|
283
|
+
console.error(result.message); // Detailed error information
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
##### Override Existing Functions
|
|
288
|
+
|
|
289
|
+
```javascript
|
|
290
|
+
import { registerFunction, register } from "@jmespath-community/jmespath";
|
|
291
|
+
|
|
292
|
+
// Option 1: Using registerFunction with options
|
|
293
|
+
registerFunction('myFunc', () => 'first', []);
|
|
294
|
+
registerFunction('myFunc', () => 'second', [], { override: true, warn: true });
|
|
295
|
+
// Console: "Warning: Overriding existing function: myFunc()"
|
|
296
|
+
|
|
297
|
+
// Option 2: Using enhanced register API
|
|
298
|
+
const result = register('myFunc', () => 'third', [], { override: true });
|
|
299
|
+
console.log(result.message); // "Function myFunc() overridden successfully"
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
##### Registry Management
|
|
303
|
+
|
|
304
|
+
```javascript
|
|
305
|
+
import {
|
|
306
|
+
isRegistered,
|
|
307
|
+
getRegisteredFunctions,
|
|
308
|
+
getCustomFunctions,
|
|
309
|
+
unregisterFunction,
|
|
310
|
+
clearCustomFunctions
|
|
311
|
+
} from "@jmespath-community/jmespath";
|
|
312
|
+
|
|
313
|
+
// Check if function exists
|
|
314
|
+
console.log(isRegistered('sum')); // true (built-in)
|
|
315
|
+
console.log(isRegistered('myFunc')); // true (if registered)
|
|
316
|
+
|
|
317
|
+
// Get all registered functions
|
|
318
|
+
const allFunctions = getRegisteredFunctions();
|
|
319
|
+
console.log(allFunctions); // ['abs', 'avg', 'ceil', ..., 'myFunc']
|
|
320
|
+
|
|
321
|
+
// Get only custom functions
|
|
322
|
+
const customFunctions = getCustomFunctions();
|
|
323
|
+
console.log(customFunctions); // ['myFunc', 'divide', ...]
|
|
324
|
+
|
|
325
|
+
// Unregister custom function (built-ins cannot be unregistered)
|
|
326
|
+
const removed = unregisterFunction('myFunc');
|
|
327
|
+
console.log(removed); // true if successful
|
|
328
|
+
|
|
329
|
+
// Clear all custom functions
|
|
330
|
+
clearCustomFunctions();
|
|
331
|
+
console.log(getCustomFunctions()); // []
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
##### Optional Arguments
|
|
335
|
+
|
|
120
336
|
Optional arguments are supported by setting `{..., optional: true}` in argument signatures
|
|
121
337
|
|
|
122
338
|
```javascript
|
|
@@ -124,7 +340,7 @@ TreeInterpreter.search(ast, { foo: { bar: "BAZ" } });
|
|
|
124
340
|
"divide",
|
|
125
341
|
(resolvedArgs) => {
|
|
126
342
|
const [dividend, divisor] = resolvedArgs;
|
|
127
|
-
return dividend / divisor ?? 1; //OPTIONAL DIVISOR THAT DEFAULTS TO 1
|
|
343
|
+
return dividend / (divisor ?? 1); //OPTIONAL DIVISOR THAT DEFAULTS TO 1
|
|
128
344
|
},
|
|
129
345
|
[{ types: [TYPE_NUMBER] }, { types: [TYPE_NUMBER], optional: true }], //SIGNATURE
|
|
130
346
|
);
|