alchemymvc 1.3.21 → 1.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -3
  3. package/lib/app/behaviour/publishable_behaviour.js +5 -5
  4. package/lib/app/behaviour/revision_behaviour.js +10 -10
  5. package/lib/app/behaviour/sluggable_behaviour.js +14 -14
  6. package/lib/app/conduit/electron_conduit.js +9 -9
  7. package/lib/app/conduit/http_conduit.js +13 -13
  8. package/lib/app/conduit/loopback_conduit.js +15 -15
  9. package/lib/app/conduit/socket_conduit.js +43 -43
  10. package/lib/app/config/routes.js +26 -0
  11. package/lib/app/controller/00-default_app_controller.js +21 -0
  12. package/lib/app/controller/alchemy_info_controller.js +12 -12
  13. package/lib/app/datasource/mongo_datasource.js +16 -16
  14. package/lib/app/element/00-default_app_element.js +19 -0
  15. package/lib/app/element/time_ago.js +5 -5
  16. package/lib/app/helper/00-default_app_helper.js +11 -0
  17. package/lib/app/helper/alchemy_helper.js +22 -22
  18. package/lib/app/helper/backed_map.js +1 -1
  19. package/lib/app/helper/breadcrumb.js +10 -10
  20. package/lib/app/helper/client_collection.js +3 -3
  21. package/lib/app/helper/cron.js +29 -29
  22. package/lib/app/helper/enum_values.js +6 -6
  23. package/lib/app/helper/pagination_helper.js +36 -36
  24. package/lib/app/helper/router_helper.js +35 -35
  25. package/lib/app/helper/socket_helper.js +57 -57
  26. package/lib/app/helper/syncable.js +84 -59
  27. package/lib/app/helper_component/paginate_component.js +9 -9
  28. package/lib/app/helper_controller/component.js +1 -1
  29. package/lib/app/helper_controller/conduit.js +31 -31
  30. package/lib/app/helper_controller/controller.js +54 -39
  31. package/lib/app/helper_datasource/00-nosql_datasource.js +624 -70
  32. package/lib/app/helper_datasource/05-fallback_datasource.js +10 -10
  33. package/lib/app/helper_datasource/idb_datasource.js +6 -6
  34. package/lib/app/helper_datasource/indexed_db.js +22 -22
  35. package/lib/app/helper_datasource/remote_datasource.js +5 -5
  36. package/lib/app/helper_error/http_error.js +4 -4
  37. package/lib/app/helper_error/model_error.js +2 -2
  38. package/lib/app/helper_error/validation_error.js +12 -12
  39. package/lib/app/helper_field/00-objectid_field.js +7 -7
  40. package/lib/app/helper_field/05-string_field.js +16 -12
  41. package/lib/app/helper_field/06-text_field.js +2 -4
  42. package/lib/app/helper_field/10-number_field.js +9 -12
  43. package/lib/app/helper_field/11-date_field.js +15 -15
  44. package/lib/app/helper_field/15-local_temporal_field.js +10 -10
  45. package/lib/app/helper_field/20-decimal_field.js +8 -9
  46. package/lib/app/helper_field/belongsto_field.js +1 -1
  47. package/lib/app/helper_field/big_int_field.js +8 -8
  48. package/lib/app/helper_field/boolean_field.js +9 -11
  49. package/lib/app/helper_field/datetime_field.js +3 -3
  50. package/lib/app/helper_field/enum_field.js +13 -8
  51. package/lib/app/helper_field/fixed_decimal_field.js +6 -7
  52. package/lib/app/helper_field/geopoint_field.js +9 -10
  53. package/lib/app/helper_field/habtm_field.js +3 -3
  54. package/lib/app/helper_field/hasoneparent_field.js +1 -1
  55. package/lib/app/helper_field/html_field.js +2 -4
  56. package/lib/app/helper_field/integer_field.js +8 -11
  57. package/lib/app/helper_field/local_date_field.js +5 -5
  58. package/lib/app/helper_field/local_date_time_field.js +5 -5
  59. package/lib/app/helper_field/local_time_field.js +5 -5
  60. package/lib/app/helper_field/mixed_field.js +5 -5
  61. package/lib/app/helper_field/object_field.js +8 -8
  62. package/lib/app/helper_field/password_field.js +3 -3
  63. package/lib/app/helper_field/regexp_field.js +7 -9
  64. package/lib/app/helper_field/schema_field.js +91 -88
  65. package/lib/app/helper_field/settings_field.js +92 -0
  66. package/lib/app/helper_field/time_field.js +6 -6
  67. package/lib/app/helper_field/url_field.js +2 -4
  68. package/lib/app/helper_model/00-base_criteria.js +662 -0
  69. package/lib/app/helper_model/05-criteria_expressions.js +605 -0
  70. package/lib/app/helper_model/10-model_criteria.js +1182 -0
  71. package/lib/app/helper_model/data_provider.js +2 -2
  72. package/lib/app/helper_model/document.js +103 -92
  73. package/lib/app/helper_model/document_list.js +14 -14
  74. package/lib/app/helper_model/field_config.js +11 -11
  75. package/lib/app/helper_model/field_set.js +17 -17
  76. package/lib/app/helper_model/model.js +203 -124
  77. package/lib/app/helper_model/remote_data_provider.js +2 -2
  78. package/lib/app/helper_validator/00_validator.js +16 -16
  79. package/lib/app/helper_validator/not_empty_validator.js +9 -9
  80. package/lib/app/model/00-default_app_model.js +18 -0
  81. package/lib/app/model/05-system_model.js +27 -0
  82. package/lib/app/model/{alchemy_migration_model.js → system_migration_model.js} +4 -4
  83. package/lib/app/model/system_setting_model.js +154 -0
  84. package/lib/app/model/{alchemy_task_history_model.js → system_task_history_model.js} +7 -7
  85. package/lib/app/model/{alchemy_task_model.js → system_task_model.js} +11 -11
  86. package/lib/bootstrap.js +22 -312
  87. package/lib/class/accumulator.js +5 -5
  88. package/lib/class/behaviour.js +5 -5
  89. package/lib/class/component.js +3 -3
  90. package/lib/class/conduit.js +203 -163
  91. package/lib/class/controller.js +42 -42
  92. package/lib/class/datasource.js +74 -79
  93. package/lib/class/document.js +74 -95
  94. package/lib/class/document_list.js +5 -5
  95. package/lib/class/element.js +17 -17
  96. package/lib/class/error.js +3 -3
  97. package/lib/class/field.js +169 -91
  98. package/lib/class/field_value.js +6 -6
  99. package/lib/class/helper.js +3 -3
  100. package/lib/class/inode.js +17 -17
  101. package/lib/class/inode_dir.js +12 -12
  102. package/lib/class/inode_file.js +50 -25
  103. package/lib/class/inode_list.js +4 -4
  104. package/lib/class/migration.js +4 -4
  105. package/lib/class/model.js +182 -168
  106. package/lib/class/path_definition.js +22 -22
  107. package/lib/class/path_evaluator.js +5 -5
  108. package/lib/class/path_param_definition.js +7 -7
  109. package/lib/class/plugin.js +312 -0
  110. package/lib/class/postponement.js +29 -29
  111. package/lib/class/reciprocal.js +8 -8
  112. package/lib/class/route.js +33 -33
  113. package/lib/class/router.js +73 -73
  114. package/lib/class/schema.js +21 -21
  115. package/lib/class/schema_client.js +73 -67
  116. package/lib/class/session.js +63 -29
  117. package/lib/class/session_scene.js +4 -4
  118. package/lib/class/sitemap.js +16 -16
  119. package/lib/class/task.js +39 -39
  120. package/lib/class/task_service.js +43 -47
  121. package/lib/{init → core}/alchemy.js +413 -374
  122. package/lib/{init/functions.js → core/alchemy_functions.js} +171 -108
  123. package/lib/core/alchemy_load_functions.js +715 -0
  124. package/lib/core/base.js +50 -62
  125. package/lib/core/client_alchemy.js +144 -152
  126. package/lib/core/client_base.js +39 -52
  127. package/lib/core/discovery.js +16 -18
  128. package/lib/core/middleware.js +54 -43
  129. package/lib/core/{routing.js → prefix.js} +14 -16
  130. package/lib/core/setting.js +1684 -0
  131. package/lib/core/stage.js +758 -0
  132. package/lib/scripts/create_constants.js +119 -0
  133. package/lib/{init/languages.js → scripts/create_languages.js} +5 -5
  134. package/lib/scripts/create_settings.js +449 -0
  135. package/lib/scripts/create_shared_constants.js +95 -0
  136. package/lib/scripts/create_stages.js +55 -0
  137. package/lib/scripts/init_alchemy.js +51 -0
  138. package/lib/{init/requirements.js → scripts/preload_modules.js} +15 -2
  139. package/lib/scripts/setup_devwatch.js +238 -0
  140. package/lib/stages/00-load_core.js +342 -0
  141. package/lib/stages/05-load_app.js +57 -0
  142. package/lib/stages/10-datasource.js +61 -0
  143. package/lib/stages/15-tasks.js +27 -0
  144. package/lib/stages/20-settings.js +68 -0
  145. package/lib/stages/50-routes.js +218 -0
  146. package/lib/stages/90-server.js +347 -0
  147. package/package.json +5 -7
  148. package/lib/app/helper_model/criteria.js +0 -2294
  149. package/lib/app/helper_model/db_query.js +0 -1488
  150. package/lib/app/routes.js +0 -11
  151. package/lib/core/socket.js +0 -171
  152. package/lib/init/constants.js +0 -158
  153. package/lib/init/devwatch.js +0 -238
  154. package/lib/init/load_functions.js +0 -973
  155. package/lib/stages.js +0 -513
