Skip to content

Commit 1ad9ee9

Browse files
committed
add support for comma delimited string
update README
1 parent 0e12eb9 commit 1ad9ee9

File tree

3 files changed

+180
-13
lines changed

3 files changed

+180
-13
lines changed

README.md

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
JSON API query parser for MongoDB/Mongoose queries.
66

7-
WIP
7+
Convert query object from any querystring parser to MongoDB/Mongoose queries.
88

99
## Installation
1010
```bash
@@ -13,9 +13,99 @@ npm install --save json-api-mongo-parser
1313

1414
## Usage
1515

16-
Some examples are available in [ tests folders](https://github.com/danivek/json-api-mongo-parser/blob/master/test/)
16+
```javascript
17+
// Input query object for the article resource
18+
var query = {
19+
fields: {
20+
article: 'title,body', // Can be comma delimited string or Array of string
21+
people: 'firstname,lastname',
22+
comment: 'title,body'
23+
},
24+
sort: '-title,body,+created', // Can be comma delimited string or Array of string
25+
page: {
26+
offset: 2,
27+
limit: 10
28+
},
29+
include: 'author,comments.tag,comments.author,comments.author.tag' // Can be comma delimited string or Array of string
30+
}
31+
```
32+
33+
```javascript
34+
var JSONAPIMongoParser = require(json-api-mongo-parser);
1735

