Skip to content

Commit c021d32

Browse files
committed
docs: describe the new operators API
1 parent fe1c806 commit c021d32

File tree

2 files changed

+19
-59
lines changed

2 files changed

+19
-59
lines changed

README.md

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,10 @@ jsonquery(data, [
9292
The build in functions can be extended with custom functions, like `times` in the following example:
9393

9494
```js
95-
import { jsonquery, functions } from '@jsonquerylang/jsonquery'
95+
import { jsonquery } from '@jsonquerylang/jsonquery'
9696

9797
const options = {
9898
functions: {
99-
...functions,
10099
times: (value) => (data) => data.map((item) => item * value)
101100
}
102101
}
@@ -369,36 +368,22 @@ Here:
369368
- `data` is the JSON document that will be queried, often an array with objects.
370369
- `query` is a JSON document containing a JSON query, either the text format or the parsed JSON format.
371370
- `options` is an optional object that can contain the following properties:
372-
- `functions` is an optional map with function creators. A function creator has optional arguments as input and must return a function that can be used to process the query data. For example:
371+
- `functions` is an optional map with custom function creators. A function creator has optional arguments as input and must return a function that can be used to process the query data. For example:
373372

374373
```js
375-
import { functions } from '@jsonquerylang/jsonquery'
376-
377374
const options = {
378375
functions: {
379-
// keep all built-in functions
380-
...functions,
381-
382-
// define a new custom function "times"
383376
// usage example: 'times(3)'
384377
times: (value) => (data) => data.map((item) => item * value)
385378
}
386379
}
387380
```
388-
389-
Note that configuring the option `functions` will overwrite the default functions. In order to extend the existing functions it is necessary to import the build-in functions and extend the custom `functions` object with them as in the example above.
390381

391382
If the parameters are not a static value but can be a query themselves, the function `compile` can be used to compile them. For example, the actual implementation of the function `filter` is the following:
392383

393384
```js
394-
import { functions } from '@jsonquerylang/jsonquery'
395-
396385
const options = {
397386
functions: {
398-
// keep all built-in functions
399-
...functions,
400-
401-
// overwrite function "filter" with our own implementation
402387
// usage example: 'filter(.age > 20)'
403388
filter: (predicate) => {
404389
const _predicate = compile(predicate)
@@ -410,44 +395,36 @@ Here:
410395

411396
You can have a look at the source code of the functions in `/src/functions.ts` for more examples.
412397

413-
- `operators` is an optional array with maps of operators having the same precedence, ordered from highest to lowest precedence. The default array with operators is the following, with the precedence going from lowest to highest:
414-
415-
```js
416-
const operators = [
417-
{ pow: '^' },
418-
{ multiply: '*', divide: '/', mod: '%' },
419-
{ add: '+', subtract: '-' },
420-
{ gt: '>', gte: '>=', lt: '<', lte: '<=', in: 'in', 'not in': 'not in' },
421-
{ eq: '==', ne: '!=' },
422-
{ and: 'and' },
423-
{ or: 'or' }
424-
]
425-
```
398+
- `operators` is an optional array definitions for custom operators. Each definition describes the new operator, the name of the function that it maps to, and the desired precedence of the operator: the same, before, or after one of the existing operators (`at`, `before`, or `after`):
426399

427-
When extending the built-in operators with a custom operator, the built-in operators can be imported via `import { operators } from '@jsonquerylang/jsonquery'` and then extended by mapping over them and adding the custom operator to the group with the right precedence level (see example below), or adding a new precedence level if needed.
400+
```ts
401+
type CustomOperator =
402+
| { name: string; op: string; at: string }
403+
| { name: string; op: string; after: string }
404+
| { name: string; op: string; before: string }
405+
```
428406

429407
The defined operators can be used in a text query. Only operators with both a left and right hand side are supported, like `a == b`. They can only be executed when there is a corresponding function. For example:
430408

431409
```js
432-
import { buildFunction, functions, operators } from '@jsonquerylang/jsonquery'
410+
import { buildFunction } from '@jsonquerylang/jsonquery'
433411

434412
const options = {
435413
// Define a new function "notEqual".
436414
functions: {
437-
...functions,
438415
notEqual: buildFunction((a, b) => a !== b)
439416
},
440417

441418
// Define a new operator "<>" which maps to the function "notEqual"
442419
// and has the same precedence as operator "==".
443-
operators: operators.map((group) => {
444-
return Object.values(group).includes('==')
445-
? { ...group, notEqual: '<>' }
446-
: group
447-
})
420+
operators: [
421+
{ name: 'aboutEq', op: '~=', at: '==' }
422+
]
448423
}
449424
```
450425

426+
The build-in operators can be found in the source code: [/src/operators.ts](https://github.com/jsonquerylang/jsonquery/blob/develop/src/operators.ts).
427+
451428
Here an example of using the function `jsonquery`:
452429

453430
```js
@@ -537,12 +514,8 @@ The function `buildFunction` is a helper function to create a custom function. I
537514
The query engine passes the raw arguments to all functions, and the functions have to compile the arguments themselves when they are dynamic. For example:
538515
539516
```ts
540-
import { functions } from '@jsonquerylang/jsonquery'
541-
542517
const options = {
543518
functions: {
544-
...functions,
545-
546519
notEqual: (a: JSONQuery, b: JSONQuery) => {
547520
const aCompiled = compile(a)
548521
const bCompiled = compile(b)
@@ -564,11 +537,10 @@ const result = jsonquery(data, '(.x + .y) <> 6', options) // true
564537
To automatically compile and evaluate the arguments of the function, the helper function `buildFunction` can be used:
565538
566539
```ts
567-
import { jsonquery, functions, buildFunction } from '@jsonquerylang/jsonquery'
540+
import { jsonquery, buildFunction } from '@jsonquerylang/jsonquery'
568541

569542
const options = {
570543
functions: {
571-
...functions,
572544
notEqual: buildFunction((a: number, b: number) => a !== b)
573545
}
574546
}

src/types.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,9 @@ export type FunctionBuildersMap = Record<string, FunctionBuilder>
3434
export type Getter = [key: string, Fun]
3535
export type OperatorGroup = Record<string, string>
3636
export type CustomOperator =
37-
| {
38-
name: string
39-
op: string
40-
at: string
41-
}
42-
| {
43-
name: string
44-
op: string
45-
after: string
46-
}
47-
| {
48-
name: string
49-
op: string
50-
before: string
51-
}
37+
| { name: string; op: string; at: string }
38+
| { name: string; op: string; after: string }
39+
| { name: string; op: string; before: string }
5240

5341
export interface Entry<T> {
5442
key: string

0 commit comments

Comments
 (0)