Skip to content

Commit 27902db

Browse files
author
Lucas Cosmo Rocha
committed
Additioned parsers methods into typescript interface.
1 parent b8ea3fa commit 27902db

File tree

12 files changed

+920
-79
lines changed

12 files changed

+920
-79
lines changed

index.d.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@ export = queryStringsParser
44
declare namespace queryStringsParser {
55
export interface QueryStringsParser {
66
(options?: IOptions): any
7+
8+
parseFields(query?: string | object, options?: IOptions): any
9+
10+
parseSort(query?: string | object, options?: IOptions): any
11+
12+
parsePagination(query?: string | object, pagination?: IPagination, use_page?: boolean): any
13+
14+
parseFilter(query?: string | object, options?: IOptions): any
15+
16+
parseDate(query?: string | object, date_field?: IDateField): any
717
}
818

919
export interface IOptions {
1020
default?: IDefault
1121
use_page?: boolean
1222
client_db?: string
13-
date_field?: string
23+
date_field?: IDateField
1424
}
1525

1626
export interface IDefault {
@@ -25,4 +35,9 @@ declare namespace queryStringsParser {
2535
skip?: number
2636
limit?: number
2737
}
38+
39+
export interface IDateField {
40+
start_at?: string
41+
end_at?: string
42+
}
2843
}

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ exports = module.exports.parseSort = function (_query, _default) {
1515
return read.parseSort(_query, _default)
1616
}
1717

18-
exports = module.exports.parsePagination = function (_query, _default) {
19-
return read.parsePagination(_query, _default)
18+
exports = module.exports.parsePagination = function (_query, _default, _use_page) {
19+
return read.parsePagination(_query, _default, _use_page)
2020
}
2121

2222
exports = module.exports.parseFilter = function (_query, _default) {

lib/mapper/filters.js

Lines changed: 98 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ function filters(query, options) {
77
delete query.skip
88
delete query.page
99

10-
var result = { $and: [], $or: [] }
10+
const result = {$and: [], $or: []}
1111

1212
if (Object.keys(query).length > 0) {
1313
result.$and = result.$and.concat(parseDate(query, options))
1414
delete query.start_at
1515
delete query.end_at
1616
delete query.period
17-
for (var elem in query) {
17+
for (const elem in query) {
1818
if (query[elem] instanceof Array) {
1919
query[elem].forEach(function (param) {
2020
result['$and'].push(processQuery(elem, param))
2121
})
2222
} else {
23-
if (query[elem] instanceof Object) { }
24-
else if (query[elem].includes(',')) {
23+
if (query[elem] instanceof Object) {
24+
} else if (query[elem].includes(',')) {
2525
result['$or'] = result['$or'].concat(splitByCommas(elem, query[elem]))
2626
} else {
2727
Object.assign(result, processQuery(elem, query[elem]))
@@ -37,7 +37,7 @@ function filters(query, options) {
3737

3838
function processQuery(key, value) {
3939
key = key.replace(/([^\w\s,.])|(\s{1,})|(^\.{1,})|\.{1,}$/gi, '')
40-
var param = {}
40+
const param = {}
4141
param[key] = treatValue(value)
4242
return param
4343
}
@@ -55,20 +55,22 @@ function treatValue(value) {
5555
function isDate(value) {
5656
return /^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))$/.test(value)
5757
}
58+
5859
function isDateTime(value) {
59-
return /^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))T(0[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$/.test(value)
60+
return /^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))T(0[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$/
61+
.test(value)
6062
}
6163

6264
function getCompareOperator(value) {
63-
if (value.startsWith('gte')) return { '$gte': treatValue(value.slice(4)) }
64-
else if (value.startsWith('gt')) return { '$gt': treatValue(value.slice(3)) }
65-
else if (value.startsWith('lte')) return { '$lte': treatValue(value.slice(4)) }
66-
else if (value.startsWith('lt')) return { '$lt': treatValue(value.slice(3)) }
65+
if (value.startsWith('gte')) return {'$gte': treatValue(value.slice(4))}
66+
else if (value.startsWith('gt')) return {'$gt': treatValue(value.slice(3))}
67+
else if (value.startsWith('lte')) return {'$lte': treatValue(value.slice(4))}
68+
else if (value.startsWith('lt')) return {'$lt': treatValue(value.slice(3))}
6769
return value
6870
}
6971

7072
function splitByCommas(key, value) {
71-
var result = []
73+
const result = []
7274
value = value.split(',')
7375
value.forEach(function (elem) {
7476
result.push(processQuery(key, elem))
@@ -78,40 +80,75 @@ function splitByCommas(key, value) {
7880

7981
function buildRegEx(value) {
8082
value = value.replace(/(^\*{2,})|\*{2,}$/gi, '*')
81-
var result = { '$options': 'i' }
83+
const result = {'$options': 'i'}
8284
if (!value.startsWith('*') && value.endsWith('*')) result.$regex = '^'.concat(value.replace(/([*])/gi, ''))
8385
else if (value.startsWith('*') && !value.endsWith('*')) result.$regex = value.replace(/([*])/gi, '').concat('&')
8486
else result.$regex = value.replace(/([*])/gi, '')
8587
return result
8688
}
8789

8890
function parseDate(query, options) {
89-
var result = []
91+
const result = []
9092
if (query.start_at === 'today') query.start_at = dateToString(new Date())
9193
if (query.end_at === 'today') query.end_at = dateToString(new Date())
9294
if (query.period) {
93-
(query.end_at && (isDate(query.end_at) || isDateTime(query.end_at))) ?
95+
if (query.start_at) {
96+
let date_start = query.start_at
97+
// If the start_at is a datetime, its necessary convert to date format before get date end by period.
98+
if (isDateTime(date_start)) date_start = dateTimeToDate(date_start)
99+
94100
result.push(
95-
processQuery(options.date_field.end_at, 'lt:'.concat(normalizeDate(query.end_at, false))),
96-
processQuery(options.date_field.start_at, 'gte:'.concat(normalizeDate(
97-
getDateStartByPeriod(query.period, new Date(query.end_at)))))) :
101+
processQuery(
102+
options.date_fields.end_at,
103+
'lt:'.concat(
104+
normalizeDate(getDateEndByPeriod(query.period, new Date(date_start)), false))),
105+
processQuery(
106+
options.date_fields.start_at,
107+
'gte:'.concat(query.start_at)))
108+
return result
109+
}
110+
111+
if (query.end_at) {
112+
let date_end = query.end_at
113+
// If the end_at is a datetime, its necessary convert to date format before get date start by period.
114+
if (isDateTime(date_end)) date_end = dateTimeToDate(date_end)
115+
98116
result.push(
99-
processQuery(options.date_field.end_at, 'lt:now'),
100-
processQuery(options.date_field.start_at, 'gte:'.concat(
101-
getDateStartByPeriod(query.period, new Date()))))
117+
processQuery(
118+
options.date_fields.end_at,
119+
'lt:'.concat(
120+
isDate(query.end_at) ? normalizeDate(query.end_at, false) : query.end_at)),
121+
processQuery(
122+
options.date_fields.start_at,
123+
'gte:'.concat(getDateStartByPeriod(query.period, new Date(date_end)))))
124+
125+
return result
126+
}
127+
128+
let date_end = dateTimeToDate(new Date().toISOString())
129+
130+
result.push(
131+
processQuery(
132+
options.date_fields.end_at,
133+
'lt:'.concat(normalizeDate(date_end, false))),
134+
processQuery(
135+
options.date_fields.start_at,
136+
'gte:'.concat(
137+
normalizeDate(getDateStartByPeriod(query.period, new Date(date_end)), true))))
138+
102139
return result
103140
}
104141

105142
if (query.start_at && (isDate(query.start_at) || isDateTime(query.start_at))) {
106143
if (query.end_at && (isDate(query.end_at) || isDateTime(query.end_at))) {
107144
result.push(
108-
processQuery(options.date_field.end_at, 'lt:'.concat(query.end_at)))
145+
processQuery(options.date_fields.end_at, 'lt:'.concat(query.end_at)))
109146
} else {
110147
result.push(
111-
processQuery(options.date_field.end_at, 'lt:now'))
148+
processQuery(options.date_fields.end_at, 'lt:now'))
112149
}
113150
result.push(
114-
processQuery(options.date_field.start_at, 'gte:'.concat(query.start_at)))
151+
processQuery(options.date_fields.start_at, 'gte:'.concat(query.start_at)))
115152
}
116153
return result
117154
}
@@ -124,31 +161,60 @@ function getDateStartByPeriod(period, end_at) {
124161
return dateToString(new Date(
125162
end_at.getFullYear(),
126163
end_at.getMonth(),
127-
(end_at.getDate() - onlyNumbers(period))))
164+
(end_at.getDate() - onlyNumbers(period) + 1)))
128165
case 'w':
129166
return dateToString(new Date(
130167
end_at.getFullYear(),
131168
end_at.getMonth(),
132-
(end_at.getDate() - 7 * onlyNumbers(period))))
169+
(end_at.getDate() - 7 * onlyNumbers(period) + 1)))
133170
case 'm':
134171
return dateToString(new Date(
135172
end_at.getFullYear(),
136173
(end_at.getMonth() - onlyNumbers(period)),
137-
end_at.getDate()))
174+
end_at.getDate() + 1))
138175
case 'y':
139176
return dateToString(new Date(
140177
(end_at.getFullYear() - onlyNumbers(period)),
141178
end_at.getMonth(),
142-
end_at.getDate()))
179+
end_at.getDate() + 1))
143180
}
144181
}
145182

