Skip to content

Commit 588f1ae

Browse files
authored
Merge pull request #26 from CodingCarlos/develop
v1.0.0
2 parents 11344ac + 3b64abb commit 588f1ae

File tree

16 files changed

+219
-79
lines changed

16 files changed

+219
-79
lines changed

README.md

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
A data modeling tool for NodeJS. It's 100% database agnostic, and 100% customizable.
99

10+
# Warning! Breaking changes in v1.0!
11+
If you have been using this package in versions under 1.0.0, you have to update your code. [Follow the migration guide](migration.md) to use the v1.x library.
12+
1013
# How to install
1114
Use NPM to install the package:
1215
```
@@ -45,7 +48,19 @@ var data = {
4548
age: 17 // Age does not match with min value
4649
};
4750

48-
var result = user.modelate(data); // => { name: 'Paco }
51+
var result = user.modelate(data);
52+
/* Result:
53+
{ data: {
54+
name: 'Paco
55+
},
56+
error: [{
57+
model: 'User',
58+
field: 'age',
59+
validator: 'value',
60+
constrains: { max: 95, min: 18 }
61+
}]
62+
}
63+
*/
4964
```
5065

5166
# Modifiers
@@ -55,12 +70,7 @@ Modifiers are just functions. It will be executed for each property, and return
5570

