Merge pull request #100 from strongloop/fix/hidden-nested

Add hidden property support
This commit is contained in:
Ritchie Martori 2014-04-11 12:36:30 -07:00
commit 4518a07bf2
3 changed files with 65 additions and 8 deletions

View File

@ -72,11 +72,11 @@ List.prototype.push = function (obj) {
return item; return item;
}; };
List.prototype.toObject = function (onlySchema) { List.prototype.toObject = function (onlySchema, removeHidden) {
var items = []; var items = [];
this.forEach(function (item) { this.forEach(function (item) {
if (item.toObject) { if (item.toObject) {
items.push(item.toObject(onlySchema)); items.push(item.toObject(onlySchema, removeHidden));
} else { } else {
items.push(item); items.push(item);
} }

View File

@ -234,22 +234,24 @@ ModelBaseClass.toString = function () {
* *
* @param {Boolean} onlySchema Restrict properties to dataSource only. Default is false. If true, the function returns only properties defined in the schema; Otherwise it returns all enumerable properties. * @param {Boolean} onlySchema Restrict properties to dataSource only. Default is false. If true, the function returns only properties defined in the schema; Otherwise it returns all enumerable properties.
*/ */
ModelBaseClass.prototype.toObject = function (onlySchema) { ModelBaseClass.prototype.toObject = function (onlySchema, removeHidden) {
if(onlySchema === undefined) { if(onlySchema === undefined) {
onlySchema = true; onlySchema = true;
} }
var data = {}; var data = {};
var self = this; var self = this;
var Model = this.constructor;
var strict = this.__strict; var strict = this.__strict;
var schemaLess = (strict === false) || !onlySchema; var schemaLess = (strict === false) || !onlySchema;
this.constructor.forEachProperty(function (propertyName) { this.constructor.forEachProperty(function (propertyName) {
if(removeHidden && Model.isHiddenProperty(propertyName)) return;
if (self[propertyName] instanceof List) { if (self[propertyName] instanceof List) {
data[propertyName] = self[propertyName].toObject(!schemaLess); data[propertyName] = self[propertyName].toObject(!schemaLess, removeHidden);
} else if (self.__data.hasOwnProperty(propertyName)) { } else if (self.__data.hasOwnProperty(propertyName)) {
if (self[propertyName] !== undefined && self[propertyName] !== null && self[propertyName].toObject) { if (self[propertyName] !== undefined && self[propertyName] !== null && self[propertyName].toObject) {
data[propertyName] = self[propertyName].toObject(!schemaLess); data[propertyName] = self[propertyName].toObject(!schemaLess, removeHidden);
} else { } else {
data[propertyName] = self[propertyName]; data[propertyName] = self[propertyName];
} }
@ -264,10 +266,11 @@ ModelBaseClass.prototype.toObject = function (onlySchema) {
// If the property is not declared in the model definition, no setter will be // If the property is not declared in the model definition, no setter will be
// triggered to add it to __data // triggered to add it to __data
for (var propertyName in self) { for (var propertyName in self) {
if(removeHidden && Model.isHiddenProperty(propertyName)) continue;
if(self.hasOwnProperty(propertyName) && (!data.hasOwnProperty(propertyName))) { if(self.hasOwnProperty(propertyName) && (!data.hasOwnProperty(propertyName))) {
val = self[propertyName]; val = self[propertyName];
if (val !== undefined && val !== null && val.toObject) { if (val !== undefined && val !== null && val.toObject) {
data[propertyName] = val.toObject(!schemaLess); data[propertyName] = val.toObject(!schemaLess, removeHidden);
} else { } else {
data[propertyName] = val; data[propertyName] = val;
} }
@ -276,20 +279,33 @@ ModelBaseClass.prototype.toObject = function (onlySchema) {
// Now continue to check __data // Now continue to check __data
for (propertyName in self.__data) { for (propertyName in self.__data) {
if (!data.hasOwnProperty(propertyName)) { if (!data.hasOwnProperty(propertyName)) {
if(removeHidden && Model.isHiddenProperty(propertyName)) continue;
val = self.hasOwnProperty(propertyName) ? self[propertyName] : self.__data[propertyName]; val = self.hasOwnProperty(propertyName) ? self[propertyName] : self.__data[propertyName];
if (val !== undefined && val !== null && val.toObject) { if (val !== undefined && val !== null && val.toObject) {
data[propertyName] = val.toObject(!schemaLess); data[propertyName] = val.toObject(!schemaLess, removeHidden);
} else { } else {
data[propertyName] = val; data[propertyName] = val;
} }
} }
} }
} }
return data; return data;
}; };
ModelBaseClass.isHiddenProperty = function(propertyName) {
var Model = this;
var settings = Model.definition && Model.definition.settings;
var hiddenProperties = settings && settings.hidden;
if(hiddenProperties) {
return ~hiddenProperties.indexOf(propertyName);
} else {
return false;
}
}
ModelBaseClass.prototype.toJSON = function () { ModelBaseClass.prototype.toJSON = function () {
return this.toObject(false); return this.toObject(false, true);
}; };
ModelBaseClass.prototype.fromObject = function (obj) { ModelBaseClass.prototype.fromObject = function (obj) {

View File

@ -242,5 +242,46 @@ describe('ModelDefinition class', function () {
assert(anotherChild.prototype instanceof baseChild); assert(anotherChild.prototype instanceof baseChild);
}); });
it('should not serialize hidden properties into JSON', function () {
var memory = new DataSource({connector: Memory});
var modelBuilder = memory.modelBuilder;
var HiddenModel = memory.createModel('hidden', {}, {
hidden: ['secret']
});
var hm = new HiddenModel({
id: 1,
foo: 'bar',
secret: 'secret'
});
var serialized = hm.toJSON();
assert.deepEqual(serialized, {
id: 1,
foo: 'bar'
});
});
it('should not serialize hidden properties of nested models into JSON', function (done) {
var memory = new DataSource({connector: Memory});
var modelBuilder = memory.modelBuilder;
var Parent = memory.createModel('parent');
var Child = memory.createModel('child', {}, {hidden: ['secret']});
Parent.hasMany(Child);
Parent.create({
name: 'parent'
}, function(err, parent) {
parent.children.create({
name: 'child',
secret: 'secret'
}, function(err, child) {
Parent.find({include: 'children'}, function(err, parents) {
var serialized = parents[0].toJSON();
var child = serialized.children[0];
assert.equal(child.name, 'child');
assert.notEqual(child.secret, 'secret');
done();
});
});
});
});
}); });