146-
function dateToString(date) {
147-
return `${date.getFullYear()}-${date.getMonth() + 1}-${formatDay(date.getDate())}`
183+
function getDateEndByPeriod(period, start_at) {
184+
if (!(/^[0-9]{1,}[d|w|m|y]$/.test(period))) return dateToString(new Date())
185+
186+
switch (period.slice(-1)) {
187+
case 'd':
188+
return dateToString(new Date(
189+
start_at.getFullYear(),
190+
start_at.getMonth(),
191+
(start_at.getDate() + onlyNumbers(period) + 1)))
192+
case 'w':
193+
return dateToString(new Date(
194+
start_at.getFullYear(),
195+
start_at.getMonth(),
196+
(start_at.getDate() + 7 * onlyNumbers(period) + 1)))
197+
case 'm':
198+
return dateToString(new Date(
199+
start_at.getFullYear(),
200+
(start_at.getMonth() + onlyNumbers(period)),
201+
start_at.getDate() + 1))
202+
case 'y':
203+
return dateToString(new Date(
204+
(start_at.getFullYear() + onlyNumbers(period)),
205+
start_at.getMonth(),
206+
start_at.getDate() + 1))
207+
}
208+
}
209+
210+
function dateTimeToDate(date) {
211+
return date.substr(0, 10)
148212
}
149213

150-
function formatDay(day) {
151-
return day < 10 ? '0'.concat(day) : day
214+
function dateToString(date) {
215+
return `${date.getFullYear()}-`
216+
.concat(`${(date.getMonth() + 1) > 9 ? (date.getMonth() + 1) : '0'.concat((date.getMonth() + 1))}-`)
217+
.concat(`${date.getDate() > 9 ? date.getDate() : '0'.concat(date.getDate())}`)
152218
}
153219

154220
function onlyNumbers(value) {
@@ -169,3 +235,4 @@ function validate_filters(_values, _default) {
169235
exports = module.exports = {
170236
filters: filters
171237
}
238+

lib/read.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict'
22

3+
const url = require('url')
34
const pagination = require('./mapper/pagination')
45
const fields = require('./mapper/fields')
56
const ordination = require('./mapper/ordination')
@@ -64,26 +65,33 @@ function validate_options(params) {
6465

6566
exports = module.exports.parseFields = function (query, fields_default) {
6667
const options = validate_options({'default': {'fields': fields_default}})
67-
return fields.fields(query, options)
68+
return fields.fields(stringToJson(query), options)
6869
}
6970

7071
exports = module.exports.parseSort = function (query, sort_default) {
7172
const options = validate_options({'default': {'sort': sort_default}})
72-
return ordination.sort(query, options)
73+
return ordination.sort(stringToJson(query), options)
7374
}
7475

75-
exports = module.exports.parsePagination = function (query, pagination_default) {
76-
const options = validate_options({'default': {'pagination': pagination_default}})
77-
return pagination.pagination(query, options)
76+
exports = module.exports.parsePagination = function (query, pagination_default, use_page) {
77+
const options = validate_options({
78+
'default': {'pagination': pagination_default},
79+
'use_page': use_page
80+
})
81+
return pagination.pagination(stringToJson(query), options)
7882
}
7983

8084
exports = module.exports.parseFilter = function (query, filters_default, date_fields) {
8185
const options = validate_options({'default': {'filters': filters_default}, 'date_fields': date_fields})
82-
return filters.filters(query, options)
86+
return filters.filters(stringToJson(query), options)
8387
}
8488

8589
exports = module.exports.parseDate = function (query, date_fields) {
8690
const options = validate_options({'date_fields': date_fields})
87-
return filters.filters(query, options)
91+
return filters.filters(stringToJson(query), options)
8892
}
8993

94+
function stringToJson(query) {
95+
if (typeof query === 'string') return url.parse(query, true).query
96+
return query
97+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "query-strings-parser",
3-
"version": "1.1.2",
3+
"version": "2.0.0",
44
"description": "Middleware to transform query strings in a format that is recognized by the MongoDB, MySQL and other databases...",
55
"license": "MIT",
66
"main": "index.js",

0 commit comments

Comments
 (0)