Skip to content

Commit 5586f26

Browse files
committed
Validate other models
1 parent 3f48f66 commit 5586f26

File tree

7 files changed

+195
-52
lines changed

7 files changed

+195
-52
lines changed

examples/chat.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,15 @@ var myUserData = {
5252
name: 'Paco',
5353
surname: 'santos',
5454
age: 19,
55-
dni: '51402430A'
55+
dni: '51402430A',
56+
unexpected: 'property'
5657
};
57-
// var myUser = User.modelate(myUserData);
58+
var myUser = User.modelate(myUserData);
5859
// console.log(myUser);
5960

6061
var messageModel = {
6162
user: {
63+
type: 'object',
6264
model: 'User'
6365
},
6466
// date: {
@@ -76,10 +78,10 @@ var Message = Modelate('Message').set(messageModel);
7678

7779
// Modelate a message
7880
var myMessageData = {
79-
message: 'I am using models inside models. Crazy.',
81+
message: 'Using models inside models. Crazy.',
8082
// date: new Date(),
81-
// user: myUser
82-
user: myUserData
83+
user: myUser
84+
// user: myUserData
8385
};
8486
var myMessage = Message.modelate(myMessageData);
8587
console.log(myMessage);

index.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
const model = require('./lib/model');
33
const modelate = require('./lib/modelate');
44

5-
// const models = model.models;
6-
7-
5+
/**
6+
* Modelate instance.
7+
*/
88
function Modelate(name) {
99
const self = this;
1010

@@ -13,8 +13,6 @@ function Modelate(name) {
1313
self.set = model.add;
1414
self.modelate = modelate;
1515

16-
// models[name] = {};
17-
1816
return this;
1917
}
2018

lib/model.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ const models = {};
33
function model(data) {
44
// ToDo: Validate model
55
// ToDo: Check if model already exists to merge instead of set
6-
for(let prop in data) {
7-
if(data[prop].model) {
8-
data[prop] = models[data[prop].model];
9-
}
10-
}
6+
// for(let prop in data) {
7+
// if(data[prop].model) {
8+
// data[prop] = models[data[prop].model];
9+
// }
10+
// }
1111

1212
models[this.modelName] = data;
1313

lib/modelate.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
const util = require('./util');
22

33
const models = require('./model').models;
4-
const validate = require('./validate');
4+
const validate = require('./validate').check;
55

6-
// var modelate = function modelate(data) {
7-
function modelate(data) {
8-
const model = util.clone(models[this.modelName]);
6+
/**
7+
* Create a new modelate, validating all properties
8+
* Options might be:
9+
* - model: {Object} A model to use (instead of this.modelName)
10+
* @param data {Object} The data to validate
11+
* @param opts {Object} Options for the modelate.
12+
*/
13+
function modelate(data, opts) {
14+
if (!this.modelName && opts && !opts.model) {
15+
return {};
16+
}
17+
18+
const model = opts && opts.model || models[this.modelName];
19+
const result = util.clone(model);
920

10-
for(let prop in model) {
11-
if(validate(data[prop], model[prop])) {
12-
model[prop] = data[prop];
21+
for (let prop in model) {
22+
if (validate(data[prop], model[prop])) {
23+
result[prop] = data[prop];
1324
} else {
14-
delete model[prop];
25+
delete result[prop];
1526
}
1627
}
1728

18-
return model;
29+
return result;
1930
}
2031

2132
module.exports = modelate;

lib/util.js

Lines changed: 109 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
/** Deep Copy
22
* Return a copy of the object passed as param, doing (recursivelly) copys of
33
* all the objects the initial has.
4-
*
4+
*
55
* Caution!!!
66
* This function is recursive. Copying a very deep object might concern heavy
77
* performance issues. Use your brain before the function.
8+
*
9+
* @param oldObj {Object} Object to clone
810
*/
911
function deepCopy(oldObj) {
10-
var newObj = oldObj;
11-
if (oldObj && typeof oldObj === 'object') {
12-
newObj = Object.prototype.toString.call(oldObj) === '[object Array]' ? [] : {};
13-
for (var i in oldObj) {
14-
newObj[i] = deepCopy(oldObj[i]);
15-
}
16-
}
17-
return newObj;
12+
var newObj = oldObj;
13+
if (oldObj && typeof oldObj === 'object') {
14+
newObj = Object.prototype.toString.call(oldObj) === '[object Array]' ? [] : {};
15+
for (var i in oldObj) {
16+
newObj[i] = deepCopy(oldObj[i]);
17+
}
18+
}
19+
return newObj;
1820
}
1921

2022
/** Merge
@@ -24,28 +26,110 @@ function deepCopy(oldObj) {
2426
* A third parameter, avoidDeepCopy is also included to avoid creating a deep
2527
* copy of the objects. With this parameter to true, original objects may get
2628
* updated, linked or similar unexpected behaviour.
29+
*
30+
* @param old {Object} Object to use as base
31+
* @param obj {Object} Object to get data from
32+
* @param avoidDeepCopy {booleam} Seting to true will update the "old" object
2733
*/
2834
function merge(old, obj, avoidDeepCopy) {
29-
30-
let dest, orig;
31-
32-
if(avoidDeepCopy) {
33-
dest = old;
34-
orig = obj;
35-
} else {
36-
dest = deepCopy(old);
37-
orig = deepCopy(obj);
38-
}
39-
40-
for(let prop in orig) {
41-
dest[prop] = orig[prop];
42-
}
43-
44-
return dest;
35+
let dest, orig;
36+
37+
if(avoidDeepCopy) {
38+
dest = old;
39+
orig = obj;
40+
} else {
41+
dest = deepCopy(old);
42+
orig = deepCopy(obj);
43+
}
44+
45+
for(let prop in orig) {
46+
dest[prop] = orig[prop];
47+
}
48+
49+
return dest;
4550
}
4651

52+
/** Equal
53+
* Check if two objects are equal.
54+
*
55+
* Seen in:
56+
* https://github.com/epoberezkin/fast-deep-equal/
57+
*
58+
* @param a {Object} First object
59+
* @param b {Object} Seccond object
60+
*/
61+
function equal(a, b) {
62+
if (a === b) {
63+
return true;
64+
}
65+
66+
var arrA = Array.isArray(a);
67+
var arrB = Array.isArray(b);
68+
var i;
69+
70+
if (arrA && arrB) {
71+
if (a.length !== b.length) {
72+
return false;
73+
}
74+
75+
for (i = 0; i < a.length; i++) {
76+
if (!equal(a[i], b[i])) {
77+
return false;
78+
}
79+
}
80+
81+
return true;
82+
}
83+
84+
if (arrA !== arrB) {
85+
return false;
86+
}
87+
88+
if (a && b && typeof a === 'object' && typeof b === 'object') {
89+
var keys = Object.keys(a);
90+
if (keys.length !== Object.keys(b).length) {
91+
return false;
92+
}
93+
94+
var dateA = a instanceof Date;
95+
var dateB = b instanceof Date;
96+
if (dateA && dateB) {
97+
return a.getTime() === b.getTime();
98+
}
99+
100+
if (dateA !== dateB) {
101+
return false;
102+
}
103+
104+
var regexpA = a instanceof RegExp;
105+
var regexpB = b instanceof RegExp;
106+
if (regexpA && regexpB) {
107+
return a.toString() === b.toString();
108+
}
109+
if (regexpA !== regexpB) {
110+
return false;
111+
}
112+
113+
for (i = 0; i < keys.length; i++) {
114+
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
115+
return false;
116+
}
117+
}
118+
119+
for (i = 0; i < keys.length; i++) {
120+
if(!equal(a[keys[i]], b[keys[i]])) {
121+
return false;
122+
}
123+
}
124+
125+
return true;
126+
}
127+
128+
return false;
129+
}
47130

48131
module.exports = {
49132
merge: merge,
133+
equal: equal,
50134
clone: deepCopy
51135
};

lib/validate.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11

22
// Add validator names here
3-
const validators = ['type', 'length', 'value', 'func'];
3+
const validators = ['type', 'length', 'value', 'func', 'model'];
4+
// const validators = ['type', 'length', 'value', 'func'];
45

56
// Turn validator names to validator instances.
67
for(let i = 0; i < validators.length; i++) {
78
validators[i] = validator(validators[i]);
89
}
910

1011
// Validate
11-
function validate(data, model) {
12+
function validate(data, model) {
1213
for(let i = 0; i < validators.length; i++) {
1314
if(!validators[i].check(data, model)) {
1415
console.error('Validation for "' + data + '" failed! Reason: ', validators[i].name);
@@ -28,4 +29,4 @@ function validator(name) {
2829
}
2930

3031

31-
module.exports = validate;
32+
module.exports = {check: validate};

lib/validators/model.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
var util = require('../util');
2+
var models = require('../model').models;
3+
// var validate = require('../validate');
4+
5+
/**
6+
* Type validator
7+
*
8+
* {
9+
* type: String // Check if data has a JS type (uses typeof)
10+
* }
11+
*/
12+
function isValid(data, model) {
13+
if(!model.model) {
14+
return true;
15+
}
16+
17+
var validate = module.parent.parent.exports;
18+
var valid = validate(data, {model: models[model.model]});
19+
20+
// var eq = util.equal(data, valid);
21+
// return eq;
22+
23+
// Turn data into a valid model...
24+
reference(data, valid);
25+
return true;
26+
}
27+
28+
/**
29+
* Replace an object for other keeping the reference
30+
*
31+
* @origin {Object} Object to replace
32+
* @newObj {Object} Object to use as new
33+
*/
34+
function reference(origin, newObj) {
35+
// Clean object
36+
for (let p in origin) {
37+
delete origin[p];
38+
}
39+
40+
// Insert new data
41+
for (let p in newObj) {
42+
origin[p] = newObj[p];
43+
}
44+
45+
}
46+
47+
module.exports = isValid;

0 commit comments

Comments
 (0)