moved api from monorepo
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
const advancedResults = (model, populate) => async (req, res, next) => {
|
||||
if (req.originalUrl.indexOf('admin') === -1)
|
||||
req.query = {
|
||||
...req.query,
|
||||
$and: [{accessedBy: {$elemMatch: {user: req.user.id}}}],
|
||||
}
|
||||
|
||||
|
||||
if (req.query.search === undefined) req.query.search = ''
|
||||
if (req.query.search)
|
||||
req.query = {...req.query, $text: {$search: req.query.search}}
|
||||
|
||||
const filterAndInGame = ['genre', 'os', 'developer', 'publisher', 'series', 'intel', 'wine', 'controller', 'store', 'soundtrack', 'playStatus', 'rating', 'ratinggte', 'ratinglte', 'steamRating', 'steamRatinggte', 'steamRatinglte']
|
||||
|
||||
filterAndInGame.map((filter) => {
|
||||
if (req.query[filter] === undefined) req.query[filter] = ''
|
||||
if (req.query[filter]) {
|
||||
let newFilter
|
||||
if (filter === 'os') {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr, index, arr) => {
|
||||
const key = `${[filter]}.${arr[index]}`.toLowerCase()
|
||||
prev.push({[key]: true})
|
||||
return prev
|
||||
}, [])
|
||||
} else if (filter === 'store' || filter === 'soundtrack' || filter === 'playStatus') {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({accessedBy: {$elemMatch: {[filter]: curr}}})
|
||||
return prev
|
||||
}, [])
|
||||
} else if (filter === 'rating') {
|
||||
if (Object.hasOwn(req.query[filter], 'gte')) {
|
||||
newFilter = req.query[filter]['gte'].split(',').reduce((prev, curr) => {
|
||||
prev.push({accessedBy: {$elemMatch: {rating: {$gte: Number(curr)}}}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.rating = `gte${req.query[filter]['gte']}`
|
||||
} else if (Object.hasOwn(req.query[filter], 'lte')) {
|
||||
newFilter = req.query[filter]['lte'].split(',').reduce((prev, curr) => {
|
||||
prev.push({accessedBy: {$elemMatch: {rating: {$lte: Number(curr)}}}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.rating = `lte${req.query[filter]['lte']}`
|
||||
} else {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({accessedBy: {$elemMatch: {rating: Number(curr)}}})
|
||||
return prev
|
||||
}, [])
|
||||
}
|
||||
} else if (filter === 'ratinggte') {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({accessedBy: {$elemMatch: {rating: {$gte: Number(curr)}}}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.rating = req.query.ratinggte
|
||||
} else if (filter === 'ratinglte') {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({accessedBy: {$elemMatch: {rating: {$lte: Number(curr)}}}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.rating = req.query.ratinglte
|
||||
} else if (filter === 'steamRating') {
|
||||
if (Object.hasOwn(req.query[filter], 'gte')) {
|
||||
newFilter = req.query[filter]['gte'].split(',').reduce((prev, curr) => {
|
||||
prev.push({steamRating: {$gte: Number(curr)}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.steamRating = `gte${req.query[filter]['gte']}`
|
||||
} else if (Object.hasOwn(req.query[filter], 'lte')) {
|
||||
newFilter = req.query[filter]['lte'].split(',').reduce((prev, curr) => {
|
||||
prev.push({steamRating: {$lte: Number(curr)}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.steamRating = `lte${req.query[filter]['lte']}`
|
||||
} else {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({steamRating: Number(curr)})
|
||||
return prev
|
||||
}, [])
|
||||
}
|
||||
} else if (filter === 'steamRatinggte') {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({steamRating: {$gte: Number(curr)}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.steamRating = req.query.steamRatinggte
|
||||
} else if (filter === 'steamRatinglte') {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({steamRating: {$lte: Number(curr)}})
|
||||
return prev
|
||||
}, [])
|
||||
req.query.steamRating = req.query.steamRatinglte
|
||||
} else {
|
||||
newFilter = req.query[filter].split(',').reduce((prev, curr) => {
|
||||
prev.push({[filter]: curr})
|
||||
return prev
|
||||
}, [])
|
||||
}
|
||||
newFilter.forEach(element => req.query.$and.push(element))
|
||||
}
|
||||
})
|
||||
|
||||
let query
|
||||
|
||||
// Copy req.query
|
||||
const reqQuery = {...req.query}
|
||||
|
||||
// Fields to exclude
|
||||
const removeFields = [
|
||||
'select',
|
||||
'series',
|
||||
'developer',
|
||||
'publisher',
|
||||
'sort',
|
||||
'limit',
|
||||
'page',
|
||||
'search',
|
||||
'os',
|
||||
'playStatus',
|
||||
'store',
|
||||
'soundtrack',
|
||||
'genre',
|
||||
'controller',
|
||||
'rating',
|
||||
'ratinggte',
|
||||
'ratinglte',
|
||||
'steamRating',
|
||||
'steamRatinggte',
|
||||
'steamRatinglte',
|
||||
]
|
||||
|
||||
// Loop over removeFields and delete them from reqQuery
|
||||
removeFields.forEach((param) => delete reqQuery[param])
|
||||
|
||||
filterAndInGame.forEach((param) => {
|
||||
if (req.query[param] === '') delete reqQuery[param]
|
||||
})
|
||||
|
||||
// Create query String
|
||||
let queryStr = JSON.stringify(reqQuery)
|
||||
|
||||
// Create operators like gt, gte, etc...
|
||||
queryStr = queryStr.replace(
|
||||
/\b(gt|gte|lt|lte|in|all)\b/g,
|
||||
(match) => `$${match}`,
|
||||
)
|
||||
|
||||
queryStr = queryStr.replace(/\$\$/g, '$')
|
||||
|
||||
const total = await model.countDocuments(reqQuery)
|
||||
|
||||
// Finding resource
|
||||
query = model.find(JSON.parse(queryStr))
|
||||
|
||||
// Select Fields
|
||||
if (req.query.select) {
|
||||
const fields = req.query.select.split(',').join(' ')
|
||||
query = query.select(fields)
|
||||
}
|
||||
|
||||
// Sort
|
||||
if (req.query.sort) {
|
||||
const sortBy = req.query.sort.split(',').join(' ')
|
||||
query = query.sort(sortBy)
|
||||
} else {
|
||||
query = query.sort('series title')
|
||||
}
|
||||
|
||||
// Pagination
|
||||
let page = parseInt(req.query.page, 10) || 1
|
||||
const limit = parseInt(req.query.limit, 10) || 10
|
||||
|
||||
// This block figures out how many total pages there will be and if
|
||||
// the client is calling a page larger than the total pages
|
||||
let pages
|
||||
if (limit === 1) pages = total
|
||||
else if (total === 0) pages = 1
|
||||
else if (total % limit === 0) pages = (total - (total % limit)) / limit
|
||||
else pages = (total - (total % limit)) / limit + 1
|
||||
if (page > pages) page = pages
|
||||
|
||||
const startIndex = (page - 1) * limit
|
||||
const endIndex = page * limit
|
||||
|
||||
query = query.skip(startIndex).limit(limit)
|
||||
|
||||
if (populate) {
|
||||
query = query.populate(populate)
|
||||
}
|
||||
|
||||
// Executing query
|
||||
const results = await query
|
||||
|
||||
// Pagination result
|
||||
const pagination = {}
|
||||
|
||||
if (endIndex < total) {
|
||||
pagination.next = {
|
||||
page: page + 1,
|
||||
}
|
||||
}
|
||||
|
||||
if (startIndex > 0) {
|
||||
pagination.prev = {
|
||||
page: page - 1,
|
||||
}
|
||||
}
|
||||
|
||||
res.advancedResults = {
|
||||
success: true,
|
||||
searchParams: req.query.search,
|
||||
count: {
|
||||
gamesPerPage: results.length,
|
||||
totalGames: total,
|
||||
currentPage: page,
|
||||
pages,
|
||||
limit,
|
||||
},
|
||||
filters: {
|
||||
series: req.query.series,
|
||||
playStatus: req.query.playStatus,
|
||||
genre: req.query.genre,
|
||||
os: req.query.os,
|
||||
store: req.query.store,
|
||||
developer: req.query.developer,
|
||||
controller: req.query.controller,
|
||||
publisher: req.query.publisher,
|
||||
soundtrack: req.query.soundtrack,
|
||||
intel: req.query.intel,
|
||||
wine: req.query.wine,
|
||||
rating: req.query.rating,
|
||||
steamRating: req.query.steamRating,
|
||||
},
|
||||
pagination,
|
||||
data: results,
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export default advancedResults
|
||||
Reference in New Issue
Block a user