18-
More examples are coming soon.
36+
var jsonApiMongoParser = new JSONAPIMongoParser({
37+
article: {
38+
relationships: { // Declaring relationships with its type
39+
author: 'people',
40+
comments: 'comment',
41+
}
42+
},
43+
comment: {
44+
relationships: {
45+
author: 'people',
46+
tag: 'tag'
47+
}
48+
},
49+
people: {
50+
relationships: {
51+
tag: 'tag'
52+
}
53+
}
54+
});
55+
56+
// Parse
57+
jsonApiMongoParser.parse('article', query);
58+
```
59+
Output mongo query for the article resource :
60+
61+
```javascript
62+
{
63+
select: {
64+
title: 1,
65+
body: 1,
66+
author: 1,
67+
comments: 1
68+
},
69+
sort: {
70+
title: -1,
71+
body: 1,
72+
created: 1
73+
},
74+
page: {
75+
skip: 2,
76+
limit: 10
77+
},
78+
populate: [{
79+
path: 'author',
80+
select: {
81+
firstname: 1,
82+
lastname: 1,
83+
tag: 1
84+
}
85+
}, {
86+
path: 'comments',
87+
populate: [{
88+
path: 'tag'
89+
}, {
90+
path: 'author',
91+
populate: [{
92+
path: 'tag'
93+
}],
94+
select: {
95+
firstname: 1,
96+
lastname: 1,
97+
tag: 1
98+
}
99+
}],
100+
select: {
101+
title: 1,
102+
body: 1,
103+
author: 1,
104+
tag: 1
105+
}
106+
}]
107+
}
108+
```
19109

20110
## Requirements
21111

@@ -24,4 +114,3 @@ json-api-mongo-parser only use ECMAScript 2015 (ES6) features supported natively
24114
## License
25115

26116
[MIT](https://github.com/danivek/json-api-mongo-parser/blob/master/LICENSE)
27-

lib/JSONAPIMongoParser.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ module.exports = class JSONAPIMongoParser {
1212

1313
if (selectQuery) {
1414
if (selectQuery[type]) {
15-
selectQuery[type].forEach(field => select[field] = 1);
15+
let fields = selectQuery[type];
16+
// Support for input comma delimited string
17+
if (_.isString(fields)) {
18+
fields = fields.split(',');
19+
}
20+
21+
fields.forEach(field => select[field] = 1);
1622
}
1723

1824
// Always select relationships if defined
@@ -26,6 +32,11 @@ module.exports = class JSONAPIMongoParser {
2632
parseSort(sortQuery) {
2733
const sort = {};
2834

35+
// Support for input comma delimited string
36+
if (_.isString(sortQuery)) {
37+
sortQuery = sortQuery.split(',');
38+
}
39+
2940
sortQuery.forEach((sortField) => {
3041
let field = sortField;
3142
const operator = sortField.charAt(0);
@@ -64,6 +75,11 @@ module.exports = class JSONAPIMongoParser {
6475
const output = [];
6576
const flatOptions = this._flattenOptions();
6677

78+
// Support for input comma delimited string
79+
if (_.isString(includeQuery)) {
80+
includeQuery = includeQuery.split(',');
81+
}
82+
6783
// Ignore include if no resources type are registered
6884
if (this.options[type]) {
6985
// Convert array of delimited string to tree

test/unit/JSONAPIMongoParser.test.js

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('JSONAPIMongoParser', function() {
1010
let parser = new JSONAPIMongoParser();
1111

1212
describe('parseFields', function() {
13-
it('should parse fields query for a resource', function(done) {
13+
it('should parse input fields array', function(done) {
1414
const fieldsQuery = {
1515
article: ['title', 'body']
1616
};
@@ -22,6 +22,18 @@ describe('JSONAPIMongoParser', function() {
2222
done();
2323
});
2424

25+
it('should parse input fields string', function(done) {
26+
const fieldsQuery = {
27+
article: 'title,body'
28+
};
29+
const select = parser.parseFields('article', fieldsQuery);
30+
expect(select).to.eql({
31+
title: 1,
32+
body: 1
33+
});
34+
done();
35+
});
36+
2537
it('should parse fields query and always select relationships if it was defined on the resource', function(done) {
2638
let parser = new JSONAPIMongoParser({
2739
article: {
@@ -46,7 +58,7 @@ describe('JSONAPIMongoParser', function() {
4658
});
4759

4860
describe('parseSort', function() {
49-
it('should parse sort query', function(done) {
61+
it('should parse input sort array', function(done) {
5062
const sortQuery = ['-title', 'body', '+created'];
5163
const sort = parser.parseSort(sortQuery);
5264
expect(sort).to.eql({
@@ -56,6 +68,17 @@ describe('JSONAPIMongoParser', function() {
5668
});
5769
done();
5870
});
71+
72+
it('should parse input sort string', function(done) {
73+
const sortQuery = '-title,body,+created';
74+
const sort = parser.parseSort(sortQuery);
75+
expect(sort).to.eql({
76+
title: -1,
77+
body: 1,
78+
created: 1
79+
});
80+
done();
81+
});
5982
});
6083

6184
describe('parsePage', function() {
@@ -119,7 +142,7 @@ describe('JSONAPIMongoParser', function() {
119142
done();
120143
});
121144

122-
it('should parse all include query', function(done) {
145+
it('should parse input include array', function(done) {
123146
const parserAllInclude = new JSONAPIMongoParser({
124147
article: {
125148
relationships: {
@@ -158,6 +181,45 @@ describe('JSONAPIMongoParser', function() {
158181
done();
159182
});
160183

184+
it('should parse input include string', function(done) {
185+
const parserAllInclude = new JSONAPIMongoParser({
186+
article: {
187+
relationships: {
188+
author: 'people',
189+
comments: 'comment',
190+
}
191+
},
192+
comment: {
193+
relationships: {
194+
author: 'people',
195+
tag: 'tag'
196+
}
197+
},
198+
people: {
199+
relationships: {
200+
tag: 'tag'
201+
}
202+
},
203+
tag: {}
204+
});
205+
const includeQuery = 'author,comments.tag,comments.author,comments.author.tag';
206+
const populate = parserAllInclude.parseInclude('article', includeQuery);
207+
expect(populate).to.eql([{
208+
path: "author"
209+
}, {
210+
path: "comments",
211+
populate: [{
212+
path: 'tag'
213+
}, {
214+
path: "author",
215+
populate: [{
216+
path: "tag"
217+
}]
218+
}]
219+
}])
220+
done();
221+
});
222+
161223
it('should parse all include query with fields query', function(done) {
162224
const parserAllInclude = new JSONAPIMongoParser({
163225
article: {
@@ -245,16 +307,16 @@ describe('JSONAPIMongoParser', function() {
245307

246308
const query = {
247309
fields: {
248-
article: ['title', 'body'],
249-
people: ['firstname', 'lastname'],
250-
comment: ['title', 'body']
310+
article: 'title,body',
311+
people: 'firstname,lastname',
312+
comment: 'title,body'
251313
},
252-
sort: ['-title', 'body', '+created'],
314+
sort: '-title,body,+created',
253315
page: {
254316
offset: 2,
255317
limit: 10
256318
},
257-
include: ['author', 'comments.tag', 'comments.author', 'comments.author.tag']
319+
include: 'author,comments.tag,comments.author,comments.author.tag'
258320
}
259321
const parseQuery = jsonApiMongoParser.parse('article', query);
260322
expect(parseQuery).to.eql({

0 commit comments

Comments
 (0)