5671
## Default
5772
If there are not data for that property, it will create a given default value:
58-
```javascript
59-
{
60-
default: String // Check if data has a JS type
61-
}
62-
```
63-
For example:
73+
6474
```javascript
6575
{
6676
default: 'Default value'
@@ -237,40 +247,18 @@ This will validate `asd` but not `sdf`
237247
238248
# Tests
239249
240-
I'm currently adding tests to this code. I'm using Jasmine, and saving tests in `/spec` folder.
250+
Are built with Jasmine, and stored in `/spec` folder.
241251
242-
To run tests, just execute:
252+
First time you run tests, you might need to install Jasmine, and other dependencies. Just execute:
243253
```
244-
npm test
254+
npm install
245255
```
246256
247-
First time you run tests, you might need to install Jasmine, and other possible test dependencies. To do it fastly, just execute:
257+
To run tests, just execute:
248258
```
249-
npm install
259+
npm test
250260
```
251261
252-
And now you can run tests ^^
253-
254-
## Test coverage:
255-
Master version might not have the last test updates. Check out the `develop` branch to see the last updates. Also, the actual test coverage (in `develop` branch) is fully referenced in #3 issue.
256-
257-
- [x] Core
258-
- [x] Exported module
259-
- [x] Model
260-
- [x] Modelate
261-
- [x] Validate
262-
- [ ] Validators
263-
- [x] Type
264-
- [x] Length
265-
- [x] Value
266-
- [x] Custom function
267-
- [x] Date
268-
- [x] Regex
269-
- [x] Email
270-
- [ ] Model (Need help with this #15)
271-
- [x] Modifiers
272-
- [x] Default
273-
274262
275263
# Contribute
276264
You can use this code as you like. If you find a bug, or want to ask for a feature, just open an issue, and we'll do our best. If you can fix it, do a pull request to dev branch, and we promise to review it as fast as possible to merge it.

examples/validators/default.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ var Modelate = require('../../index');
66
var model = {
77
name: {
88
default: 'I am the default value'
9-
}
9+
},
10+
surname: {
11+
default: 'No surname setted'
12+
}
1013
};
1114
var user = Modelate('User').set(model);
1215

13-
var data = {};
16+
var data = {surname: 'Santos'};
1417
var result = user.modelate(data);
1518

1619

17-
console.log(result); // Shall be { name: 'I am the default value' }
20+
console.log(result); // Shall be { name: 'I am the default value', surname: 'Santos' }

index.js

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

5+
console.warn('---');
6+
console.warn('CAUTION!! This is an experimental release of Modelate. Everything might change from one day to other.');
7+
console.warn('---');
8+
59
/**
610
* Modelate instance.
711
*/

lib/modelate.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,42 @@ const modify = require('./modify').check;
88
* Create a new modelate, validating all properties
99
* Options might be:
1010
* - model: {Object} A model to use (instead of this.modelName)
11+
* - modelName: {String} A name for the model to use (instead of this.modelName)
1112
* @param data {Object} The data to validate
1213
* @param opts {Object} Options for the modelate.
1314
*/
1415
function modelate(data, opts) {
15-
if ((!this.modelName && !(opts && !opts.model)) || !data || typeof data !== 'object') {
16-
return {};
16+
const modelateResponse = {
17+
data: {},
18+
error: null
1719
}
1820

19-
const model = (opts && opts.model) || models[this.modelName];
21+
if ((!this.modelName && (!(opts && !opts.model) || !(opts && !opts.modelName))) || !data || typeof data !== 'object') {
22+
return modelateResponse;
23+
}
24+
25+
var modelName = (opts && opts.modelName) || this.modelName;
26+
27+
const model = (opts && opts.model) || models[modelName];
2028
const result = util.clone(model) || {};
29+
const errors = [];
2130

2231
for (const prop in model) {
2332
// Step 1: Apply the modifiers
2433
data[prop] = modify(data[prop], model[prop]);
2534

2635
// Step 2: validate the result
27-
if (validate(data[prop], model[prop])) {
36+
if (validate(data[prop], model[prop], errors, modelName, prop)) {
2837
result[prop] = data[prop];
2938
} else {
3039
delete result[prop];
3140
}
3241
}
3342

34-
return result;
43+
modelateResponse.data = result;
44+
modelateResponse.error = (errors.length !== 0) ? errors : null;
45+
46+
return modelateResponse;
3547
}
3648

3749
module.exports = modelate;

lib/modifiers/default.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88

99
function modify(data, model) {
1010
if (!model.default) {
11-
return null;
11+
return data;
1212
}
1313

14-
if (!data) {
14+
if (!data && data !== false && data !== 0) {
1515
return model.default;
1616
}
1717

18-
return null;
18+
return data;
1919
}
2020

2121

lib/modify.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ const modifiers = fs.readdirSync(directory).map(function(file) {
1919
function modify(data, model) {
2020
let newValue = data;
2121
for (let i = 0; i < modifiers.length; i++) {
22-
newValue = modifiers[i].check(data, model);
22+
newValue = modifiers[i].check(newValue, model);
2323
}
24+
2425

2526
return newValue;
2627
}

lib/validate.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,27 @@ const validators = fs.readdirSync(directory).map(function(file) {
1616
* @param data {Object} Data to validate
1717
* @param model {Object} Model to apply validations
1818
*/
19-
function validate(data, model) {
19+
function validate(data, model, errors, modelName, fieldName) {
20+
if (!errors) {
21+
errors = [];
22+
} else if (!Array.isArray(errors)) {
23+
throw new TypeError('Validation errors is not an array.');
24+
return false;
25+
}
26+
2027
for (let i = 0; i < validators.length; i++) {
21-
if (!validators[i].check(data, model)) {
22-
console.error('Validation for "' + data + '" failed! Reason: ', validators[i].name);
28+
if (!validators[i].check(data, model, errors)) {
29+
30+
const error = {
31+
model: modelName,
32+
field: fieldName,
33+
validator: validators[i].name,
34+
value: data,
35+
constrains: model[validators[i].name]
36+
}
37+
38+
errors.push(error);
39+
2340
return false;
2441
}
2542
}

lib/validators/model.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,32 @@ var models = require('../model').models;
88
* model: String // Check if data has a model type
99
* }
1010
*/
11-
function isValid(data, model) {
11+
function isValid(data, model, errors) {
1212
if (!model.model) {
1313
return true;
1414
}
15-
1615
if(!models[model.model]) {
1716
return false;
1817
}
1918

20-
var validate = module.parent.parent.exports;
21-
var valid = validate(data, { model: models[model.model] });
22-
23-
// Return if data is of model's type.
24-
// var eq = util.equal(data, valid);
25-
// return eq;
19+
// Load parent modelate
20+
var modelate = module.parent.parent.exports;
21+
// Launch modelate of data with requested model
22+
var valid = modelate(data, {
23+
model: models[model.model],
24+
modelName: model.model
25+
}, []);
26+
27+
// Populate errors to parent model
28+
if (valid.error) {
29+
for (var i = 0; i < valid.error.length; i++) {
30+
errors.push(valid.error[i]);
31+
}
32+
}
2633

2734
// Turn data into a valid model...
28-
reference(data, valid);
35+
reference(data, valid.data);
36+
2937
// And return true (data is parsed, so data is modelated)
3038
return true;
3139
}

lib/validators/required.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Required validator
3+
*
4+
* {
5+
* required: Boolean
6+
* }
7+
*/
8+
9+
function isValid(data, model) {
10+
if (!model.required) {
11+
return true;
12+
}
13+
14+
if(model.required && typeof data !== 'undefined') {
15+
return true;
16+
}
17+
18+
return false;
19+
}
20+
21+
22+
module.exports = isValid;

lib/validators/type.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
function isValid(data, model) {
10-
if (!model.type) {
10+
if (!model.type || typeof data === 'undefined') {
1111
return true;
1212
}
1313

0 commit comments

Comments
 (0)