Split out parsing helpers into proper functions
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable camelcase */
|
||||
import mongoose from 'mongoose';
|
||||
const Schema = mongoose.Schema;
|
||||
import {paramParser} from '../utils/paramParser';
|
||||
@@ -17,6 +18,11 @@ const Page = mongoose.model('Page', PageSchema);
|
||||
describe('param parser', () => {
|
||||
|
||||
describe('Parameter Parsing', () => {
|
||||
it('No params', () => {
|
||||
let parsed = paramParser(Page, {});
|
||||
expect(parsed).toEqual({});
|
||||
});
|
||||
|
||||
it('Property Equals', () => {
|
||||
let parsed = paramParser(Page, {title: 'This is my title'});
|
||||
expect(parsed.searchParams).toEqual({title: 'This is my title'});
|
||||
|
||||
@@ -7,11 +7,11 @@ export default function apiQueryPlugin(schema) {
|
||||
const model = this;
|
||||
const params = paramParser(this, rawParams);
|
||||
|
||||
let // Create the Mongoose Query object.
|
||||
query = model
|
||||
.find(params.searchParams)
|
||||
.limit(params.per_page)
|
||||
.skip((params.page - 1) * params.per_page);
|
||||
// Create the Mongoose Query object.
|
||||
let query = model
|
||||
.find(params.searchParams)
|
||||
.limit(params.per_page)
|
||||
.skip((params.page - 1) * params.per_page);
|
||||
|
||||
if (params.sort)
|
||||
query = query.sort(params.sort);
|
||||
@@ -22,192 +22,4 @@ export default function apiQueryPlugin(schema) {
|
||||
return query;
|
||||
}
|
||||
};
|
||||
|
||||
schema.statics.apiQueryParams = function (rawParams) {
|
||||
const model = this;
|
||||
|
||||
const convertToBoolean = str => {
|
||||
return str.toLowerCase() === 'true' ||
|
||||
str.toLowerCase() === 't' ||
|
||||
str.toLowerCase() === 'yes' ||
|
||||
str.toLowerCase() === 'y' ||
|
||||
str === '1';
|
||||
};
|
||||
|
||||
//changed
|
||||
const searchParams = {};
|
||||
|
||||
let query;
|
||||
let page = 1;
|
||||
let per_page = 100;
|
||||
let sort = false;
|
||||
|
||||
const parseSchemaForKey = (schema, keyPrefix, lcKey, val, operator) => {
|
||||
|
||||
let paramType;
|
||||
|
||||
const addSearchParam = val => {
|
||||
const key = keyPrefix + lcKey;
|
||||
|
||||
if (typeof searchParams[key] !== 'undefined') {
|
||||
for (i in val) {
|
||||
searchParams[key][i] = val[i];
|
||||
}
|
||||
} else {
|
||||
searchParams[key] = val;
|
||||
}
|
||||
};
|
||||
|
||||
let matches = lcKey.match(/(.+)\.(.+)/);
|
||||
if (matches) {
|
||||
// parse subschema
|
||||
if (schema.paths[matches[1]].constructor.name === 'DocumentArray' ||
|
||||
schema.paths[matches[1]].constructor.name === 'Mixed') {
|
||||
parseSchemaForKey(schema.paths[matches[1]].schema, `${matches[1]}.`, matches[2], val, operator)
|
||||
}
|
||||
|
||||
} else if (typeof schema === 'undefined') {
|
||||
paramType = 'String';
|
||||
|
||||
} else if (typeof schema.paths[lcKey] === 'undefined') {
|
||||
// nada, not found
|
||||
} else if (operator === 'near') {
|
||||
paramType = 'Near';
|
||||
} else if (schema.paths[lcKey].constructor.name === 'SchemaBoolean') {
|
||||
paramType = 'Boolean';
|
||||
} else if (schema.paths[lcKey].constructor.name === 'SchemaString') {
|
||||
paramType = 'String';
|
||||
} else if (schema.paths[lcKey].constructor.name === 'SchemaNumber') {
|
||||
paramType = 'Number';
|
||||
} else if (schema.paths[lcKey].constructor.name === 'ObjectId') {
|
||||
paramType = 'ObjectId';
|
||||
}//changed
|
||||
else if (schema.paths[lcKey].constructor.name === 'SchemaArray') {
|
||||
paramType = 'Array';
|
||||
}
|
||||
|
||||
console.log('Param Type: ' + paramType);
|
||||
|
||||
if (paramType === 'Boolean') {
|
||||
addSearchParam(convertToBoolean(val));
|
||||
} else if (paramType === 'Number') {
|
||||
if (val.match(/([0-9]+,?)/) && val.match(',')) {
|
||||
if (operator === 'all') {
|
||||
addSearchParam({ $all: val.split(',') });
|
||||
} else if (operator === 'nin') {
|
||||
addSearchParam({ $nin: val.split(',') });
|
||||
} else if (operator === 'mod') {
|
||||
addSearchParam({ $mod: [val.split(',')[0], val.split(',')[1]] });
|
||||
} else {
|
||||
addSearchParam({ $in: val.split(',') });
|
||||
}
|
||||
} else if (val.match(/([0-9]+)/)) {
|
||||
if (operator === 'gt' ||
|
||||
operator === 'gte' ||
|
||||
operator === 'lt' ||
|
||||
operator === 'lte' ||
|
||||
operator === 'ne') {
|
||||
let newParam = {};
|
||||
newParam[`$${operator}`] = val;
|
||||
addSearchParam(newParam);
|
||||
} else {//changed
|
||||
addSearchParam(parseInt(val));
|
||||
}
|
||||
}
|
||||
} else if (paramType === 'String') {
|
||||
if (val.match(',')) {
|
||||
const options = val.split(',').map(str => new RegExp(str, 'i'));
|
||||
|
||||
if (operator === 'all') {
|
||||
addSearchParam({ $all: options });
|
||||
} else if (operator === 'nin') {
|
||||
addSearchParam({ $nin: options });
|
||||
} else {
|
||||
addSearchParam({ $in: options });
|
||||
}
|
||||
} else if (val.match(/([0-9]+)/)) {
|
||||
if (operator === 'gt' ||
|
||||
operator === 'gte' ||
|
||||
operator === 'lt' ||
|
||||
operator === 'lte') {
|
||||
let newParam = {};
|
||||
newParam[`$${operator}`] = val;
|
||||
addSearchParam(newParam);
|
||||
} else {
|
||||
addSearchParam(val);
|
||||
}
|
||||
} else if (operator === 'ne' || operator === 'not') {
|
||||
const neregex = new RegExp(val, 'i');
|
||||
addSearchParam({ '$not': neregex });
|
||||
} else if (operator === 'exact') {
|
||||
addSearchParam(val);
|
||||
} else {
|
||||
addSearchParam({ $regex: val, $options: '-i' });
|
||||
}
|
||||
} else if (paramType === 'Near') {
|
||||
// divide by 69 to convert miles to degrees
|
||||
const latlng = val.split(',');
|
||||
const distObj = { $near: [parseFloat(latlng[0]), parseFloat(latlng[1])] };
|
||||
if (typeof latlng[2] !== 'undefined') {
|
||||
distObj.$maxDistance = parseFloat(latlng[2]) / 69;
|
||||
}
|
||||
addSearchParam(distObj);
|
||||
} else if (paramType === 'ObjectId') {
|
||||
addSearchParam(val);
|
||||
} else if (paramType === 'Array') {
|
||||
addSearchParam(val);
|
||||
console.log(lcKey)
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const parseParam = (key, val) => {
|
||||
console.log(key, val);
|
||||
const lcKey = key;
|
||||
let operator = val.match(/\{(.*)\}/);
|
||||
val = val.replace(/\{(.*)\}/, '');
|
||||
|
||||
if (operator) operator = operator[1];
|
||||
|
||||
if (val === '') {
|
||||
return;
|
||||
} else if (lcKey === 'page') {
|
||||
page = val;
|
||||
} else if (lcKey === 'per_page' || lcKey === 'limit') {
|
||||
per_page = parseInt(val);
|
||||
} else if (lcKey === 'sort_by') {
|
||||
const parts = val.split(',');
|
||||
sort = {};
|
||||
sort[parts[0]] = parts.length > 1 ? parts[1] : 1;
|
||||
} else {
|
||||
parseSchemaForKey(model.schema, '', lcKey, val, operator);
|
||||
}
|
||||
};
|
||||
|
||||
// Construct searchParams
|
||||
for (const key in rawParams) {
|
||||
const separatedParams = rawParams[key].match(/\{\w+\}(.[^\{\}]*)/g);
|
||||
|
||||
if (separatedParams === null) {
|
||||
parseParam(key, rawParams[key]);
|
||||
} else {
|
||||
for (var i = 0, len = separatedParams.length; i < len; ++i) {
|
||||
parseParam(key, separatedParams[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let returnVal = {
|
||||
searchParams,
|
||||
page,
|
||||
per_page,
|
||||
sort
|
||||
};
|
||||
|
||||
console.log(returnVal);
|
||||
|
||||
return returnVal;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +1,89 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
export function paramParser(model, rawParams) {
|
||||
|
||||
const convertToBoolean = str => {
|
||||
return str.toLowerCase() === 'true' ||
|
||||
str.toLowerCase() === 't' ||
|
||||
str.toLowerCase() === 'yes' ||
|
||||
str.toLowerCase() === 'y' ||
|
||||
str === '1';
|
||||
};
|
||||
|
||||
//changed
|
||||
const searchParams = {};
|
||||
const searchPageSort = {
|
||||
page: 1,
|
||||
per_page: 100,
|
||||
sort: false
|
||||
};
|
||||
let search = {};
|
||||
|
||||
let query;
|
||||
let page = 1;
|
||||
let per_page = 100;
|
||||
let sort = false;
|
||||
// Construct searchParams
|
||||
for (const key in rawParams) {
|
||||
const separatedParams = rawParams[key]
|
||||
.match(/{\w+}(.[^{}]*)/g);
|
||||
|
||||
const parseSchemaForKey = (schema, keyPrefix, lcKey, val, operator) => {
|
||||
if (separatedParams === null) {
|
||||
console.log('separated params null');
|
||||
search = parseParam(key, rawParams[key], model, searchParams, searchPageSort);
|
||||
} else {
|
||||
for (let i = 0; i < separatedParams.length; ++i) {
|
||||
search = parseParam(key, separatedParams[i], model, searchParams, searchPageSort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(search, 'searchparams');
|
||||
|
||||
// let returnVal = {
|
||||
// searchParams,
|
||||
// ...searchPageSort
|
||||
// };
|
||||
//
|
||||
// console.log(returnVal);
|
||||
|
||||
return search;
|
||||
}
|
||||
|
||||
function convertToBoolean(str) {
|
||||
return str.toLowerCase() === 'true' ||
|
||||
str.toLowerCase() === 't' ||
|
||||
str.toLowerCase() === 'yes' ||
|
||||
str.toLowerCase() === 'y' ||
|
||||
str === '1';
|
||||
}
|
||||
|
||||
function parseParam (key, val, model, searchParams, searchPageSort) {
|
||||
console.log(key, val);
|
||||
const lcKey = key;
|
||||
let operator = val.match(/\{(.*)\}/);
|
||||
val = val.replace(/\{(.*)\}/, '');
|
||||
|
||||
if (operator) operator = operator[1];
|
||||
|
||||
if (val === '') {
|
||||
// return;
|
||||
} else if (lcKey === 'page') {
|
||||
searchPageSort.page = val;
|
||||
} else if (lcKey === 'per_page' || lcKey === 'limit') {
|
||||
searchPageSort.per_page = parseInt(val);
|
||||
} else if (lcKey === 'sort_by') {
|
||||
const parts = val.split(',');
|
||||
searchPageSort.sort = {};
|
||||
searchPageSort.sort[parts[0]] = parts.length > 1 ? parts[1] : 1;
|
||||
} else {
|
||||
searchParams = parseSchemaForKey(model.schema, searchParams, '', lcKey, val, operator);
|
||||
}
|
||||
return {
|
||||
searchParams,
|
||||
...searchPageSort
|
||||
};
|
||||
}
|
||||
|
||||
function parseSchemaForKey(schema, searchParams, keyPrefix, lcKey, val, operator) {
|
||||
|
||||
let paramType;
|
||||
|
||||
const addSearchParam = val => {
|
||||
const addSearchParam = value => {
|
||||
const key = keyPrefix + lcKey;
|
||||
|
||||
if (typeof searchParams[key] !== 'undefined') {
|
||||
for (let i in val) {
|
||||
searchParams[key][i] = val[i];
|
||||
for (let i in value) {
|
||||
searchParams[key][i] = value[i];
|
||||
}
|
||||
} else {
|
||||
searchParams[key] = val;
|
||||
searchParams[key] = value;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,7 +110,7 @@ export function paramParser(model, rawParams) {
|
||||
paramType = 'Number';
|
||||
} else if (schema.paths[lcKey].constructor.name === 'ObjectId') {
|
||||
paramType = 'ObjectId';
|
||||
}//changed
|
||||
}
|
||||
else if (schema.paths[lcKey].constructor.name === 'SchemaArray') {
|
||||
paramType = 'Array';
|
||||
}
|
||||
@@ -82,9 +137,9 @@ export function paramParser(model, rawParams) {
|
||||
operator === 'lte' ||
|
||||
operator === 'ne') {
|
||||
let newParam = {};
|
||||
newParam[`$${operator}`] = val;
|
||||
newParam['$' + operator] = val;
|
||||
addSearchParam(newParam);
|
||||
} else {//changed
|
||||
} else {
|
||||
addSearchParam(parseInt(val));
|
||||
}
|
||||
}
|
||||
@@ -105,7 +160,7 @@ export function paramParser(model, rawParams) {
|
||||
operator === 'lt' ||
|
||||
operator === 'lte') {
|
||||
let newParam = {};
|
||||
newParam[`$${operator}`] = val;
|
||||
newParam['$' + operator] = val;
|
||||
addSearchParam(newParam);
|
||||
} else {
|
||||
addSearchParam(val);
|
||||
@@ -124,53 +179,5 @@ export function paramParser(model, rawParams) {
|
||||
addSearchParam(val);
|
||||
console.log(lcKey)
|
||||
}
|
||||
};
|
||||
|
||||
const parseParam = (key, val) => {
|
||||
console.log(key, val);
|
||||
const lcKey = key;
|
||||
let operator = val.match(/\{(.*)\}/);
|
||||
val = val.replace(/\{(.*)\}/, '');
|
||||
|
||||
if (operator) operator = operator[1];
|
||||
|
||||
if (val === '') {
|
||||
return;
|
||||
} else if (lcKey === 'page') {
|
||||
page = val;
|
||||
} else if (lcKey === 'per_page' || lcKey === 'limit') {
|
||||
per_page = parseInt(val);
|
||||
} else if (lcKey === 'sort_by') {
|
||||
const parts = val.split(',');
|
||||
sort = {};
|
||||
sort[parts[0]] = parts.length > 1 ? parts[1] : 1;
|
||||
} else {
|
||||
parseSchemaForKey(model.schema, '', lcKey, val, operator);
|
||||
}
|
||||
};
|
||||
|
||||
// Construct searchParams
|
||||
for (const key in rawParams) {
|
||||
const separatedParams = rawParams[key]
|
||||
.match(/{\w+}(.[^{}]*)/g);
|
||||
|
||||
if (separatedParams === null) {
|
||||
parseParam(key, rawParams[key]);
|
||||
} else {
|
||||
for (let i = 0; i < separatedParams.length; ++i) {
|
||||
parseParam(key, separatedParams[i]);
|
||||
}
|
||||
}
|
||||
return searchParams;
|
||||
}
|
||||
|
||||
let returnVal = {
|
||||
searchParams,
|
||||
page,
|
||||
per_page,
|
||||
sort
|
||||
};
|
||||
|
||||
console.log(returnVal);
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user