@@ -1,15 +1,17 @@
1
+ const CASTER = Symbol('caster');
2
+
1
3
  /**
2
4
  * Field instances are created on boot,
3
5
  * so they are shared between Schema & Model instances.
4
6
  *
5
7
  * @constructor
6
8
  *
7
- * @author Jelle De Loecker <jelle@elevenways.be>
9
+ * @author Jelle De Loecker <jelle@elevenways.be>
8
10
  * @since 0.2.0
9
11
  * @version 1.3.6
10
12
  *
11
13
  * @param {Schema} schema The schema this field is added to
12
- * @param {String} name The name of the field
14
+ * @param {string} name The name of the field
13
15
  * @param {Object} options Field options
14
16
  */
15
17
  Blast.Globals.Field = Function.inherits('Alchemy.Base', 'Alchemy.Field', function Field(schema, name, options) {
@@ -42,7 +44,7 @@ Field.startNewGroup();
42
44
  /**
43
45
  * Defer casting when processing data?
44
46
  *
45
- * @type {Boolean}
47
+ * @type {boolean}
46
48
  */
47
49
  Field.setProperty('deferCast', false);
48
50
 
@@ -55,18 +57,31 @@ Field.setDeprecatedProperty('isArray', 'is_array');
55
57
  /**
56
58
  * All children will be stored here
57
59
  *
58
- * @type {Object}
60
+ * @type {Object}
59
61
  */
60
62
  Field.setStatic('types', {});
61
63
 
64
+ /**
65
+ * Set the main cast function
66
+ *
67
+ * @author Jelle De Loecker <jelle@elevenways.be>
68
+ * @since 1.4.0
69
+ * @version 1.4.0
70
+ *
71
+ * @param {Function} fnc
72
+ */
73
+ Field.setStatic(function setCastFunction(fnc) {
74
+ this.setMethod(CASTER, fnc);
75
+ });
76
+
62
77
  /**
63
78
  * Set the datatype of this field
64
79
  *
65
- * @author Jelle De Loecker <jelle@develry.be>
80
+ * @author Jelle De Loecker <jelle@elevenways.be>
66
81
  * @since 1.1.0
67
82
  * @version 1.1.0
68
83
  *
69
- * @param {String}
84
+ * @param {string}
70
85
  */
71
86
  Field.setStatic(function setDatatype(type) {
72
87
  this.setProperty('datatype', type);
@@ -75,11 +90,11 @@ Field.setStatic(function setDatatype(type) {
75
90
  /**
76
91
  * Set if the value of this field is self-contained
77
92
  *
78
- * @author Jelle De Loecker <jelle@develry.be>
93
+ * @author Jelle De Loecker <jelle@elevenways.be>
79
94
  * @since 1.1.0
80
95
  * @version 1.1.0
81
96
  *
82
- * @param {Boolean} value
97
+ * @param {boolean} value
83
98
  */
84
99
  Field.setStatic(function setSelfContained(value) {
85
100
 
@@ -93,7 +108,7 @@ Field.setStatic(function setSelfContained(value) {
93
108
  /**
94
109
  * Create a PathEvaluator
95
110
  *
96
- * @author Jelle De Loecker <jelle@develry.be>
111
+ * @author Jelle De Loecker <jelle@elevenways.be>
97
112
  * @since 1.1.0
98
113
  * @version 1.1.0
99
114
  *
@@ -106,11 +121,11 @@ Field.setStatic(function createPathEvaluator(path) {
106
121
  /**
107
122
  * Get the description of the field
108
123
  *
109
- * @author Jelle De Loecker <jelle@elevenways.be>
124
+ * @author Jelle De Loecker <jelle@elevenways.be>
110
125
  * @since 1.3.0
111
126
  * @version 1.3.0
112
127
  *
113
- * @type {String}
128
+ * @type {string}
114
129
  */
115
130
  Field.setProperty(function description() {
116
131
  return this.options?.description || this.options?.options?.description || null;
@@ -119,11 +134,11 @@ Field.setProperty(function description() {
119
134
  /**
120
135
  * Is this a private field?
121
136
  *
122
- * @author Jelle De Loecker <jelle@develry.be>
137
+ * @author Jelle De Loecker <jelle@elevenways.be>
123
138
  * @since 1.0.0
124
139
  * @version 1.2.4
125
140
  *
126
- * @type {Boolean}
141
+ * @type {boolean}
127
142
  */
128
143
  Field.setProperty(function is_private() {
129
144
 
@@ -137,11 +152,11 @@ Field.setProperty(function is_private() {
137
152
  /**
138
153
  * Does this field have a default value?
139
154
  *
140
- * @author Jelle De Loecker <jelle@develry.be>
155
+ * @author Jelle De Loecker <jelle@elevenways.be>
141
156
  * @since 1.1.0
142
157
  * @version 1.1.0
143
158
  *
144
- * @type {Boolean}
159
+ * @type {boolean}
145
160
  */
146
161
  Field.prepareProperty(function has_default() {
147
162
  return Object.hasProperty(this.options, 'default');
@@ -151,11 +166,11 @@ Field.prepareProperty(function has_default() {
151
166
  * Is this field translatable, meaning:
152
167
  * it is an object with the locales as keys.
153
168
  *
154
- * @author Jelle De Loecker <jelle@develry.be>
169
+ * @author Jelle De Loecker <jelle@elevenways.be>
155
170
  * @since 1.1.0
156
171
  * @version 1.1.0
157
172
  *
158
- * @type {Boolean}
173
+ * @type {boolean}
159
174
  */
160
175
  Field.setProperty(function is_translatable() {
161
176
  return !!this.options.translatable;
@@ -164,11 +179,11 @@ Field.setProperty(function is_translatable() {
164
179
  /**
165
180
  * Does this field need to be translated in some way?
166
181
  *
167
- * @author Jelle De Loecker <jelle@elevenways.be>
182
+ * @author Jelle De Loecker <jelle@elevenways.be>
168
183
  * @since 1.1.4
169
184
  * @version 1.1.4
170
185
  *
171
- * @type {Boolean}
186
+ * @type {boolean}
172
187
  */
173
188
  Field.setProperty(function requires_translating() {
174
189
  return this.is_translatable;
@@ -177,11 +192,11 @@ Field.setProperty(function requires_translating() {
177
192
  /**
178
193
  * Is this field an object?
179
194
  *
180
- * @author Jelle De Loecker <jelle@develry.be>
195
+ * @author Jelle De Loecker <jelle@elevenways.be>
181
196
  * @since 1.1.0
182
197
  * @version 1.1.0
183
198
  *
184
- * @type {Boolean}
199
+ * @type {boolean}
185
200
  */
186
201
  Field.setProperty(function is_object() {
187
202
  return this.is_translatable;
@@ -190,11 +205,11 @@ Field.setProperty(function is_object() {
190
205
  /**
191
206
  * Is this field an array?
192
207
  *
193
- * @author Jelle De Loecker <jelle@develry.be>
208
+ * @author Jelle De Loecker <jelle@elevenways.be>
194
209
  * @since 1.1.0
195
210
  * @version 1.1.0
196
211
  *
197
- * @type {Boolean}
212
+ * @type {boolean}
198
213
  */
199
214
  Field.setProperty(function is_array() {
200
215
 
@@ -210,20 +225,33 @@ Field.setProperty(function is_array() {
210
225
  /**
211
226
  * Does this field have a computed value?
212
227
  *
213
- * @author Jelle De Loecker <jelle@elevenways.be>
228
+ * @author Jelle De Loecker <jelle@elevenways.be>
214
229
  * @since 1.3.21
215
230
  * @version 1.3.21
216
231
  *
217
- * @type {Boolean}
232
+ * @type {boolean}
218
233
  */
219
234
  Field.setProperty(function is_computed() {
220
235
  return !!this.options.is_computed;
221
236
  });
222
237
 
238
+ /**
239
+ * Should this field allow null values?
240
+ *
241
+ * @author Jelle De Loecker <jelle@elevenways.be>
242
+ * @since 1.4.0
243
+ * @version 1.4.0
244
+ *
245
+ * @type {boolean}
246
+ */
247
+ Field.setProperty(function is_nullable() {
248
+ return !(this.options.is_nullable === false);
249
+ });
250
+
223
251
  /**
224
252
  * Get the required related fields
225
253
  *
226
- * @author Jelle De Loecker <jelle@elevenways.be>
254
+ * @author Jelle De Loecker <jelle@elevenways.be>
227
255
  * @since 1.3.21
228
256
  * @version 1.3.21
229
257
  *
@@ -241,7 +269,7 @@ Field.enforceProperty(function required_fields(new_value) {
241
269
  /**
242
270
  * Get the optional related fields
243
271
  *
244
- * @author Jelle De Loecker <jelle@elevenways.be>
272
+ * @author Jelle De Loecker <jelle@elevenways.be>
245
273
  * @since 1.3.21
246
274
  * @version 1.3.21
247
275
  *
@@ -259,7 +287,7 @@ Field.enforceProperty(function optional_fields(new_value) {
259
287
  /**
260
288
  * Get all the dependency fields
261
289
  *
262
- * @author Jelle De Loecker <jelle@elevenways.be>
290
+ * @author Jelle De Loecker <jelle@elevenways.be>
263
291
  * @since 1.3.21
264
292
  * @version 1.3.21
265
293
  *
@@ -288,7 +316,7 @@ Field.enforceProperty(function dependency_fields(new_value) {
288
316
  /**
289
317
  * Resolve a field path to a field instance
290
318
  *
291
- * @author Jelle De Loecker <jelle@elevenways.be>
319
+ * @author Jelle De Loecker <jelle@elevenways.be>
292
320
  * @since 1.3.21
293
321
  * @version 1.3.21
294
322
  */
@@ -320,7 +348,7 @@ function resolveFieldPaths(field, field_paths) {
320
348
  /**
321
349
  * The datasource this field is used in
322
350
  *
323
- * @author Jelle De Loecker <jelle@develry.be>
351
+ * @author Jelle De Loecker <jelle@elevenways.be>
324
352
  * @since 1.0.7
325
353
  * @version 1.1.0
326
354
  *
@@ -345,11 +373,11 @@ Field.setProperty(function datasource() {
345
373
  * Get the path to this field in the main record
346
374
  * (Without name of the model)
347
375
  *
348
- * @author Jelle De Loecker <jelle@elevenways.be>
376
+ * @author Jelle De Loecker <jelle@elevenways.be>
349
377
  * @since 1.1.0
350
378
  * @version 1.1.0
351
379
  *
352
- * @type {String}
380
+ * @type {string}
353
381
  */
354
382
  Field.setProperty(function path() {
355
383
  return this.schema.getPath(this.name, false);
@@ -359,11 +387,11 @@ Field.setProperty(function path() {
359
387
  * Get the path to this field in the document
360
388
  * (WITH the name of the model)
361
389
  *
362
- * @author Jelle De Loecker <jelle@elevenways.be>
390
+ * @author Jelle De Loecker <jelle@elevenways.be>
363
391
  * @since 1.1.0
364
392
  * @version 1.1.0
365
393
  *
366
- * @type {String}
394
+ * @type {string}
367
395
  */
368
396
  Field.setProperty(function path_in_document() {
369
397
  return this.schema.getPath(this.name, true);
@@ -372,7 +400,7 @@ Field.setProperty(function path_in_document() {
372
400
  /**
373
401
  * Set basic behaviour
374
402
  *
375
- * @author Jelle De Loecker <jelle@develry.be>
403
+ * @author Jelle De Loecker <jelle@elevenways.be>
376
404
  * @since 0.2.3
377
405
  * @version 1.1.0
378
406
  */
@@ -396,7 +424,7 @@ Field.constitute(function setTitle() {
396
424
  /**
397
425
  * Revive a dried field
398
426
  *
399
- * @author Jelle De Loecker <jelle@develry.be>
427
+ * @author Jelle De Loecker <jelle@elevenways.be>
400
428
  * @since 1.1.0
401
429
  * @version 1.1.0
402
430
  *
@@ -412,7 +440,7 @@ Field.setStatic(function unDry(value) {
412
440
  /**
413
441
  * Convert to JSON
414
442
  *
415
- * @author Jelle De Loecker <jelle@develry.be>
443
+ * @author Jelle De Loecker <jelle@elevenways.be>
416
444
  * @since 0.2.0
417
445
  * @version 1.3.1
418
446
  *
@@ -432,7 +460,7 @@ Field.setMethod(function toDry() {
432
460
  /**
433
461
  * Prepare the title property
434
462
  *
435
- * @author Jelle De Loecker <jelle@develry.be>
463
+ * @author Jelle De Loecker <jelle@elevenways.be>
436
464
  * @since 0.2.0
437
465
  * @version 0.4.0
438
466
  *
@@ -456,11 +484,11 @@ Field.setProperty(function title() {
456
484
  /**
457
485
  * Get a property by name
458
486
  *
459
- * @author Jelle De Loecker <jelle@develry.be>
487
+ * @author Jelle De Loecker <jelle@elevenways.be>
460
488
  * @since 0.4.0
461
489
  * @version 0.4.0
462
490
  *
463
- * @param {String} property_name
491
+ * @param {string} property_name
464
492
  *
465
493
  * @return {Mixed}
466
494
  */
@@ -474,13 +502,13 @@ Field.setMethod(function get(property_name) {
474
502
  *
475
503
  * @deprecated
476
504
  *
477
- * @author Jelle De Loecker <jelle@develry.be>
505
+ * @author Jelle De Loecker <jelle@elevenways.be>
478
506
  * @since 0.2.0
479
507
  * @version 0.2.0
480
508
  *
481
- * @param {Boolean} with_top_schema Add top schema name, defaults to true
509
+ * @param {boolean} with_top_schema Add top schema name, defaults to true
482
510
  *
483
- * @return {String}
511
+ * @return {string}
484
512
  */
485
513
  Field.decorateMethod('deprecate', function getPath(with_top_schema) {
486
514
  return this.schema.getPath(this.name, with_top_schema);
@@ -489,7 +517,7 @@ Field.decorateMethod('deprecate', function getPath(with_top_schema) {
489
517
  /**
490
518
  * Get all the fields that lead to this field
491
519
  *
492
- * @author Jelle De Loecker <jelle@develry.be>
520
+ * @author Jelle De Loecker <jelle@elevenways.be>
493
521
  * @since 1.1.0
494
522
  * @version 1.1.0
495
523
  *
@@ -503,7 +531,7 @@ Field.setMethod(function getFieldChain() {
503
531
  * Get all the values for the current field in the given document
504
532
  * as an array of FieldValue instances
505
533
  *
506
- * @author Jelle De Loecker <jelle@develry.be>
534
+ * @author Jelle De Loecker <jelle@elevenways.be>
507
535
  * @since 1.1.0
508
536
  * @version 1.1.0
509
537
  *
@@ -525,12 +553,12 @@ Field.setMethod(function getDocumentValues(document) {
525
553
  /**
526
554
  * Get the database value from the given record
527
555
  *
528
- * @author Jelle De Loecker <jelle@develry.be>
556
+ * @author Jelle De Loecker <jelle@elevenways.be>
529
557
  * @since 0.2.0
530
558
  * @version 1.1.0
531
559
  *
532
560
  * @param {Object} record
533
- * @param {String} path_to_value_hint
561
+ * @param {string} path_to_value_hint
534
562
  *
535
563
  * @return {Mixed}
536
564
  */
@@ -635,30 +663,89 @@ Field.setMethod(function getRecordValue(record, path_to_value_hint) {
635
663
  });
636
664
 
637
665
  /**
638
- * Cast the given value to this field's type
666
+ * Cast the value (could be in a container)
667
+ *
668
+ * @author Jelle De Loecker <jelle@elevenways.be>
669
+ * @since 1.4.0
670
+ * @version 1.4.0
671
+ *
672
+ * @param {*} value
673
+ * @param {boolean} to_datasource Is this meant for the datasource?
674
+ *
675
+ * @return {*}
676
+ */
677
+ Field.setMethod(function castContainedValues(value, to_datasource) {
678
+
679
+ if (this.is_translatable && value && this.is_translatable) {
680
+ let prefix;
681
+
682
+ for (prefix in value) {
683
+ value[prefix] = this.cast(value[prefix], to_datasource);
684
+ }
685
+ } else if (this.is_array && value) {
686
+ let i;
687
+
688
+ for (i = 0; i < value.length; i++) {
689
+ value[i] = this.cast(value[i], to_datasource);
690
+ }
691
+ } else {
692
+ value = this.cast(value, to_datasource);
693
+ }
694
+
695
+ return value;
696
+ });
697
+
698
+ /**
699
+ * Cast the given value to this field's type.
700
+ * Containers should not be passed (like the array or translation object container)
639
701
  *
640
- * @author Jelle De Loecker <jelle@develry.be>
702
+ * @author Jelle De Loecker <jelle@elevenways.be>
641
703
  * @since 0.2.0
642
- * @version 1.0.7
704
+ * @version 1.4.0
643
705
  *
644
- * @param {Mixed} value
645
- * @param {Boolean} to_datasource Is this meant for the datasource?
706
+ * @param {*} value
707
+ * @param {boolean} to_datasource Is this meant for the datasource?
646
708
  *
647
- * @return {Mixed}
709
+ * @return {*}
648
710
  */
649
711
  Field.setMethod(function cast(value, to_datasource) {
712
+
713
+ if (value === '' && this.datatype !== 'string') {
714
+ value = null;
715
+ }
716
+
717
+ if (value == null && this.is_nullable) {
718
+ return null;
719
+ }
720
+
721
+ return this[CASTER](value, to_datasource);
722
+ });
723
+
724
+ /**
725
+ * Default cast function
726
+ *
727
+ * @author Jelle De Loecker <jelle@elevenways.be>
728
+ * @since 1.4.0
729
+ * @version 1.4.0
730
+ *
731
+ * @param {*} value
732
+ * @param {boolean} to_datasource Is this meant for the datasource?
733
+ *
734
+ * @return {*}
735
+ */
736
+ Field.setCastFunction(function defaultCast(value, to_datasource) {
650
737
  return value;
651
738
  });
652
739
 
653
740
  /**
654
741
  * Cast the given value if it doesn't need to be deferred
655
742
  *
656
- * @author Jelle De Loecker <jelle@develry.be>
743
+ * @author Jelle De Loecker <jelle@elevenways.be>
657
744
  * @since 1.1.5
658
745
  * @version 1.1.5
659
746
  *
660
747
  * @param {Mixed} value
661
- * @param {Boolean} to_datasource Is this meant for the datasource?
748
+ * @param {boolean} to_datasource Is this meant for the datasource?
662
749
  *
663
750
  * @return {Mixed}
664
751
  */
@@ -676,7 +763,7 @@ Field.setMethod(function _initialValueCast(value, to_datasource) {
676
763
  * Allows an array of values.
677
764
  * Calls `castCondition` to do the actual casting per-value.
678
765
  *
679
- * @author Jelle De Loecker <jelle@develry.be>
766
+ * @author Jelle De Loecker <jelle@elevenways.be>
680
767
  * @since 0.2.0
681
768
  * @version 0.5.0
682
769
  *
@@ -708,7 +795,7 @@ Field.setMethod(function castForQuery(value, field_paths) {
708
795
  /**
709
796
  * Cast the given value to this field's type for search in a db
710
797
  *
711
- * @author Jelle De Loecker <jelle@develry.be>
798
+ * @author Jelle De Loecker <jelle@elevenways.be>
712
799
  * @since 0.2.0
713
800
  * @version 1.1.0
714
801
  *
@@ -724,7 +811,7 @@ Field.setMethod(function castCondition(value, field_paths) {
724
811
  /**
725
812
  * Cast the given value to this field's type for search in a db
726
813
  *
727
- * @author Jelle De Loecker <jelle@develry.be>
814
+ * @author Jelle De Loecker <jelle@elevenways.be>
728
815
  * @since 0.5.0
729
816
  * @version 1.2.0
730
817
  *
@@ -746,7 +833,7 @@ Field.setMethod(function _castCondition(value, field_paths) {
746
833
  /**
747
834
  * Prepare the value to be saved in the database
748
835
  *
749
- * @author Jelle De Loecker <jelle@develry.be>
836
+ * @author Jelle De Loecker <jelle@elevenways.be>
750
837
  * @since 0.2.0
751
838
  * @version 0.2.0
752
839
  *
@@ -775,7 +862,7 @@ Field.setMethod(function toDatasource(value, data, datasource, callback) {
775
862
  * The actual toDatasource method inherited Field's can modify.
776
863
  * These won't get passed a null or undefined value.
777
864
  *
778
- * @author Jelle De Loecker <jelle@develry.be>
865
+ * @author Jelle De Loecker <jelle@elevenways.be>
779
866
  * @since 0.2.0
780
867
  * @version 1.1.0
781
868
  *
@@ -796,7 +883,7 @@ Field.setMethod(function _toDatasource(value, data, datasource, callback) {
796
883
  /**
797
884
  * Prepare regular values to be returned
798
885
  *
799
- * @author Jelle De Loecker <jelle@develry.be>
886
+ * @author Jelle De Loecker <jelle@elevenways.be>
800
887
  * @since 0.2.0
801
888
  * @version 1.3.1
802
889
  *
@@ -830,7 +917,7 @@ Field.setMethod(function regularToDatasource(value, data, datasource, callback)
830
917
  /**
831
918
  * Prepare the translatable values to be returned
832
919
  *
833
- * @author Jelle De Loecker <jelle@develry.be>
920
+ * @author Jelle De Loecker <jelle@elevenways.be>
834
921
  * @since 0.2.0
835
922
  * @version 0.2.0
836
923
  *
@@ -853,9 +940,9 @@ Field.setMethod(function translatableToDatasource(value, data, datasource, callb
853
940
  /**
854
941
  * Prepare the value to be returned to node
855
942
  *
856
- * @author Jelle De Loecker <jelle@develry.be>
943
+ * @author Jelle De Loecker <jelle@elevenways.be>
857
944
  * @since 0.2.0
858
- * @version 0.2.0
945
+ * @version 1.4.0
859
946
  *
860
947
  * @param {Object} query The original query
861
948
  * @param {Object} options The original query options
@@ -863,14 +950,6 @@ Field.setMethod(function translatableToDatasource(value, data, datasource, callb
863
950
  * @param {Function} callback
864
951
  */
865
952
  Field.setMethod(function toApp(query, options, value, callback) {
866
-
867
- var that = this,
868
- tasks;
869
-
870
- if (value == null) {
871
- return callback(null, null);
872
- }
873
-
874
953
  if (this.is_translatable) {
875
954
  this.fromTranslatableToApp(query, options, value, callback);
876
955
  } else {
@@ -881,7 +960,7 @@ Field.setMethod(function toApp(query, options, value, callback) {
881
960
  /**
882
961
  * Prepare regular values to be returned
883
962
  *
884
- * @author Jelle De Loecker <jelle@develry.be>
963
+ * @author Jelle De Loecker <jelle@elevenways.be>
885
964
  * @since 0.2.0
886
965
  * @version 0.2.0
887
966
  *
@@ -889,21 +968,20 @@ Field.setMethod(function toApp(query, options, value, callback) {
889
968
  */
890
969
  Field.setMethod(function fromRegularToApp(query, options, value, callback) {
891
970
 
892
- var that = this,
893
- tasks;
894
-
895
971
  // Non-arrayable fields need only 1 call to _toApp
896
972
  if (!this.is_array) {
897
973
  return this._toApp(query, options, value, callback);
898
974
  }
899
975
 
976
+ const that = this;
977
+
900
978
  // If it is an arrayable field, make sure the value is actually an array
901
979
  if (!Array.isArray(value)) {
902
980
  value = Array.cast(value);
903
981
  }
904
982
 
905
983
  // Call _toApp for every value inside the array
906
- tasks = value.map(function eachValue(entry) {
984
+ let tasks = value.map(function eachValue(entry) {
907
985
  return function eachValueToApp(next) {
908
986
  that._toApp(query, options, entry, next);
909
987
  };
@@ -916,7 +994,7 @@ Field.setMethod(function fromRegularToApp(query, options, value, callback) {
916
994
  /**
917
995
  * Prepare the translatable values to be returned
918
996
  *
919
- * @author Jelle De Loecker <jelle@develry.be>
997
+ * @author Jelle De Loecker <jelle@elevenways.be>
920
998
  * @since 0.2.0
921
999
  * @version 1.1.0
922
1000
  *
@@ -956,7 +1034,7 @@ Field.setMethod(function fromTranslatableToApp(query, options, value, callback)
956
1034
  * The actual toApp method inherited Field's can modify.
957
1035
  * These won't get passed a null or undefined value.
958
1036
  *
959
- * @author Jelle De Loecker <jelle@develry.be>
1037
+ * @author Jelle De Loecker <jelle@elevenways.be>
960
1038
  * @since 0.2.0
961
1039
  * @version 1.0.7
962
1040
  *
@@ -972,7 +1050,7 @@ Field.setMethod(function _toApp(query, options, value, callback) {
972
1050
  /**
973
1051
  * Get the default value out of the options
974
1052
  *
975
- * @author Jelle De Loecker <jelle@develry.be>
1053
+ * @author Jelle De Loecker <jelle@elevenways.be>
976
1054
  * @since 0.2.0
977
1055
  * @version 1.1.0
978
1056
  *
@@ -1002,7 +1080,7 @@ Field.setMethod(function getDefault() {
1002
1080
  /**
1003
1081
  * Get the value to store, using the given value
1004
1082
  *
1005
- * @author Jelle De Loecker <jelle@develry.be>
1083
+ * @author Jelle De Loecker <jelle@elevenways.be>
1006
1084
  * @since 0.2.0
1007
1085
  * @version 1.1.5
1008
1086
  *
@@ -1037,11 +1115,11 @@ Field.setMethod(function getValue(value) {
1037
1115
  /**
1038
1116
  * Get the value to store, using the given value
1039
1117
  *
1040
- * @author Jelle De Loecker <jelle@develry.be>
1118
+ * @author Jelle De Loecker <jelle@elevenways.be>
1041
1119
  * @since 0.2.0
1042
1120
  * @version 1.1.5
1043
1121
  *
1044
- * @param {Array} wrapped
1122
+ * @param {Array} wrapped
1045
1123
  */
1046
1124
  Field.setMethod(function _getValue(wrapped, done_translation) {
1047
1125
 
@@ -1087,7 +1165,7 @@ Field.setMethod(function _getValue(wrapped, done_translation) {
1087
1165
  /**
1088
1166
  * See if we need to apply any indexes
1089
1167
  *
1090
- * @author Jelle De Loecker <jelle@elevenways.be>
1168
+ * @author Jelle De Loecker <jelle@elevenways.be>
1091
1169
  * @since 1.1.0
1092
1170
  * @version 1.3.6
1093
1171
  */
@@ -1120,7 +1198,7 @@ Field.setMethod(function checkIndexes() {
1120
1198
  /**
1121
1199
  * Make a client-side safe clone of this field
1122
1200
  *
1123
- * @author Jelle De Loecker <jelle@develry.be>
1201
+ * @author Jelle De Loecker <jelle@elevenways.be>
1124
1202
  * @since 1.1.0
1125
1203
  * @version 1.1.0
1126
1204
  *
@@ -1139,7 +1217,7 @@ Field.setMethod(function toHawkejs(wm) {
1139
1217
  /**
1140
1218
  * Get the client-side options
1141
1219
  *
1142
- * @author Jelle De Loecker <jelle@develry.be>
1220
+ * @author Jelle De Loecker <jelle@elevenways.be>
1143
1221
  * @since 1.1.0
1144
1222
  * @version 1.1.0
1145
1223
  *
@@ -1154,7 +1232,7 @@ Field.setMethod(function getClientConfigOptions(wm) {
1154
1232
  /**
1155
1233
  * Get the options that can be used for drying
1156
1234
  *
1157
- * @author Jelle De Loecker <jelle@elevenways.be>
1235
+ * @author Jelle De Loecker <jelle@elevenways.be>
1158
1236
  * @since 1.3.1
1159
1237
  * @version 1.3.1
1160
1238
  *
@@ -1167,7 +1245,7 @@ Field.setMethod(function getOptionsForDrying() {
1167
1245
  /**
1168
1246
  * Get all the rules for this field
1169
1247
  *
1170
- * @author Jelle De Loecker <jelle@develry.be>
1248
+ * @author Jelle De Loecker <jelle@elevenways.be>
1171
1249
  * @since 1.1.0
1172
1250
  * @version 1.1.0
1173
1251
  *
@@ -1191,13 +1269,13 @@ Field.setMethod(function getRules() {
1191
1269
  /**
1192
1270
  * See if the given vlaue is considered not-empty for this field
1193
1271
  *
1194
- * @author Jelle De Loecker <jelle@elevenways.be>
1272
+ * @author Jelle De Loecker <jelle@elevenways.be>
1195
1273
  * @since 1.3.7
1196
1274
  * @version 1.3.7
1197
1275
  *
1198
1276
  * @param {Mixed} value
1199
1277
  *
1200
- * @return {Boolean}
1278
+ * @return {boolean}
1201
1279
  */
1202
1280
  Field.setMethod(function valueHasContent(value) {
1203
1281
 
@@ -1221,7 +1299,7 @@ Field.setMethod(function valueHasContent(value) {
1221
1299
  /**
1222
1300
  * Translate the given value
1223
1301
  *
1224
- * @author Jelle De Loecker <jelle@develry.be>
1302
+ * @author Jelle De Loecker <jelle@elevenways.be>
1225
1303
  * @since 1.1.4
1226
1304
  * @version 1.2.5
1227
1305
  */