Compare commits
19 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
74bfa76a4e | ||
![]() |
4c31065249 | ||
![]() |
195121070f | ||
![]() |
01ca521789 | ||
![]() |
182b8be1d4 | ||
![]() |
70cfecd483 | ||
![]() |
a53e88ac9e | ||
![]() |
c95faba670 | ||
![]() |
f037201b20 | ||
![]() |
fd4e034cd9 | ||
![]() |
457b4bc1da | ||
![]() |
6c24592e43 | ||
![]() |
a45271da5a | ||
![]() |
9616a5b783 | ||
![]() |
652d417f66 | ||
![]() |
82e9f5ed5b | ||
![]() |
6364d326cd | ||
![]() |
a10ac23e1a | ||
![]() |
810e7c7b5a |
10 changed files with 189 additions and 95 deletions
11
.eslintrc.js
Normal file
11
.eslintrc.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
module.exports = {
|
||||
"extends": "standard",
|
||||
"plugins": [
|
||||
"standard",
|
||||
"promise",
|
||||
"jest"
|
||||
],
|
||||
"env": {
|
||||
"jest/globals": true
|
||||
}
|
||||
};
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
node_modules
|
||||
./coverage
|
||||
|
|
16
.travis.yml
16
.travis.yml
|
@ -1,3 +1,19 @@
|
|||
env:
|
||||
global:
|
||||
- CC_TEST_REPORTER_ID=e1449b0f2e8eba8f08c56a292243145925aeb4f521e5682667ac6d704829ba4c
|
||||
- GIT_COMMITTED_AT=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then git log -1 --pretty=format:%ct; else git log -1 --skip 1 --pretty=format:%ct; fi)
|
||||
language: node_js
|
||||
node_js:
|
||||
- "7"
|
||||
before_script:
|
||||
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||
- chmod +x ./cc-test-reporter
|
||||
script:
|
||||
- npm run test
|
||||
# Preferably you will run test-reporter on branch update events. But
|
||||
# if you setup travis to build PR updates only, you don't need to run
|
||||
# the line below
|
||||
- if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT; fi
|
||||
# In the case where travis is setup to build PR updates only,
|
||||
# uncomment the line below
|
||||
# - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
||||
|
|
24
LICENSE
Normal file
24
LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
24
README.md
24
README.md
|
@ -1,6 +1,6 @@
|
|||
# json-query-chain
|
||||
|
||||
[](https://travis-ci.org/sharpshark28/json-query-chain) [](https://badge.fury.io/js/json-query-chain)
|
||||
[](https://travis-ci.org/sharpshark28/json-query-chain) [](https://badge.fury.io/js/json-query-chain)  [](https://codeclimate.com/github/sharpshark28/json-query-chain/maintainability)
|
||||
|
||||
Chain queries onto POJOs to return precise results.
|
||||
|
||||
|
@ -32,9 +32,21 @@ Currently supports booleans and strings. (See [#1](https://github.com/sharpshark
|
|||
.search('name', 'steele')
|
||||
```
|
||||
|
||||
#### Sort
|
||||
#### Filter
|
||||
|
||||
Currently supports booleans and strings. (See [#1](https://github.com/sharpshark28/json-query-chain/issues/2) for Integer Support)
|
||||
Simpler version of search using a custom function in the chain.
|
||||
|
||||
```javascript
|
||||
.filter(a => a.age >= 21)
|
||||
```
|
||||
|
||||
##### By Key
|
||||
|
||||
```javascript
|
||||
.filterBy('age', x => x >= 21)
|
||||
```
|
||||
|
||||
#### Sort
|
||||
|
||||
##### By Boolean
|
||||
|
||||
|
@ -48,6 +60,12 @@ Currently supports booleans and strings. (See [#1](https://github.com/sharpshark
|
|||
.sort('name')
|
||||
```
|
||||
|
||||
##### By Number
|
||||
|
||||
```javascript
|
||||
.sort('netWorth')
|
||||
```
|
||||
|
||||
#### Pagination
|
||||
|
||||
Page 1 with 5 results per page.
|
||||
|
|
1
coverage.svg
Normal file
1
coverage.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="114" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h62v20H0z"/><path fill="#4C1" d="M62 0h52v20H62z"/><path fill="url(#b)" d="M0 0h114v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,DejaVu Sans,Geneva,sans-serif" font-size="11"><text x="31" y="15" fill="#010101" fill-opacity=".3">coverage</text><text x="31" y="14">coverage</text><text x="87" y="15" fill="#010101" fill-opacity=".3">97.22%</text><text x="87" y="14">97.22%</text></g></svg>
|
After Width: | Height: | Size: 735 B |
68
index.js
68
index.js
|
@ -1,57 +1,55 @@
|
|||
module.exports = class Query {
|
||||
constructor (data) {
|
||||
this.data = data.map(item => {
|
||||
item.sortScore = 0;
|
||||
return item;
|
||||
});
|
||||
};
|
||||
item.sortScore = 0
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
get results () {
|
||||
return this.data;
|
||||
};
|
||||
return this.data
|
||||
}
|
||||
|
||||
filter (func) {
|
||||
this.data = this.data.filter(func);
|
||||
return this;
|
||||
};
|
||||
this.data = this.data.filter(func)
|
||||
return this
|
||||
}
|
||||
|
||||
filterBy (key, func) {
|
||||
this.data = this.data.filter(item => func(item[key]));
|
||||
return this;
|
||||
};
|
||||
this.data = this.data.filter(item => func(item[key]))
|
||||
return this
|
||||
}
|
||||
|
||||
search (key, term, score = 0) {
|
||||
switch (typeof term) {
|
||||
case 'boolean':
|
||||
this.data = this.data.filter(item => item[key] === term);
|
||||
break;
|
||||
this.data = this.data.filter(item => item[key] === term)
|
||||
break
|
||||
case 'string':
|
||||
if (term.length >= 3) {
|
||||
this.data = this.data.filter(item => {
|
||||
let regFind = new RegExp(term, 'gi');
|
||||
let termMatches = (item[key].match(regFind) || []).length;
|
||||
item.sortScore += termMatches;
|
||||
return termMatches;
|
||||
});
|
||||
let regFind = new RegExp(term, 'gi')
|
||||
let termMatches = (item[key].match(regFind) || []).length
|
||||
item.sortScore += termMatches
|
||||
return termMatches
|
||||
})
|
||||
break
|
||||
}
|
||||
break;
|
||||
return this
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
sort (key = 'sortScore') {
|
||||
this.data = this.data.sort((a, b) => {
|
||||
if (a[key] < b[key]) return -1;
|
||||
if (a[key] > b[key]) return 1;
|
||||
return 0;
|
||||
});
|
||||
return this;
|
||||
};
|
||||
if (a[key] < b[key]) return -1
|
||||
if (a[key] > b[key]) return 1
|
||||
return 0
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
paginate (page = 1, perPage = 10) {
|
||||
let min = page * perPage - perPage;
|
||||
let max = min + perPage;
|
||||
this.data = this.data.slice(min, max);
|
||||
return this;
|
||||
};
|
||||
};
|
||||
let min = page * perPage - perPage
|
||||
let max = min + perPage
|
||||
this.data = this.data.slice(min, max)
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,99 +1,109 @@
|
|||
const Query = require('./index');
|
||||
const TestData = require('./testdata.json');
|
||||
const Query = require('./index')
|
||||
const TestData = require('./testdata.json')
|
||||
|
||||
test('should not modify passed data without chain alterations', () => {
|
||||
let query = new Query(TestData)
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query).toMatchObject(TestData);
|
||||
});
|
||||
expect(query).toMatchObject(TestData)
|
||||
})
|
||||
|
||||
test('should paginate with default params', () => {
|
||||
let query = new Query(TestData)
|
||||
.paginate()
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query.length).toBe(9);
|
||||
});
|
||||
expect(query.length).toBe(9)
|
||||
})
|
||||
|
||||
test('should paginate with custom page length', () => {
|
||||
let query = new Query(TestData)
|
||||
.paginate(1, 3)
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query.length).toBe(3);
|
||||
expect(query.length).toBe(3)
|
||||
expect(query[0].name).toBe('Haynes Meadows')
|
||||
});
|
||||
})
|
||||
|
||||
test('should paginate to second page with custom page length', () => {
|
||||
let query = new Query(TestData)
|
||||
.paginate(2, 3)
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query.length).toBe(3);
|
||||
expect(query.length).toBe(3)
|
||||
expect(query[0].name).toBe('Howard Buckley')
|
||||
});
|
||||
})
|
||||
|
||||
test('should search by boolean isActive', () => {
|
||||
let query = new Query(TestData)
|
||||
.search('isActive', true)
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query.length).toBe(4);
|
||||
});
|
||||
expect(query.length).toBe(4)
|
||||
})
|
||||
|
||||
test('should search by name', () => {
|
||||
let query = new Query(TestData)
|
||||
.search('name', 'steele')
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query.length).toBe(2);
|
||||
});
|
||||
expect(query.length).toBe(2)
|
||||
})
|
||||
|
||||
test('should sort by boolean isActive', () => {
|
||||
let query = new Query(TestData)
|
||||
.sort('isActive')
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query[0].name).toBe('Katelyn Steele');
|
||||
});
|
||||
expect(query[0].name).toBe('Katelyn Steele')
|
||||
})
|
||||
|
||||
test('should sort by number netWorth', () => {
|
||||
let query = new Query(TestData)
|
||||
.sort('netWorth')
|
||||
.results
|
||||
|
||||
expect(query[0].name).toBe('Howard Buckley') // Negative
|
||||
expect(query[1].name).toBe('Natalia Petty') // 0
|
||||
expect(query[query.length - 1].name).toBe('Newman Mays') // Richest
|
||||
})
|
||||
|
||||
test('should sort by string name', () => {
|
||||
let query = new Query(TestData)
|
||||
.sort('name')
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query[0].name).toBe('Dudley Conner');
|
||||
});
|
||||
expect(query[0].name).toBe('Dudley Conner')
|
||||
})
|
||||
|
||||
test('should filter', () => {
|
||||
let isAgeOver33 = a => a.age > 33;
|
||||
let isAgeOver33 = a => a.age > 33
|
||||
|
||||
let query = new Query(TestData)
|
||||
.filter(isAgeOver33)
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query[0].name).toBe('Howard Buckley');
|
||||
});
|
||||
expect(query[0].name).toBe('Howard Buckley')
|
||||
})
|
||||
|
||||
test('should filter by key', () => {
|
||||
let isNumGT33 = num => num > 33;
|
||||
let isNumGT33 = num => num > 33
|
||||
|
||||
let query = new Query(TestData)
|
||||
.filterBy('age', isNumGT33)
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query[0].name).toBe('Howard Buckley');
|
||||
});
|
||||
expect(query[0].name).toBe('Howard Buckley')
|
||||
})
|
||||
|
||||
test('should chain everything together', () => {
|
||||
let query = new Query(TestData)
|
||||
.search('isActive', true)
|
||||
.sort('name')
|
||||
.paginate(1, 2)
|
||||
.results;
|
||||
.results
|
||||
|
||||
expect(query.length).toBe(2);
|
||||
expect(query[0].name).toBe('Dudley Conner');
|
||||
expect(query[query.length - 1].name).toBe('Haynes Meadows');
|
||||
});
|
||||
expect(query.length).toBe(2)
|
||||
expect(query[0].name).toBe('Dudley Conner')
|
||||
expect(query[query.length - 1].name).toBe('Haynes Meadows')
|
||||
})
|
||||
|
|
18
package.json
18
package.json
|
@ -1,22 +1,32 @@
|
|||
{
|
||||
"name": "json-query-chain",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.3",
|
||||
"description": "Chain queries onto POJOs to return precise results.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
"test": "jest --coverage && npm run badge",
|
||||
"badge": "lcov-badge coverage/lcov.info -o coverage.svg",
|
||||
"lint": "eslint ./*.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/sharpshark28/json-query-chain.git"
|
||||
},
|
||||
"author": "Joe Wroten <joe@wroten.me>",
|
||||
"author": "Ava Wroten <ava@wroten.me>",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sharpshark28/json-query-chain/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sharpshark28/json-query-chain#readme",
|
||||
"devDependencies": {
|
||||
"jest": "^20.0.4"
|
||||
"eslint": "^4.18.1",
|
||||
"eslint-config-standard": "^11.0.0",
|
||||
"eslint-plugin-import": "^2.9.0",
|
||||
"eslint-plugin-jest": "^21.12.2",
|
||||
"eslint-plugin-node": "^6.0.0",
|
||||
"eslint-plugin-promise": "^3.6.0",
|
||||
"eslint-plugin-standard": "^3.0.1",
|
||||
"jest": "^20.0.4",
|
||||
"lcov-badge": "^1.0.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"_id": "5928038b69b33613f3577487",
|
||||
"isActive": true,
|
||||
"age": 20,
|
||||
"netWorth": 54200.49,
|
||||
"name": "Haynes Meadows",
|
||||
"tags": [
|
||||
"et",
|
||||
|
@ -18,6 +19,7 @@
|
|||
"_id": "5928038ba2400e7e09550991",
|
||||
"isActive": false,
|
||||
"age": 22,
|
||||
"netWorth": 11900,
|
||||
"name": "Katelyn Steele",
|
||||
"tags": [
|
||||
"cupidatat",
|
||||
|
@ -33,6 +35,7 @@
|
|||
"_id": "5928038bff4df5c29016be22",
|
||||
"isActive": false,
|
||||
"age": 29,
|
||||
"netWorth": 0,
|
||||
"name": "Natalia Petty",
|
||||
"tags": [
|
||||
"nulla",
|
||||
|
@ -48,6 +51,7 @@
|
|||
"_id": "5928038b496f64e646cb8d69",
|
||||
"isActive": false,
|
||||
"age": 34,
|
||||
"netWorth": -5000.2,
|
||||
"name": "Howard Buckley",
|
||||
"tags": [
|
||||
"qui",
|
||||
|
@ -63,6 +67,7 @@
|
|||
"_id": "5928038b4d214186ba1e7fa2",
|
||||
"isActive": false,
|
||||
"age": 22,
|
||||
"netWorth": 401512.99,
|
||||
"name": "Jenkins Mosley",
|
||||
"tags": [
|
||||
"adipisicing",
|
||||
|
|
Loading…
Add table
Reference in a new issue