You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
734 lines
20 KiB
734 lines
20 KiB
const express = require('express')
|
|
const router = express.Router()
|
|
const path = require('path')
|
|
const fs = require('fs')
|
|
const ObjectId = require('mongodb').ObjectId
|
|
const async = require('async')
|
|
|
|
const Ajv = require('ajv')
|
|
const jsf = require('json-schema-faker')
|
|
|
|
// const CFG = require('../../config')
|
|
const TAG = 'REST'
|
|
|
|
const REST_CTX = {
|
|
models: [],
|
|
api: [
|
|
{method: 'GET', url: '/:collection', desc: ''},
|
|
{method: 'POST', url: '/:collection', desc: ''},
|
|
{method: 'PUT', url: '/:collection/:id', desc: ''},
|
|
{method: 'DELETE', url: '/:collection', desc: ''},
|
|
{method: 'GET', url: '/:collection/private/json-schema', desc: ''},
|
|
{method: 'GET', url: '/:collection/private/json-schema/fake', desc: ''}
|
|
]
|
|
}
|
|
|
|
jsf.extend('faker', function () {
|
|
return require('faker')
|
|
})
|
|
// router.use((req, res, next) => {
|
|
// console.log('API isAuth', req.isAuth)
|
|
// next()
|
|
// })
|
|
|
|
function initCollections (pCtx) {
|
|
pCtx.restapi = {}
|
|
fs.readdir(path.join(__dirname, './collections'), (pErr, pColls) => {
|
|
pColls.forEach((pColl) => {
|
|
if (/^__/.test(pColl)) return
|
|
let coll = require(path.join(__dirname, './collections', pColl, pColl))(pCtx)
|
|
if (pCtx.logEnabled) console.log(`[-] ${TAG} | Loading collection: ${coll.name}`)
|
|
// INIT INDEXES
|
|
coll.indexes = coll.indexes || []
|
|
coll.indexes.forEach((pIndex) => {
|
|
pCtx.db.collection(coll.name).createIndex(pIndex.keys, pIndex.options)
|
|
})
|
|
pCtx.restapi[coll.name] = coll
|
|
initRestApi(pCtx, coll)
|
|
REST_CTX.models.push(coll.name)
|
|
})
|
|
})
|
|
|
|
router.get('/__intern/collections', function (req, res, next) {
|
|
let all = []
|
|
for (let coll in pCtx.restapi) {
|
|
all.push({
|
|
coll: coll,
|
|
label: pCtx.restapi[coll].label,
|
|
icon: pCtx.restapi[coll].icon,
|
|
description: pCtx.restapi[coll].description
|
|
})
|
|
}
|
|
res.done(null, all.sort((a, b) => a.label.localeCompare(b.label)))
|
|
})
|
|
|
|
router.get('/', function (req, res, next) {
|
|
res.done(null, REST_CTX)
|
|
})
|
|
}
|
|
|
|
function initRestApi (pCtx, pColl) {
|
|
let collHandler = pCtx.db.collection(pColl.name)
|
|
let ajv = new Ajv({removeAdditional: true, allErrors: true})
|
|
let collValidator = ajv.compile(pColl.schema)
|
|
if (collValidator.error) {
|
|
console.error(collValidator)
|
|
process.exit(1)
|
|
}
|
|
|
|
router.use(function (req, res, next) {
|
|
generateFilterObject(req)
|
|
next()
|
|
})
|
|
|
|
pColl.__services = {
|
|
read: null,
|
|
readOne: null,
|
|
create: null,
|
|
update: null,
|
|
delete: null
|
|
}
|
|
|
|
pColl.__db = collHandler
|
|
|
|
pColl.__addMetadata = function (doc, user, req) {
|
|
doc.__metadata = {
|
|
owner: user ? user._id : null,
|
|
updatedBy: null,
|
|
createdAt: new Date(),
|
|
updatedAt: null,
|
|
deletedAt: null
|
|
}
|
|
}
|
|
|
|
pColl.__updateMetadata = function (doc, user) {
|
|
delete doc.__metadata
|
|
doc['__metadata.updatedAt'] = new Date()
|
|
if (user) doc['__metadata.updatedBy'] = user ? user._id : null
|
|
}
|
|
|
|
pColl.__generateFilterObject = generateFilterObject
|
|
pColl.__buildRestOp = buildRestOpObject
|
|
|
|
// Add new routes
|
|
if (pColl.__internal.router) router.use('/' + pColl.name + '/methods/', pColl.__internal.router)
|
|
|
|
/**
|
|
* @api {get} /api/:collection Get all
|
|
* @apiName get:/api/:collection
|
|
* @apiVersion 0.0.1
|
|
* @apiGroup Restapi
|
|
* @apiDescription Get all documents from one collection
|
|
*
|
|
* @apiParam {String} collection Required collection
|
|
*
|
|
* @apiSuccess {Object} res Response.
|
|
* @apiSuccess {Object} res.ok 1 if success.
|
|
* @apiSuccess {Object} res.data List of documents.
|
|
* @apiSuccess {Object} res.limit Results limitation.
|
|
* @apiSuccess {Object} res.skip Skipped results.
|
|
* @apiSuccess {Object} res.count Total results available on server.
|
|
* @apiSuccess {Object} res.links Links to navigate into documents.
|
|
*
|
|
* @apiUse SessionError
|
|
*/
|
|
router.get(`/${pColl.name}`, (req, res) => {
|
|
pColl.__services.read(req.restOp, res.done)
|
|
})
|
|
|
|
pColl.__services.read = function (pArgs, pCallback) {
|
|
let restOp = pArgs || buildRestOpObject()
|
|
// Find operator
|
|
let findOp = { $and: [] }
|
|
findOp.$and.push(restOp.filter)
|
|
// Projection operator
|
|
let projOp = Object.keys(restOp.projection).length ? restOp.projection : {}
|
|
// Find all matching elements
|
|
collHandler.find(findOp).count(function (pErr, pCount) {
|
|
collHandler
|
|
// Filters elements
|
|
.find(findOp)
|
|
// Project fields
|
|
.project(projOp)
|
|
// Sort result
|
|
.sort(restOp.sort)
|
|
// Limit the number
|
|
.limit(restOp.limit)
|
|
// Skip
|
|
.skip(restOp.skip)
|
|
// Get results
|
|
.toArray(function (pErr, pResults) {
|
|
if (pErr) return pCallback(pErr)
|
|
pCallback(null, {
|
|
ok: 1,
|
|
label: pCtx.restapi[pColl.name].label,
|
|
icon: pCtx.restapi[pColl.name].icon,
|
|
description: pCtx.restapi[pColl.name].description,
|
|
data: pResults,
|
|
limit: restOp.limit,
|
|
count: pCount,
|
|
skip: restOp.skip,
|
|
links: {
|
|
base: '',
|
|
next: `/api/${pColl.name}?limit=${restOp.limit}&skip=${restOp.skip + restOp.limit}`,
|
|
prev: `/api/${pColl.name}?limit=${restOp.limit}&skip=${Math.max(0, restOp.skip - restOp.limit)}`
|
|
},
|
|
sort: restOp.sort
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @api {post} /api/:collection Create
|
|
* @apiName post:/api/:collection
|
|
* @apiVersion 0.0.1
|
|
* @apiGroup Restapi
|
|
* @apiDescription Create one new document
|
|
*
|
|
* @apiSuccess {Object} res Response.
|
|
* @apiSuccess {Object} res.ok 1 if success.
|
|
* @apiSuccess {Object} res.data Returned document.
|
|
*
|
|
* @apiError Db:DuplicateKey When a field set as unique index has been already created
|
|
* @apiUse SessionError
|
|
*/
|
|
router.post(`/${pColl.name}`, (req, res) => {
|
|
pColl.__services.create(req.body, req.user, res.done)
|
|
})
|
|
|
|
pColl.__services.create = function (pDoc, pUser, pCallback) {
|
|
collValidator(pDoc)
|
|
let errors = collValidator.errors
|
|
if (errors && errors.length) return pCallback(errors)
|
|
//
|
|
|
|
let tasks = []
|
|
let createdDoc = {ok: 0, doc: null}
|
|
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.create.before(pCtx, pDoc, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
|
|
tasks.push(function (pCb) {
|
|
// delete pDoc._id
|
|
pColl.__addMetadata(pDoc, pUser)
|
|
collHandler.insertOne(pDoc, function (pErr, pResult) {
|
|
if (pErr) {
|
|
switch (pErr.code) {
|
|
case 11000:
|
|
createdDoc = pErr
|
|
return pCb(new Error('Db:DuplicateKey'), pErr)
|
|
default:
|
|
return pCb(pErr)
|
|
}
|
|
}
|
|
createdDoc.ok = pResult.insertedCount
|
|
createdDoc.doc = pResult.ops[0]
|
|
pCb()
|
|
})
|
|
})
|
|
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.create.after(pCtx, createdDoc.doc, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
|
|
async.waterfall(tasks, function (pErr) {
|
|
pCallback(pErr, createdDoc)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @api {get} /api/:collection/:id Get one
|
|
* @apiName get:/api/:collection/:id
|
|
* @apiVersion 0.0.1
|
|
* @apiGroup Restapi
|
|
* @apiDescription Get one document
|
|
*
|
|
* @apiParam {String} collection Required collection
|
|
* @apiParam {ObjectId} id Required document Id
|
|
*
|
|
* @apiSuccess {Object} res Response.
|
|
* @apiSuccess {Object} res.ok 1 if success.
|
|
* @apiSuccess {Object} res.data Returned document.
|
|
*
|
|
* @apiError Db:WrongDbId ID parameter is not a MongoDB ObjectId
|
|
* @apiError Db:NotFound Required document ID not found in DB
|
|
* @apiUse SessionError
|
|
*/
|
|
router.get(`/${pColl.name}/:id`, (req, res) => {
|
|
pColl.__services.readOne(req.params.id, req.restOp, res.done)
|
|
})
|
|
|
|
pColl.__services.readOne = function (pId, pArgs, pCallback) {
|
|
// Convert ID if it's a correct one else returns one error
|
|
let objectId = getObjectId(pId, pColl.customId)
|
|
if (!objectId) {
|
|
return pCallback(new Error('Db:WrongDbId'))
|
|
}
|
|
|
|
let tasks = []
|
|
let oneDoc = {ok: 0, id: pId, data: null}
|
|
|
|
// Call before hook to transform data
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.readOne.before(pCtx, objectId, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
// Get one document
|
|
tasks.push(function (pCb) {
|
|
collHandler
|
|
.find({_id: objectId})
|
|
.project(pArgs.projection)
|
|
.limit(1)
|
|
.next(function (pErr, pDoc) {
|
|
if (pErr) return pCallback(pErr)
|
|
if (!pDoc) return pCallback(400, new Error('Db:NotFound'))
|
|
oneDoc.ok = 1
|
|
oneDoc.label = pCtx.restapi[pColl.name].label
|
|
oneDoc.icon = pCtx.restapi[pColl.name].icon
|
|
oneDoc.description = pCtx.restapi[pColl.name].description
|
|
oneDoc.data = pDoc
|
|
pCb()
|
|
})
|
|
})
|
|
// Call after hook to perform some operations
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.readOne.after(pCtx, oneDoc.data, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
|
|
async.waterfall(tasks, function (pErr) {
|
|
pCallback(pErr, oneDoc)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @api {put} /api/:collection/:id Update
|
|
* @apiName put:/api/:collection/:id
|
|
* @apiVersion 0.0.1
|
|
* @apiGroup Restapi
|
|
* @apiDescription Update some fields of one document
|
|
*
|
|
* @apiParam {String} collection Required collection
|
|
* @apiParam {ObjectId} id Required document Id
|
|
*
|
|
* @apiSuccess {Object} res Response.
|
|
* @apiSuccess {Object} res.ok 1 if success.
|
|
* @apiSuccess {Object} res.data Returned document.
|
|
*
|
|
* @apiError Db:WrongDbId ID parameter is not a MongoDB ObjectId
|
|
* @apiError Db:NotFound Required document ID not found in DB
|
|
* @apiUse SessionError
|
|
*/
|
|
router.put(`/${pColl.name}/:id`, (req, res) => {
|
|
pColl.__services.update(req.params.id, req.body, req.user, 'router', res.done)
|
|
})
|
|
|
|
pColl.__services.update = function (pId, pDoc, pUser, pOrigin, pCallback) {
|
|
// console.log(pDoc)
|
|
// Convert ID if it's a correct one else returns one error
|
|
let objectId = getObjectId(pId, pColl.customId)
|
|
if (!objectId) {
|
|
return pCallback(new Error('Db:WrongDbId'))
|
|
}
|
|
//
|
|
collValidator(pDoc)
|
|
if (collValidator.errors) {
|
|
// console.dir(collValidator.errors, {depth: null, colors: true})
|
|
let errors = collValidator.errors.filter(error => error.keyword !== 'required')
|
|
if (errors.length) return pCallback('JSONSchema:ValidationFailed', errors)
|
|
}
|
|
//
|
|
let tasks = []
|
|
let updatedDoc = { ok: 0, id: pId, doc: null }
|
|
|
|
// Call before hook to transform data
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.update.before(pCtx, objectId, pDoc, pOrigin, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
// Save in DB
|
|
tasks.push(function (pCb) {
|
|
delete pDoc._id
|
|
// console.log(pDoc)
|
|
pColl.__updateMetadata(pDoc, pUser)
|
|
collHandler
|
|
.findOneAndUpdate(
|
|
{_id: objectId},
|
|
{$set: pDoc},
|
|
{returnOriginal: false},
|
|
function (pErr, pResult) {
|
|
if (pErr) return pCb(pErr)
|
|
updatedDoc.ok = pResult.ok
|
|
updatedDoc.doc = pResult.value
|
|
pCb()
|
|
})
|
|
})
|
|
// Call after hook to perform some operations
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.update.after(pCtx, updatedDoc.doc, pOrigin, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
|
|
async.waterfall(tasks, function (pErr) {
|
|
pCallback(pErr, updatedDoc)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @api {delete} /api/:collection/:id Delete
|
|
* @apiName delete:/api/:collection/:id
|
|
* @apiVersion 0.0.1
|
|
* @apiGroup Restapi
|
|
* @apiDescription Delete one document
|
|
*
|
|
* @apiParam {String} collection Required collection
|
|
* @apiParam {ObjectId} id Required document Id
|
|
*
|
|
* @apiSuccess {Object} res Response.
|
|
* @apiSuccess {Object} res.id [DbId] of deleted document.
|
|
* @apiSuccess {Object} res.ok 1 if success.
|
|
*
|
|
* @apiError Db:WrongDbId ID parameter is not a MongoDB ObjectId
|
|
* @apiUse SessionError
|
|
*/
|
|
router.delete(`/${pColl.name}/:id`, (req, res) => {
|
|
pColl.__services.delete(req.params.id, req.user, res.done)
|
|
})
|
|
|
|
pColl.__services.delete = function (pId, pUser, pCallback) {
|
|
// Convert ID if it's a correct one else returns one error
|
|
let objectId = getObjectId(pId, pColl.customId)
|
|
if (!objectId) {
|
|
return pCallback(new Error('Db:WrongDbId'))
|
|
}
|
|
|
|
let tasks = []
|
|
let deletedDoc = {ok: 0, id: pId}
|
|
|
|
// Call before hook to transform data
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.delete.before(pCtx, objectId, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
// Get one document
|
|
tasks.push(function (pCb) {
|
|
collHandler.removeOne({_id: objectId}, function (pErr, pDoc) {
|
|
if (pErr) return pCb(pErr)
|
|
deletedDoc.ok = pDoc.deletedCount
|
|
pCb()
|
|
})
|
|
})
|
|
// Call after hook to perform some operations
|
|
tasks.push(function (pCb) {
|
|
pColl.hooks.delete.after(pCtx, true, function (pErr) {
|
|
pCb(pErr)
|
|
})
|
|
})
|
|
|
|
async.waterfall(tasks, function (pErr) {
|
|
pCallback(pErr, deletedDoc)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @api {get} /api/:collection/private/json-schema Get json schema
|
|
* @apiName get:/api/:collection/private/json-schema
|
|
* @apiVersion 0.0.1
|
|
* @apiGroup Restapi
|
|
* @apiDescription Get JSON schema defined for this collection
|
|
*
|
|
* @apiParam {String} collection Required collection
|
|
*
|
|
* @apiSuccess {Json} schema JSON schema.
|
|
*
|
|
* @apiUse SessionError
|
|
*/
|
|
router.get(`/${pColl.name}/private/json-schema`, (req, res) => {
|
|
res.done(null, pColl.schema)
|
|
})
|
|
|
|
router.get(`/${pColl.name}/private/json-form`, (req, res) => {
|
|
res.done(null, pColl.form || [])
|
|
})
|
|
|
|
router.get(`/${pColl.name}/private/json-form-create`, (req, res) => {
|
|
res.done(null, pColl.formCreate || [])
|
|
})
|
|
|
|
router.get(`/${pColl.name}/private/listing-header`, (req, res) => {
|
|
res.done(null, pColl.listingHeader || [{ text: 'Nom', align: 'left', value: 'name' }])
|
|
})
|
|
|
|
router.get(`/${pColl.name}/private/new-objectid`, (req, res) => {
|
|
res.done(null, new ObjectId())
|
|
})
|
|
|
|
router.put(`/${pColl.name}/upsert/from/:field`, (req, res) => {
|
|
let findOp = {
|
|
[req.params.field]: req.body[req.params.field]
|
|
}
|
|
|
|
let cat = req.body.categories
|
|
|
|
delete req.body[req.params.value]
|
|
delete req.body.categories
|
|
|
|
let upOp = {$set: req.body}
|
|
if (cat) {
|
|
upOp['$addToSet'] = {categories: cat}
|
|
}
|
|
|
|
collHandler.findOneAndUpdate(
|
|
findOp,
|
|
upOp,
|
|
{upsert: true},
|
|
res.done)
|
|
})
|
|
|
|
/**
|
|
* @api {get} /api/:collection/private/json-schema/fake Get fake schema
|
|
* @apiName get:/api/:collection/private/json-schema/fake
|
|
* @apiVersion 0.0.1
|
|
* @apiGroup Restapi
|
|
* @apiDescription Get a fake JSON from schema defined for this collection
|
|
*
|
|
* @apiParam {String} collection Required collection
|
|
*
|
|
* @apiSuccess {Json} schema Fake JSON.
|
|
*
|
|
* @apiUse SessionError
|
|
*/
|
|
router.get(`/${pColl.name}/private/json-schema/fake`, (req, res) => {
|
|
jsf.option({ alwaysFakeOptionals: true })
|
|
|
|
jsf
|
|
.resolve(pColl.schema)
|
|
.then(function (result) {
|
|
if (result.planning) {
|
|
result.planning.byFormat = {
|
|
bannersHome: {
|
|
byAirline: {
|
|
AirFrance: {
|
|
deltaImpressions: 10000,
|
|
allowedFormats: ['iab-leaderboard', 'iab-squra']
|
|
},
|
|
TAROM: {
|
|
deltaImpressions: -10000,
|
|
allowedFormats: ['iab-squra']
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
res.done(null, result)
|
|
})
|
|
.catch(function (error) {
|
|
res.done(error)
|
|
})
|
|
})
|
|
}
|
|
|
|
function buildRestOpObject () {
|
|
return {
|
|
filter: {},
|
|
projection: {},
|
|
sort: {},
|
|
limit: 100,
|
|
skip: 0
|
|
}
|
|
}
|
|
|
|
function generateFilterObject (pReq) {
|
|
var filterObject = {}
|
|
var sortObject = {}
|
|
var projObject = {}
|
|
var request = null
|
|
var queries = pReq.query
|
|
var queryKeys = Object.keys(queries)
|
|
var length = queryKeys.length
|
|
var limit = 0
|
|
var skip = 0
|
|
var index, key, localData, lQueries, regArray, match, query, type
|
|
|
|
var deletedDocs = null
|
|
|
|
for (index = 0; index < length; index++) {
|
|
key = queryKeys[index]
|
|
if (key === 'limit') {
|
|
limit = parseInt(queries.limit)
|
|
} else if (key === 'skip') {
|
|
skip = parseInt(queries.skip)
|
|
} else if (key === 'projection') {
|
|
queries.projection.split(',').forEach(function (pProj) {
|
|
var projField = pProj.split(':')
|
|
projObject[projField[0]] = +projField[1]
|
|
})
|
|
} else if (key === 'sort') {
|
|
queries.sort.split(',').forEach(function (pSort) {
|
|
if (pSort[0] === '-') {
|
|
sortObject[pSort.substring(1)] = -1
|
|
} else {
|
|
sortObject[pSort] = 1
|
|
}
|
|
})
|
|
} else if (key === 'search') {
|
|
filterObject['$text'] = { '$search': queries.search }
|
|
} else if (key === 'deletedDocs') {
|
|
deletedDocs = queries.deletedDocs
|
|
} else {
|
|
request = key.split('__')
|
|
if (request.length <= 1 || !queries[key]) {
|
|
// console.log('unknown key', key);
|
|
continue
|
|
}
|
|
|
|
match = queries[key].match(/\((.*)\)(.*)/)
|
|
if (match) {
|
|
type = match[1]
|
|
query = castValue(match[2], type)
|
|
} else {
|
|
type = null
|
|
query = queries[key]
|
|
}
|
|
|
|
filterObject[request[0]] = filterObject[request[0]] || {}
|
|
|
|
switch (request[1]) {
|
|
case 'eq' :
|
|
if (!type) {
|
|
switch (query) {
|
|
case 'true':
|
|
query = true
|
|
break
|
|
case 'false':
|
|
query = false
|
|
break
|
|
default:
|
|
if (!isNaN(query)) {
|
|
query = +query
|
|
}
|
|
}
|
|
}
|
|
filterObject[request[0]]['$eq'] = query
|
|
break
|
|
case 'lt' :
|
|
filterObject[request[0]]['$lt'] = query
|
|
break
|
|
case 'lte' :
|
|
filterObject[request[0]]['$lte'] = query
|
|
break
|
|
case 'gt' :
|
|
filterObject[request[0]]['$gt'] = query
|
|
break
|
|
case 'gte' :
|
|
filterObject[request[0]]['$gte'] = query
|
|
break
|
|
case 'ne' :
|
|
filterObject[request[0]]['$ne'] = query
|
|
break
|
|
case 'regex' :
|
|
regArray = query.split(',')
|
|
filterObject[request[0]]['$regex'] = new RegExp(regArray[0], regArray[1])
|
|
break
|
|
case 'regexNot' :
|
|
regArray = query.split(',')
|
|
filterObject[request[0]]['$not'] = new RegExp(regArray[0], regArray[1])
|
|
break
|
|
case 'exists' :
|
|
filterObject[request[0]]['$exists'] = query == 'true'
|
|
break
|
|
case 'in' :
|
|
case 'all' :
|
|
case 'nin' :
|
|
if (typeof query === 'string') {
|
|
localData = query.split(',')
|
|
} else {
|
|
localData = [query]
|
|
}
|
|
if (!type && request[0] === '_id') {
|
|
type = 'ObjectId'
|
|
}
|
|
if (type) {
|
|
lQueries = []
|
|
localData.forEach(function (pElem) {
|
|
lQueries.push(castValue(pElem, type))
|
|
})
|
|
} else {
|
|
lQueries = localData
|
|
}
|
|
filterObject[request[0]]['$' + request[1]] = lQueries
|
|
break
|
|
default:
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if (!deletedDocs) {
|
|
// filterObject['__metadata.deletionDate'] = { $exists: false }
|
|
// } else {
|
|
// if (deletedDocs === 'only') {
|
|
// filterObject['__metadata.deletionDate'] = { $exists: true }
|
|
// }
|
|
// }
|
|
|
|
pReq.restOp = buildRestOpObject()
|
|
pReq.restOp.filter = filterObject
|
|
pReq.restOp.projection = projObject
|
|
pReq.restOp.sort = sortObject
|
|
pReq.restOp.limit = limit || 100
|
|
pReq.restOp.skip = skip
|
|
|
|
return pReq.restOp
|
|
}
|
|
|
|
function getObjectId (pId, pCustomId) {
|
|
let objectId = pCustomId ? pId : null
|
|
try { objectId = ObjectId(pId) } catch (e) {}
|
|
return objectId
|
|
}
|
|
|
|
function castValue (pValue, pType) {
|
|
var query = pValue
|
|
switch (pType) {
|
|
case 'Number':
|
|
query = +query
|
|
break
|
|
case 'Boolean':
|
|
query = query == 'true'
|
|
break
|
|
case 'Date':
|
|
query = new Date(query)
|
|
break
|
|
case 'ObjectId':
|
|
try {
|
|
query = ObjectId(query)
|
|
} catch (e) {
|
|
// query = query
|
|
}
|
|
break
|
|
case 'NULL':
|
|
query = null
|
|
break
|
|
default:
|
|
console.warn('Unknown cast type', pType)
|
|
}
|
|
|
|
return query
|
|
}
|
|
|
|
module.exports = function (pCtx) {
|
|
initCollections(pCtx)
|
|
return router
|
|
}
|