-
Notifications
You must be signed in to change notification settings - Fork 0
/
pseudo.js
132 lines (102 loc) · 3.11 KB
/
pseudo.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// ./models/validators/isNumerical.validator.js
export default function isNumericalValidator(propertyNameOrNames, customErrorMessage, callback) {
const model = this;
if (propertyNameOrNames.constructor === Array) {
let errorMessages = [];
const propertyNames = propertyNameOrNames;
propertyNames.forEach((property) => {
if (!isNumerical(model[property])) {
const errorMessage = customErrorMessage || `"${property}" must be a number`;
errorMessages.push(errorMessage);
}
});
if (errorMessages.length === 0) {
callback();
} else {
const error = new Error(`${errorMessages.join(", ")}.`);
callback(error);
}
} else {
const propertyName = propertyNameOrNames;
if (isNumerical(model[propertyName])) {
callback();
} else {
const errorMessage = customErrorMessage || `"${propertyName}" must be a number.`;
const error = new Error(errorMesage);
callback(error);
}
}
}
function isNumerical(value) {
const valueIsNumerical = !isNaN(parseFloat(value)) && isFinite(value);
return valueIsNumerical;
}
// ./model/plugins/isProtected.plugin.js
export default function isProtected() {
const model = this;
model.validations.add("isProtected", isProtectedValidator);
}
function isProtectedValidator(propertyNameOrNames, customErrorMessage, callback) {
const model = this;
if (propertyNameOrNames.constructor === Array) {
const propertyNames = propertyNameOrNames;
propertyNames.forEach(addFilter, model);
} else {
const propertyName = propertyNameOrNames;
addFilter.call(model, propertyName);
}
}
function addFilter(propertyName) {
const model = this;
model.filters.add((newPropertyName, newPropertyValue, callback) => {
if (propertyName === newPropertyName) {
const errorMessage = customErrorMessage || `${propertyName} is a protected property.`
const error = new Error(errorMessage);
model.errors.push(error);
}
});
}
// ./models/ourModel.js
include isNumericalValidator from "./validators/isNumerical.js";
export default class OurModel extends Model {
beforeInitialize(attributes, options) {
// Simple native plugins
this.use.timestamps;
this.use.softDelete;
// Simple 3rd-party plugins
this.use(isNumerical);
// Validate one property
this.ensure("id").isProtected;
// Validate many propertyNames
this.ensure(["id", "createdAt", "updatedAt", "deletedAt"]).isProtected;
}
}
class User extends OurModel {
initialize(attributes, options) {
// Immediately begin using 3rd-party functionality
this.ensure("age").isNumerical;
this.ensure("name").isSet;
this.ensure("age").isSet;
super();
}
}
class Admin extends User {
initialize(attributes, options) {
this.ensure("key").isSet;
super();
}
}
let user = new User("Bob", 46);
const admin = new User("Steve", 54, "1209ufajksbdv0q9h3csdv");
user.id = 54;
user.save(); // OK!
user.id = 42; // OK! You are directly setting the id!
let user = new User({name: "Bob", age: 46, id: 4}); // Doesn't throw, but .save will return error now
user.save((errors) => {
errors;
});
user.errors((errors) => {
errors.forEach((error) => {
console.log(error.message);
});
});