UNPKG

6.06 kBJavaScriptView Raw
1'use strict';
2
3const { setProp } = require('./util');
4const ValidationError = require('./error/validation');
5
6/**
7 * This is the basic schema type.
8 * All schema types should inherit from this class.
9 * For example:
10 *
11 * ``` js
12 * class SchemaTypeCustom extends SchemaType {};
13 * ```
14 *
15 * **Query operators**
16 *
17 * To add a query operator, defines a method whose name is started with `q$`.
18 * For example:
19 *
20 * ``` js
21 * SchemaTypeCustom.q$foo = function(value, query, data){
22 * // ...
23 * };
24 * ```
25 *
26 * The `value` parameter is the value of specified field; the `query` parameter
27 * is the value passed to the query operator; the `data` parameter is the
28 * complete data.
29 *
30 * The return value must be a boolean indicating whether the data passed.
31 *
32 * **Update operators**
33 *
34 * To add a update operator, defines a method whose name is started with `u$`.
35 * For example:
36 *
37 * ``` js
38 * SchemaTypeCustom.u$foo = function(value, update, data){
39 * // ...
40 * };
41 * ```
42 *
43 * The `value` parameter is the value of specified field; the `update` parameter
44 * is the value passed to the update operator; the `data` parameter is the
45 * complete data.
46 *
47 * The return value will replace the original data.
48 */
49class SchemaType {
50
51 /**
52 * SchemaType constructor.
53 *
54 * @param {String} name
55 * @param {Object} [options]
56 * @param {Boolean} [options.required=false]
57 * @param {*} [options.default]
58 */
59 constructor(name, options) {
60 this.name = name || '';
61
62 this.options = Object.assign({
63 required: false
64 }, options);
65
66 const default_ = this.options.default;
67
68 if (typeof default_ === 'function') {
69 this.default = default_;
70 } else {
71 this.default = () => default_;
72 }
73 }
74
75 /**
76 * Casts data. This function is used by getters to cast an object to document
77 * instances. If the value is null, the default value will be returned.
78 *
79 * @param {*} value
80 * @param {Object} data
81 * @return {*}
82 */
83 cast(value, data) {
84 if (value == null) {
85 return this.default();
86 }
87
88 return value;
89 }
90
91 /**
92 * Validates data. This function is used by setters.
93 *
94 * @param {*} value
95 * @param {Object} data
96 * @return {*|Error}
97 */
98 validate(value, data) {
99 if (this.options.required && value == null) {
100 throw new ValidationError(`\`${this.name}\` is required!`);
101 }
102
103 return value;
104 }
105
106 /**
107 * Compares data. This function is used when sorting.
108 *
109 * @param {*} a
110 * @param {*} b
111 * @return {Number}
112 */
113 compare(a, b) {
114 if (a > b) {
115 return 1;
116 } else if (a < b) {
117 return -1;
118 }
119
120 return 0;
121 }
122
123 /**
124 * Parses data. This function is used when restoring data from database files.
125 *
126 * @param {*} value
127 * @param {Object} data
128 * @return {*}
129 */
130 parse(value, data) {
131 return value;
132 }
133
134 /**
135 * Transforms value. This function is used when saving data to database files.
136 *
137 * @param {*} value
138 * @param {Object} data
139 * @return {*}
140 */
141 value(value, data) {
142 return value;
143 }
144
145 /**
146 * Checks the equality of data.
147 *
148 * @param {*} value
149 * @param {*} query
150 * @param {Object} data
151 * @return {Boolean}
152 */
153 match(value, query, data) {
154 return value === query;
155 }
156
157 /**
158 * Checks the existance of data.
159 *
160 * @param {*} value
161 * @param {*} query
162 * @param {Object} data
163 * @return {Boolean}
164 */
165 q$exist(value, query, data) {
166 return (value != null) === query;
167 }
168
169 /**
170 * Checks the equality of data. Returns true if the value doesn't match.
171 *
172 * @param {*} value
173 * @param {*} query
174 * @param {Object} data
175 * @return {boolean}
176 */
177 q$ne(value, query, data) {
178 return !this.match(value, query, data);
179 }
180
181 /**
182 * Checks whether `value` is less than (i.e. <) the `query`.
183 *
184 * @param {*} value
185 * @param {*} query
186 * @param {Object} data
187 * @return {Boolean}
188 */
189 q$lt(value, query, data) {
190 return value < query;
191 }
192
193 /**
194 * Checks whether `value` is less than or equal to (i.e. <=) the `query`.
195 *
196 * @param {*} value
197 * @param {*} query
198 * @param {Object} data
199 * @return {Boolean}
200 */
201 q$lte(value, query, data) {
202 return value <= query;
203 }
204
205 /**
206 * Checks whether `value` is greater than (i.e. >) the `query`.
207 *
208 * @param {*} value
209 * @param {*} query
210 * @param {Object} data
211 * @return {Boolean}
212 */
213 q$gt(value, query, data) {
214 return value > query;
215 }
216
217 /**
218 * Checks whether `value` is greater than or equal to (i.e. >=) the `query`.
219 *
220 * @param {*} value
221 * @param {*} query
222 * @param {Object} data
223 * @return {Boolean}
224 */
225 q$gte(value, query, data) {
226 return value >= query;
227 }
228
229 /**
230 * Checks whether `value` is equal to one of elements in `query`.
231 *
232 * @param {*} value
233 * @param {Array} query
234 * @param {Object} data
235 * @return {Boolean}
236 */
237 q$in(value, query, data) {
238 return query.includes(value);
239 }
240
241 /**
242 * Checks whether `value` is not equal to any elements in `query`.
243 *
244 * @param {*} value
245 * @param {Array} query
246 * @param {Object} data
247 * @return {Boolean}
248 */
249 q$nin(value, query, data) {
250 return !query.includes(value);
251 }
252
253 /**
254 * Sets the value.
255 *
256 * @param {*} value
257 * @param {*} update
258 * @param {Object} data
259 * @return {*}
260 */
261 u$set(value, update, data) {
262 return update;
263 }
264
265 /**
266 * Unsets the value.
267 *
268 * @param {*} value
269 * @param {*} update
270 * @param {Object} data
271 * @return {*}
272 */
273 u$unset(value, update, data) { return update ? undefined : value; }
274
275 /**
276 * Renames a field.
277 *
278 * @param {*} value
279 * @param {*} update
280 * @param {Object} data
281 * @return {*}
282 */
283 u$rename(value, update, data) {
284 if (value !== undefined) setProp(data, update, value);
285 return undefined;
286 }
287}
288
289SchemaType.prototype.q$exists = SchemaType.prototype.q$exist;
290
291SchemaType.prototype.q$max = SchemaType.prototype.q$lte;
292
293SchemaType.prototype.q$min = SchemaType.prototype.q$gte;
294
295module.exports = SchemaType;