Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filter can now be used as a replacement to Model#toJSON() #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions lib/filtered.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
'use strict';

var clone = require('./utils/clone');

module.exports = function(Model) {
var filteredAttrs = [];

Expand All @@ -9,7 +13,7 @@ module.exports = function(Model) {
});

Model.prototype.filter = function(filterList) {
if(typeof filterList == 'string') {
if(typeof filterList === 'string') {
filterList = [filterList];
}

Expand All @@ -19,10 +23,16 @@ module.exports = function(Model) {

filterList = filterList.concat(filteredAttrs);

var attrs = this.toJSON();
var attrs = {};
var self = this;

Object.keys(this.attrs).forEach(function (key) {
var val = self.attrs[key];
attrs[key] = (val && val.toJSON) ? val.toJSON() : clone(val);
});

for(var i = 0; i < filterList.length; ++i) {
delete attrs[filterList[i]];
delete attrs[filterList[i]];
}

return attrs;
Expand Down
59 changes: 59 additions & 0 deletions lib/utils/clone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* TODO: cleanup. This is a pretty big hack. inlined `clone` because
* it cannot handle objectid instances
*/

/**
* Module dependencies
*/

var type = require('./type');

/**
* Expose `clone`
*/

module.exports = clone;

/**
* Clone values.
*
* @param {Mixed} val
* @return {Mixed}
* @api public
*/

function clone(obj) {
switch (type(obj)) {
case 'object':
// Hack for BSON IDs
if(obj.toHexString)
return obj;
var copy = {};
for (var key in obj) {
copy[key] = clone(obj[key]);
}
return copy;

case 'array':
var copy = new Array(obj.length);
for (var i = 0, l = obj.length; i < l; i++) {
copy[i] = clone(obj[i]);
}
return copy;

case 'regexp':
// from millermedeiros/amd-utils - MIT
var flags = '';
flags += obj.multiline ? 'm' : '';
flags += obj.global ? 'g' : '';
flags += obj.ignoreCase ? 'i' : '';
return new RegExp(obj.source, flags);

case 'date':
return new Date(obj.getTime());

default: // string, number, boolean, …
return obj;
}
}
35 changes: 35 additions & 0 deletions lib/utils/type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* https://github.com/component/type
*
* TODO: un-bundle, once we have a way to use component and node together
*/

/**
* toString ref.
*/

var toString = Object.prototype.toString;

/**
* Return the type of `val`.
*
* @param {Mixed} val
* @return {String}
* @api public
*/

module.exports = function(val){
switch (toString.call(val)) {
case '[object Function]': return 'function';
case '[object Date]': return 'date';
case '[object RegExp]': return 'regexp';
case '[object Arguments]': return 'arguments';
case '[object Array]': return 'array';
}

if (val === null) return 'null';
if (val === undefined) return 'undefined';
if (val === Object(val)) return 'object';

return typeof val;
};
16 changes: 16 additions & 0 deletions test/filtered.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,20 @@ describe("Filtered", function() {
it("auto-filters properties defined with filter flag", function() {
expect(user.filter()).to.not.have.key('hashedPassword');
});

it("can be used inside model#toJSON()", function() {
User.prototype.toJSON = function() {
return this.filter;
};
var user = new User({
username: 'thisisauser',
hashedPassword: '129408158932dsjkaklfjsad',
socialSecurityNumber: '123-456-7890'
});
var result = user.filter('socialSecurityNumber');

expect(result).to.not.have.key('socialSecurityNumber');
expect(result).to.have.key('username');

});
});