Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add option to include the query method of jsonpath PFR-990 #168

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import jsonpath from '../../../functions/jsonpath-value/1.0';
import jsonpath from '../../../functions/jsonpath/1.0';

const TEST_DATA = `
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import jsonpath from '../../../functions/jsonpath-value/1.1';
import jsonpath from '../../../functions/jsonpath/1.1';

const TEST_DATA = `
{
Expand Down
183 changes: 183 additions & 0 deletions __tests__/jsonpath/2.0/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import jsonpath from '../../../functions/jsonpath/2.0';

const TEST_DATA = `
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
}, {
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}, {
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}, {
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95,
"sold": true
}
}
}
`;

describe('Jsonpath value', () => {
describe('with input type string and return type', () => {
test('object', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$..book[(@.length-1)]',
method: 'value',
});
expect(result).toStrictEqual({
author: 'J. R. R. Tolkien',
category: 'fiction',
isbn: '0-395-19395-8',
price: 22.99,
title: 'The Lord of the Rings',
});
});

test('text', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$.store.bicycle.color',
method: 'value',
});
expect(result).toBe('red');
});

test('number', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$.store.bicycle.price',
method: 'value',
});
expect(result).toBe(19.95);
});

test('boolean', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$.store.bicycle.sold',
method: 'value',
});
expect(result).toBe(true);
});

test('list returns the first item', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$.store.book[*].author',
method: 'value',
});
expect(result).toStrictEqual('Nigel Rees');
});
});

test('with input type object return type text', async () => {
const { result } = await jsonpath({
data: JSON.parse(TEST_DATA),
path: '$.store.bicycle.color',
method: 'value',
});
expect(result).toBe('red');
});

test('with input type integer', async () =>
expect(async () =>
jsonpath({
data: 12345,
path: '$.store.bicycle.color',
method: 'value',
}),
).rejects.toThrow(new Error('obj needs to be an object')));
});

describe('Jsonpath query', () => {
describe('with input type string', () => {
test('The authors of all books in the store', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$.store.book[*].author',
method: 'query',
});
expect(result).toStrictEqual([
'Nigel Rees',
'Evelyn Waugh',
'Herman Melville',
'J. R. R. Tolkien',
]);
});

test('The first two books via subscript array slice', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$..book[:2]',
method: 'query',
});
expect(result).toStrictEqual([
{
category: 'reference',
author: 'Nigel Rees',
title: 'Sayings of the Century',
price: 8.95,
},
{
category: 'fiction',
author: 'Evelyn Waugh',
title: 'Sword of Honour',
price: 12.99,
},
]);
});

test('Filter all books cheaper than 10', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$..book[?(@.price<10)]',
method: 'query',
});
expect(result).toStrictEqual([
{
category: 'reference',
author: 'Nigel Rees',
title: 'Sayings of the Century',
price: 8.95,
},
{
category: 'fiction',
author: 'Herman Melville',
title: 'Moby Dick',
isbn: '0-553-21311-3',
price: 8.99,
},
]);
});

test('No results with provided path', async () => {
const { result } = await jsonpath({
data: TEST_DATA,
path: '$..book[?(@.price==0)]',
method: 'query',
});
expect(result).toStrictEqual([]);
});
});
});
2 changes: 1 addition & 1 deletion blocks/jsonpath.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"dependencies": [],
"functions": ["jsonpathValue 1.1"],
"functions": ["jsonpath 2.0"],
"includes": ["./functions/utils"]
}
File renamed without changes.
File renamed without changes.
97 changes: 97 additions & 0 deletions functions/jsonpath/2.0/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"description": "Allows to select fields from json/objects using JSONPath: https://www.npmjs.com/package/jsonpath.",
"label": "JSONPath",
"category": "Data",
"icon": {
"name": "RightIcon",
"color": "Purple"
},
"options": [
{
"info": "The data or object.",
"name": "data",
"label": "Data",
"meta": {
"type": "Value",
"validations": {
"required": true
},
"allowedKinds": ["OBJECT", "JSON", "STRING", "ARRAY"]
}
},
{
"info": "The method you want to use to find the correct element(s). The value method returns the value of the first element matching the expression. The query method returns an array of elements matching the expression. See https://www.npmjs.com/package/jsonpath#methods for more information.",
"label": "Method",
"meta": {
"type": "Select",
"default": "value",
"values": [
{
"label": "Value",
"value": "value"
},
{
"label": "Query",
"value": "query"
}
],
"validations": {
"required": true
}
},
"name": "method"
},
{
"info": "The jsonpath, see: https://www.npmjs.com/package/jsonpath.",
"name": "path",
"label": "JSONPath",
"configuration": {
"placeholder": "$."
},
"meta": {
"type": "Text",
"validations": {
"required": true
}
}
},
{
"info": "The schema model can be utilized to type the output of this step when it is an object or an array of objects.",
"meta": {
"type": "SchemaModel"
},
"name": "schemaModel",
"label": "Schema Model"
},
{
"meta": {
"type": "Output",
"validations": {
"required": true
},
"output": {
"anyOf": [
{
"type": "Text"
},
{
"type": "Boolean"
},
{
"type": "Number"
},
{ "type": "Object", "schemaModel": "schemaModel" },
{
"type": "Array",
"schemaModel": "schemaModel",
"dataType": "SCHEMA"
}
]
}
},
"name": "result",
"label": "Result"
}
],
"yields": "NONE"
}
21 changes: 21 additions & 0 deletions functions/jsonpath/2.0/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import jsonpath from '../../utils/jsonpath.min';

export default async ({ data, path, method }) => {
let parsed = data;
let result = '';

if (typeof data === 'string') {
parsed = JSON.parse(data);
}

switch (method) {
case 'value':
result = jsonpath.value(parsed, path);
break;
case 'query':
result = jsonpath.query(parsed, path);
break;
}

return { result };
};
Loading