Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

qs2mongo

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

qs2mongo - npm Package Compare versions

Comparing version 0.0.1 to 1.0.0

lib/schemas/index.js

231

lib/qs2mongo.js
(function() {
var Qs2Mongo, _,
var Qs2Mongo, TypeCaster, _, schemas,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },

@@ -8,3 +8,30 @@ slice = [].slice;

TypeCaster = require("./typeCaster");
schemas = require("./schemas");
module.exports = Qs2Mongo = (function() {
Qs2Mongo.Schemas = schemas;
Qs2Mongo.MongooseSchema = function(schema, options) {
if (options == null) {
options = {};
}
return new this(_.merge({
schema: new schemas.Mongoose(schema)
}, options));
};
Qs2Mongo.ManualSchema = function(fields, options) {
if (fields == null) {
fields = {};
}
if (options == null) {
options = {};
}
return new this(_.merge({
schema: new schemas.Manual(fields)
}, options));
};
Qs2Mongo.defaultOmitableProperties = ['by', 'ids', 'attributes', 'offset', 'limit', 'sort'];

@@ -15,15 +42,14 @@

function Qs2Mongo(arg) {
var ref, ref1, ref2, ref3, ref4;
this.defaultSort = arg.defaultSort, this.idField = (ref = arg.idField) != null ? ref : "id", this.multigetIdField = (ref1 = arg.multigetIdField) != null ? ref1 : "_id", this.filterableBooleans = (ref2 = arg.filterableBooleans) != null ? ref2 : [], this.filterableDates = (ref3 = arg.filterableDates) != null ? ref3 : [], this.omitableProperties = (ref4 = arg.omitableProperties) != null ? ref4 : Qs2Mongo.defaultOmitableProperties;
var ref, ref1, ref2;
this.schema = arg.schema, this.defaultSort = arg.defaultSort, this.idField = (ref = arg.idField) != null ? ref : "id", this.multigetIdField = (ref1 = arg.multigetIdField) != null ? ref1 : "_id", this.omitableProperties = (ref2 = arg.omitableProperties) != null ? ref2 : Qs2Mongo.defaultOmitableProperties;
this.buildIdFilters = bind(this.buildIdFilters, this);
this._transformFilters = bind(this._transformFilters, this);
this._castFilters = bind(this._castFilters, this);
this._castByName = bind(this._castByName, this);
this.buildSort = bind(this.buildSort, this);
this._mergeWithOperators = bind(this._mergeWithOperators, this);
this.castDateFilters = bind(this.castDateFilters, this);
this.castBooleanFilters = bind(this.castBooleanFilters, this);
this.buildFilters = bind(this.buildFilters, this);
this.buildSort = bind(this.buildSort, this);
this._omitableProperties = bind(this._omitableProperties, this);
this.buildSearch = bind(this.buildSearch, this);
this.buildFilters = bind(this.buildFilters, this);
this._makeOrFilters = bind(this._makeOrFilters, this);
this._parseOperator = bind(this._parseOperator, this);
this._castOrOperands = bind(this._castOrOperands, this);
this._parseOperators = bind(this._parseOperators, this);

@@ -33,2 +59,9 @@ this._getFilters_ = bind(this._getFilters_, this);

this.parse = bind(this.parse, this);
this.typeCaster = new TypeCaster({
booleans: this.schema.booleans(),
dates: this.schema.dates(),
numbers: this.schema.numbers(),
objectIds: this.schema.objectIds(),
omitableProperties: this.omitableProperties
});
}

@@ -85,3 +118,3 @@

return function(value, field) {
var name, obj, obj1, obj2, operator;
var name, obj, operator;
operator = _.find(Qs2Mongo.operators, function(operator) {

@@ -98,11 +131,3 @@ return _.endsWith(field, "__" + operator);

name = field.replace("__" + operator, "");
return (
obj1 = {},
obj1["" + name] = (
obj2 = {},
obj2["$" + operator] = value.source || value,
obj2
),
obj1
);
return _this._parseOperator(name, operator, value);
};

@@ -116,23 +141,66 @@ })(this));

})(this));
return rv;
return this._castOrOperands(rv);
};
Qs2Mongo.prototype._castOrOperands = function(filters) {
if (filters["$or"]) {
filters["$or"] = _.compact(filters["$or"].map((function(_this) {
return function(filter) {
var name, obj, value;
name = _.head(_.keys(filter));
value = _this._castByName(name, filter[name]);
if (!_.isUndefined(value)) {
return (
obj = {},
obj["" + name] = value,
obj
);
}
};
})(this)));
}
return filters;
};
Qs2Mongo.prototype._parseOperator = function(name, operator, operand) {
var argument, obj, obj1;
argument = operand.source || operand;
if ((operator === "in" || operator === "nin") && _.isString(argument)) {
argument = argument.split(',').map((function(_this) {
return function(it) {
return _this._castByName(name, it);
};
})(this));
}
return (
obj = {},
obj["" + name] = (
obj1 = {},
obj1["$" + operator] = argument,
obj1
),
obj
);
};
Qs2Mongo.prototype._makeOrFilters = function(filters) {
var _toCondition;
_toCondition = _.curry(function(value, fieldNames) {
var fields, obj;
fields = fieldNames.split(',');
switch (fields.length) {
case 1:
return (
obj = {},
obj["" + fields[0]] = value,
obj
);
default:
return {
"$or": fields.map(_toCondition(value))
};
}
});
_toCondition = _.curry((function(_this) {
return function(value, fieldNames) {
var fields, obj;
fields = fieldNames.split(',');
switch (fields.length) {
case 1:
return (
obj = {},
obj["" + fields[0]] = value,
obj
);
default:
return {
"$or": fields.map(_toCondition(value))
};
}
};
})(this));
return _.merge.apply(_, [{}].concat(slice.call(_.map(filters, _toCondition))));

@@ -147,4 +215,3 @@ };

idFilters = this.buildIdFilters(filters.ids);
this.castBooleanFilters(filters);
this.castDateFilters(filters);
this._castFilters(filters);
return _(filters).omit(propertiesToOmit).merge(idFilters).value();

@@ -161,20 +228,28 @@ };

Qs2Mongo.prototype.stringToBoolean = function(value, _default) {
var ref;
return ((ref = value != null ? typeof value.toLowerCase === "function" ? value.toLowerCase() : void 0 : void 0) != null ? ref : _default != null ? _default.toString() : void 0) === 'true';
};
Qs2Mongo.prototype.buildSearch = function(arg) {
var booleans, dates, filterableDates, idFilters, query, search;
var casteableFields, castedFilters, filters, idFilters, query, search;
query = arg.query;
filterableDates = this._mergeWithOperators(this.filterableDates);
search = _.omit(query, this.filterableBooleans.concat(this.omitableProperties).concat(filterableDates));
booleans = _.pick(query, this.filterableBooleans);
dates = _.pick(query, filterableDates);
this.castBooleanFilters(booleans);
this.castDateFilters(dates);
idFilters = this.buildIdFilters(query.ids);
return _.merge(dates, booleans, idFilters, this._asLikeIgnoreCase(search));
filters = _.clone(query);
casteableFields = _.flatMap(["dates", "numbers", "objectIds", "booleans"], (function(_this) {
return function(getter) {
return _this._mergeWithOperators(_this.schema[getter]());
};
})(this));
search = _.omit(filters, casteableFields, this.omitableProperties);
this._castFilters(filters);
castedFilters = _.pick(filters, casteableFields);
idFilters = this.buildIdFilters(filters.ids);
return _.merge(castedFilters, idFilters, this._asLikeIgnoreCase(search));
};
Qs2Mongo.prototype._mergeWithOperators = function(fields) {
return _.flatMap(fields, (function(_this) {
return function(field) {
return Qs2Mongo.operators.map(function(it) {
return field + "__" + it;
}).concat(field);
};
})(this));
};
Qs2Mongo.prototype._asLikeIgnoreCase = function(search) {

@@ -187,6 +262,2 @@ return _.reduce(search, (function(result, value, field) {

Qs2Mongo.prototype._omitableProperties = function() {
return ['by', 'ids', 'attributes', 'offset', 'limit', 'sort'];
};
Qs2Mongo.prototype.buildSort = function(field) {

@@ -210,45 +281,15 @@ var descending, obj;

Qs2Mongo.prototype.buildFilters = function(arg) {
var filters, idFilters, propertiesToOmit, query;
query = arg.query;
filters = _.clone(query);
propertiesToOmit = this.omitableProperties;
idFilters = this.buildIdFilters(filters.ids);
this.castBooleanFilters(filters);
this.castDateFilters(filters);
return _(filters).omit(propertiesToOmit).merge(idFilters).value();
Qs2Mongo.prototype._castByName = function(name, value) {
var obj;
return this._castFilters((
obj = {},
obj["" + name] = value,
obj
))[name];
};
Qs2Mongo.prototype.castBooleanFilters = function(query) {
return this._transformFilters(query, this.filterableBooleans, this.stringToBoolean);
Qs2Mongo.prototype._castFilters = function(filters) {
return this.typeCaster.castFilters(filters);
};
Qs2Mongo.prototype.castDateFilters = function(query) {
return this._transformFilters(query, this.filterableDates, function(it) {
return new Date(it.source || it);
});
};
Qs2Mongo.prototype._mergeWithOperators = function(fields) {
return _.flatMap(fields, (function(_this) {
return function(field) {
return Qs2Mongo.operators.map(function(it) {
return field + "__" + it;
}).concat(field);
};
})(this));
};
Qs2Mongo.prototype._transformFilters = function(query, fields, transformation) {
var filtersWithOperators;
filtersWithOperators = this._mergeWithOperators(fields);
return filtersWithOperators.forEach((function(_this) {
return function(field) {
if (query[field] != null) {
return query[field] = transformation(query[field]);
}
};
})(this));
};
Qs2Mongo.prototype.buildIdFilters = function(ids) {

@@ -255,0 +296,0 @@ if (ids != null) {

{
"name": "qs2mongo",
"version": "0.0.1",
"version": "1.0.0",
"description": "qs2mongo",

@@ -17,4 +17,5 @@ "main": "index.js",

"coffee-script": "1.11.0",
"lodash": "4.15.0",
"mocha": "^3.2.0"
"lodash": "4.17.4",
"mocha": "3.2.0",
"mongodb": "^2.2.27"
},

@@ -27,2 +28,3 @@ "devDependencies": {

"grunt-mocha-test": "0.13.2",
"mongoose": "4.10.4",
"should": "11.1.0"

@@ -29,0 +31,0 @@ },

@@ -17,4 +17,5 @@ # qs2mongo

- not strict: `key=value` is `{ key: /value/gi }`
- or: `key,anotherKey=value` is `$or: [{key:value}, {anotherKey:anotherValue}]`
- unary operators: `key__gt=value` is `{key: $gt: "value"}`
- $or: `key,anotherKey=value` is `$or: [{key:value}, {anotherKey:value}]`
- $in : `key__in=a,b,c` is `key: $in: ["a","b","c"]`
- unary operators: `key__gt=value` is `{key: { $gt: "value"} }`

@@ -25,3 +26,17 @@ #### Basic usage

Qs2Mongo = require ("qs2mongo")
qs2mongo = new Qs2Mongo()
#Bind types to mongoose schema
qs2mongo = Qs2Mongo.MongooseSchema YourMongooseSchema, {...otherOptions...}
#Or manually specify types
qs2mongo = Qs2Mongo.ManualSchema {
filterableBooleans,
filterableNumbers,
filterableDates,
filterableObjectIds
}, {...otherOptions...}
```
``` Coffeescript
#...

@@ -54,4 +69,2 @@ anEndpoint: (req, res): =>

multigetIdField = "_id",
filterableBooleans = [],
filterableDates = [],
omitableProperties = Qs2Mongo.defaultOmitableProperties

@@ -62,8 +75,19 @@ }

#### Specify types of querystring keys
## Advanced
``` Coffeescript
qs2mongo = new Qs2Mongo
filterableBooleans: ["aBooleanField","anotherBooleanField"]
filterableDates: ["aDateField","anotherDateField"]
Default driver is mongodb. If you'd like to use a custom mongodb driver, you must provide your own type conversion implementation as follows:
``` Coffesscript
{
toObjectId: (it) -> #your conversion
toNumber: (it) -> #your conversion
toBoolean: (it) -> #your conversion
toDate: (it) -> #your conversion
}
```
Note: Your conversion must return the properly converted value if `it` is valid or `undefined` otherwise.
Specify the path to your implementation in process.env.QS_TRANSFORMER_DRIVER
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc