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
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @constructor
5
5
  *
6
- * @author Jelle De Loecker <jelle@elevenways.be>
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
7
  * @since 1.3.20
8
8
  * @version 1.3.20
9
9
  */
@@ -12,7 +12,7 @@ const LocalDateTime = Function.inherits('Alchemy.Field.LocalTemporal', 'LocalDat
12
12
  /**
13
13
  * Set the datatype name
14
14
  *
15
- * @author Jelle De Loecker <jelle@elevenways.be>
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
16
  * @since 1.3.20
17
17
  * @version 1.3.20
18
18
  */
@@ -21,15 +21,15 @@ LocalDateTime.setDatatype('datetime');
21
21
  /**
22
22
  * Cast the given value to this field's type
23
23
  *
24
- * @author Jelle De Loecker <jelle@elevenways.be>
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
25
  * @since 1.3.20
26
26
  * @version 1.3.20
27
27
  *
28
- * @param {Mixed} value
28
+ * @param {*} value
29
29
  *
30
30
  * @return {Develry.LocalDateTime}
31
31
  */
32
- LocalDateTime.setMethod(function cast(value) {
32
+ LocalDateTime.setCastFunction(function cast(value) {
33
33
 
34
34
  if (value == null || value === '') {
35
35
  return null;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @constructor
5
5
  *
6
- * @author Jelle De Loecker <jelle@elevenways.be>
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
7
  * @since 1.3.20
8
8
  * @version 1.3.20
9
9
  */
@@ -12,7 +12,7 @@ const LocalTime = Function.inherits('Alchemy.Field.LocalTemporal', 'LocalTime');
12
12
  /**
13
13
  * Set the datatype name
14
14
  *
15
- * @author Jelle De Loecker <jelle@elevenways.be>
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
16
  * @since 1.3.20
17
17
  * @version 1.3.20
18
18
  */
@@ -21,15 +21,15 @@ LocalTime.setDatatype('time');
21
21
  /**
22
22
  * Cast the given value to this field's type
23
23
  *
24
- * @author Jelle De Loecker <jelle@elevenways.be>
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
25
  * @since 1.3.20
26
26
  * @version 1.3.20
27
27
  *
28
- * @param {Mixed} value
28
+ * @param {*} value
29
29
  *
30
30
  * @return {Develry.LocalTime}
31
31
  */
32
- LocalTime.setMethod(function cast(value) {
32
+ LocalTime.setCastFunction(function cast(value) {
33
33
 
34
34
  if (value == null || value === '') {
35
35
  return null;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @constructor
5
5
  *
6
- * @author Jelle De Loecker <jelle@elevenways.be>
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
7
  * @since 1.3.21
8
8
  * @version 1.3.21
9
9
  */
@@ -12,7 +12,7 @@ const MixedField = Function.inherits('Alchemy.Field', 'Mixed');
12
12
  /**
13
13
  * Set the datatype name
14
14
  *
15
- * @author Jelle De Loecker <jelle@elevenways.be>
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
16
  * @since 1.3.21
17
17
  * @version 1.3.21
18
18
  */
@@ -21,7 +21,7 @@ MixedField.setDatatype('object');
21
21
  /**
22
22
  * This field value is self-contained
23
23
  *
24
- * @author Jelle De Loecker <jelle@elevenways.be>
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
25
  * @since 1.3.21
26
26
  * @version 1.3.21
27
27
  */
@@ -30,7 +30,7 @@ MixedField.setSelfContained(true);
30
30
  /**
31
31
  * Store objects as strings, if wanted
32
32
  *
33
- * @author Jelle De Loecker <jelle@elevenways.be>
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
34
34
  * @since 1.3.21
35
35
  * @version 1.3.21
36
36
  *
@@ -54,7 +54,7 @@ MixedField.setMethod(function _toDatasource(value, data, datasource, callback) {
54
54
  /**
55
55
  * Convert from database to app
56
56
  *
57
- * @author Jelle De Loecker <jelle@elevenways.be>
57
+ * @author Jelle De Loecker <jelle@elevenways.be>
58
58
  * @since 1.3.21
59
59
  * @version 1.3.21
60
60
  *
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @constructor
5
5
  *
6
- * @author Jelle De Loecker <jelle@develry.be>
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
7
  * @since 0.3.0
8
8
  * @version 1.1.0
9
9
  */
@@ -14,7 +14,7 @@ var ObjectField = Function.inherits('Alchemy.Field', function Object(schema, nam
14
14
  /**
15
15
  * Set the datatype name
16
16
  *
17
- * @author Jelle De Loecker <jelle@develry.be>
17
+ * @author Jelle De Loecker <jelle@elevenways.be>
18
18
  * @since 0.3.0
19
19
  * @version 1.1.0
20
20
  */
@@ -23,7 +23,7 @@ ObjectField.setDatatype('object');
23
23
  /**
24
24
  * This field value is self-contained
25
25
  *
26
- * @author Jelle De Loecker <jelle@develry.be>
26
+ * @author Jelle De Loecker <jelle@elevenways.be>
27
27
  * @since 1.1.0
28
28
  * @version 1.1.0
29
29
  */
@@ -32,17 +32,17 @@ ObjectField.setSelfContained(true);
32
32
  /**
33
33
  * Cast the given value to this field's type
34
34
  *
35
- * @author Jelle De Loecker <jelle@develry.be>
35
+ * @author Jelle De Loecker <jelle@elevenways.be>
36
36
  * @since 0.5.0
37
- * @version 0.5.0
37
+ * @version 1.3.22
38
38
  *
39
39
  * @param {Mixed} value
40
40
  *
41
41
  * @return {Object}
42
42
  */
43
- ObjectField.setMethod(function cast(value) {
43
+ ObjectField.setCastFunction(function cast(value) {
44
44
 
45
- if (typeof value == 'string') {
45
+ if (this.options.store_as_string && typeof value == 'string') {
46
46
  return JSON.undry(value);
47
47
  }
48
48
 
@@ -52,7 +52,7 @@ ObjectField.setMethod(function cast(value) {
52
52
  /**
53
53
  * Store objects as strings, if wanted
54
54
  *
55
- * @author Jelle De Loecker <jelle@develry.be>
55
+ * @author Jelle De Loecker <jelle@elevenways.be>
56
56
  * @since 0.5.0
57
57
  * @version 1.1.0
58
58
  *
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @constructor
5
5
  *
6
- * @author Jelle De Loecker <jelle@elevenways.be>
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
7
  * @since 0.2.0
8
8
  * @version 1.2.3
9
9
  */
@@ -19,11 +19,11 @@ const bcrypt = alchemy.use('bcrypt'),
19
19
  /**
20
20
  * Make sure the password is hashed before storing it
21
21
  *
22
- * @author Jelle De Loecker <jelle@develry.be>
22
+ * @author Jelle De Loecker <jelle@elevenways.be>
23
23
  * @since 0.4.0
24
24
  * @version 0.4.0
25
25
  *
26
- * @param {String} value Value of field
26
+ * @param {string} value Value of field
27
27
  * @param {Object} data The data object containing `value`
28
28
  * @param {Datasource} datasource The destination datasource
29
29
  */
@@ -3,18 +3,16 @@
3
3
  *
4
4
  * @constructor
5
5
  *
6
- * @author Jelle De Loecker <jelle@develry.be>
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
7
  * @since 0.2.0
8
8
  * @version 1.1.0
9
9
  */
10
- var RegExpField = Function.inherits('Alchemy.Field', function RegExp(schema, name, options) {
11
- RegExp.super.call(this, schema, name, options);
12
- });
10
+ const RegExpField = Function.inherits('Alchemy.Field', 'RegExp');
13
11
 
14
12
  /**
15
13
  * Set the datatype name
16
14
  *
17
- * @author Jelle De Loecker <jelle@develry.be>
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
18
16
  * @since 0.2.0
19
17
  * @version 1.1.0
20
18
  */
@@ -23,7 +21,7 @@ RegExpField.setDatatype('regexp');
23
21
  /**
24
22
  * This field value is self-contained
25
23
  *
26
- * @author Jelle De Loecker <jelle@develry.be>
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
27
25
  * @since 1.1.0
28
26
  * @version 1.1.0
29
27
  */
@@ -32,15 +30,15 @@ RegExpField.setSelfContained(true);
32
30
  /**
33
31
  * Cast the given value to this field's type
34
32
  *
35
- * @author Jelle De Loecker <jelle@develry.be>
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
36
34
  * @since 0.2.0
37
35
  * @version 0.2.0
38
36
  *
39
37
  * @param {Mixed} value
40
38
  *
41
- * @return {String}
39
+ * @return {string}
42
40
  */
43
- RegExpField.setMethod(function cast(value) {
41
+ RegExpField.setCastFunction(function cast(value) {
44
42
 
45
43
  if (!(value instanceof RegExp)) {
46
44
  value = RegExp.interpret(value);
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @constructor
5
5
  *
6
- * @author Jelle De Loecker <jelle@develry.be>
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
7
  * @since 0.2.0
8
8
  * @version 1.3.16
9
9
  */
@@ -53,7 +53,7 @@ SchemaField.setDeprecatedProperty('fieldSchema', 'field_schema');
53
53
  /**
54
54
  * Schema fields are stored as objects
55
55
  *
56
- * @author Jelle De Loecker <jelle@develry.be>
56
+ * @author Jelle De Loecker <jelle@elevenways.be>
57
57
  * @since 1.1.0
58
58
  * @version 1.1.0
59
59
  */
@@ -62,22 +62,22 @@ SchemaField.setDatatype('object');
62
62
  /**
63
63
  * Is this schema field always an array?
64
64
  *
65
- * @author Jelle De Loecker <jelle@elevenways.be>
65
+ * @author Jelle De Loecker <jelle@elevenways.be>
66
66
  * @since 1.3.16
67
67
  * @version 1.3.16
68
68
  *
69
- * @return {Boolean}
69
+ * @return {boolean}
70
70
  */
71
71
  SchemaField.setProperty('force_array_contents', false);
72
72
 
73
73
  /**
74
74
  * Get the subschema of this field
75
75
  *
76
- * @author Jelle De Loecker <jelle@develry.be>
76
+ * @author Jelle De Loecker <jelle@elevenways.be>
77
77
  * @since 0.2.0
78
78
  * @version 0.2.0
79
79
  *
80
- * @return {String}
80
+ * @return {string}
81
81
  */
82
82
  SchemaField.setProperty(function root_model() {
83
83
  return this.parent_schema.root_model || this.parent_schema.model_name;
@@ -86,11 +86,11 @@ SchemaField.setProperty(function root_model() {
86
86
  /**
87
87
  * Does this field need to be translated in some way?
88
88
  *
89
- * @author Jelle De Loecker <jelle@elevenways.be>
89
+ * @author Jelle De Loecker <jelle@elevenways.be>
90
90
  * @since 1.1.4
91
91
  * @version 1.3.0
92
92
  *
93
- * @type {Boolean}
93
+ * @type {boolean}
94
94
  */
95
95
  SchemaField.setProperty(function requires_translating() {
96
96
 
@@ -108,12 +108,12 @@ SchemaField.setProperty(function requires_translating() {
108
108
  /**
109
109
  * Get the subschema of this field
110
110
  *
111
- * @author Jelle De Loecker <jelle@elevenways.be>
111
+ * @author Jelle De Loecker <jelle@elevenways.be>
112
112
  * @since 0.2.0
113
113
  * @version 1.3.21
114
114
  *
115
115
  * @param {Object} record This *should* be the schema context (might not be the root)
116
- * @param {String} some_path Some path to a field in the wanted schema
116
+ * @param {string} some_path Some path to a field in the wanted schema
117
117
  *
118
118
  * @return {Schema}
119
119
  */
@@ -133,14 +133,14 @@ SchemaField.setMethod(function getSubschema(record, some_path) {
133
133
  /**
134
134
  * Get the subschema of a given schema
135
135
  *
136
- * @author Jelle De Loecker <jelle@elevenways.be>
136
+ * @author Jelle De Loecker <jelle@elevenways.be>
137
137
  * @since 1.3.21
138
138
  * @version 1.3.21
139
139
  *
140
140
  * @param {Schema} context_schema The schema context (probably the schema this field is in)
141
141
  * @param {Object} record This *should* be the schema context (might not be the root)
142
- * @param {String} some_path Some path to a field in the wanted schema
143
- * @param {String} schema The schema path to resolve
142
+ * @param {string} some_path Some path to a field in the wanted schema
143
+ * @param {string} schema The schema path to resolve
144
144
  *
145
145
  * @return {Schema}
146
146
  */
@@ -209,12 +209,12 @@ SchemaField.setMethod(function resolveSchemaPath(context_schema, record, field_p
209
209
  * Get the subschema via an association
210
210
  * @TODO: Work in progress!
211
211
  *
212
- * @author Jelle De Loecker <jelle@elevenways.be>
212
+ * @author Jelle De Loecker <jelle@elevenways.be>
213
213
  * @since 0.2.0
214
214
  * @version 1.3.21
215
215
  *
216
216
  * @param {Object} record This *should* be the schema context (might not be the root)
217
- * @param {String} path The path inside the associated schema
217
+ * @param {string} path The path inside the associated schema
218
218
  * @param {Object} association The association object
219
219
  *
220
220
  * @return {Schema} Response might be a promise
@@ -252,7 +252,7 @@ SchemaField.setMethod(function getSubschemaFromAssociation(record, path, associa
252
252
  /**
253
253
  * Cast all the subschema values using their _toDatasource method
254
254
  *
255
- * @author Jelle De Loecker <jelle@develry.be>
255
+ * @author Jelle De Loecker <jelle@elevenways.be>
256
256
  * @since 0.2.0
257
257
  * @version 1.3.16
258
258
  *
@@ -284,7 +284,7 @@ SchemaField.setMethod(function _toDatasource(value, holder, datasource, callback
284
284
  /**
285
285
  * Cast all the subschema values using their _toDatasource method
286
286
  *
287
- * @author Jelle De Loecker <jelle@develry.be>
287
+ * @author Jelle De Loecker <jelle@elevenways.be>
288
288
  * @since 0.2.0
289
289
  * @version 1.3.1
290
290
  *
@@ -365,9 +365,9 @@ SchemaField.setMethod(function _toDatasourceFromValue(value, holder, datasource,
365
365
  /**
366
366
  * Turn datasource data into app data
367
367
  *
368
- * @author Jelle De Loecker <jelle@develry.be>
368
+ * @author Jelle De Loecker <jelle@elevenways.be>
369
369
  * @since 0.2.0
370
- * @version 1.3.16
370
+ * @version 1.4.0
371
371
  *
372
372
  * @param {Mixed} value
373
373
  * @param {Function} callback
@@ -388,28 +388,34 @@ SchemaField.setMethod(function _toApp(query, options, value, callback) {
388
388
  });
389
389
  }
390
390
 
391
- Function.parallel(tasks, (err, result) => {
391
+ Pledge.Swift.all(tasks).done((err, result) => {
392
392
 
393
393
  if (err) {
394
394
  return callback(err);
395
395
  }
396
396
 
397
- callback(null, this.cast(result));
398
- });
397
+ try {
398
+ result = this.cast(result)
399
+ } catch (err) {
400
+ callback(err);
401
+ return;
402
+ }
399
403
 
404
+ callback(null, result);
405
+ });
400
406
  });
401
407
 
402
408
  /**
403
409
  * Turn datasource data into app data
404
410
  *
405
- * @author Jelle De Loecker <jelle@develry.be>
411
+ * @author Jelle De Loecker <jelle@elevenways.be>
406
412
  * @since 0.2.0
407
- * @version 1.3.16
413
+ * @version 1.4.0
408
414
  *
409
415
  * @param {Mixed} value
410
416
  * @param {Function} callback
411
417
  */
412
- SchemaField.setMethod(function _toAppFromValue(query, options, value, callback) {
418
+ SchemaField.setMethod(async function _toAppFromValue(query, options, value, callback) {
413
419
 
414
420
  var that = this,
415
421
  recursive,
@@ -421,7 +427,11 @@ SchemaField.setMethod(function _toAppFromValue(query, options, value, callback)
421
427
  recursive = options.recursive;
422
428
 
423
429
  if (recursive == null) {
424
- recursive = 1;
430
+ if (this.options?.recursive != null) {
431
+ recursive = this.options.recursive;
432
+ } else {
433
+ recursive = 1;
434
+ }
425
435
  }
426
436
 
427
437
  if (recursive && Blast.isBrowser) {
@@ -430,59 +440,6 @@ SchemaField.setMethod(function _toAppFromValue(query, options, value, callback)
430
440
  recursive = 0;
431
441
  }
432
442
 
433
- // Get associated records if the subschema has associations defined
434
- if (recursive && this.field_schema && !Object.isEmpty(this.field_schema.associations)) {
435
-
436
- name = this.name + 'FieldModel';
437
- Dummy = alchemy.getModel('Model', false);
438
-
439
- Dummy = new Dummy({
440
- root_model : this.root_model,
441
- name : name
442
- });
443
-
444
- item = {};
445
-
446
- item[name] = value;
447
-
448
- let sub_criteria = Dummy.find();
449
-
450
- // Disable generating Document instances
451
- // if the original find did the same
452
- sub_criteria.setOption('document', options.document);
453
- sub_criteria.setOption('original_query', query);
454
- sub_criteria.setOption('_root_data', options._root_data);
455
- sub_criteria.setOption('_parent_field', that);
456
- sub_criteria.setOption('_parent_model', that.schema.model_name);
457
- sub_criteria.setOption('recursive', recursive);
458
-
459
- sub_criteria.setOption('associations', this.field_schema.associations);
460
-
461
- // @todo: inherit other original find options?
462
-
463
- Dummy.addAssociatedDataToRecord(sub_criteria, item, function gotAssociatedData(err, result) {
464
-
465
- var key;
466
-
467
- if (err) {
468
- return callback(err);
469
- }
470
-
471
- for (key in result) {
472
- if (key == name) {
473
- continue;
474
- }
475
-
476
- value[key] = result[key];
477
- }
478
-
479
- callback(null, value);
480
- }
481
- );
482
-
483
- return;
484
- }
485
-
486
443
  let record;
487
444
 
488
445
  if (options.parent_value) {
@@ -532,14 +489,60 @@ SchemaField.setMethod(function _toAppFromValue(query, options, value, callback)
532
489
  }
533
490
  });
534
491
 
535
- return Function.parallel(4, tasks, function convertedFields(err, result) {
492
+ value = await Function.parallel(4, tasks);
493
+ }
536
494
 
537
- if (err) {
538
- return callback(err);
539
- }
495
+ // Get associated records if the subschema has associations defined
496
+ if (recursive && this.field_schema && !Object.isEmpty(this.field_schema.associations)) {
540
497
 
541
- callback(null, that.castEntry(result));
498
+ name = this.name + 'FieldModel';
499
+ Dummy = alchemy.getModel('Model', false);
500
+
501
+ Dummy = new Dummy({
502
+ root_model : this.root_model,
503
+ name : name
542
504
  });
505
+
506
+ item = {};
507
+
508
+ item[name] = value;
509
+
510
+ let sub_criteria = Dummy.find();
511
+
512
+ // Disable generating Document instances
513
+ // if the original find did the same
514
+ sub_criteria.setOption('document', options.document);
515
+ sub_criteria.setOption('original_query', query);
516
+ sub_criteria.setOption('_root_data', options._root_data);
517
+ sub_criteria.setOption('_parent_field', that);
518
+ sub_criteria.setOption('_parent_model', that.schema.model_name);
519
+ sub_criteria.setOption('recursive', recursive);
520
+
521
+ sub_criteria.setOption('associations', this.field_schema.associations);
522
+
523
+ // @todo: inherit other original find options?
524
+
525
+ Dummy.addAssociatedDataToRecord(sub_criteria, item, function gotAssociatedData(err, result) {
526
+
527
+ var key;
528
+
529
+ if (err) {
530
+ return callback(err);
531
+ }
532
+
533
+ for (key in result) {
534
+ if (key == name) {
535
+ continue;
536
+ }
537
+
538
+ value[key] = result[key];
539
+ }
540
+
541
+ callback(null, value);
542
+ }
543
+ );
544
+
545
+ return;
543
546
  }
544
547
 
545
548
  callback(null, this.castEntry(value));
@@ -548,7 +551,7 @@ SchemaField.setMethod(function _toAppFromValue(query, options, value, callback)
548
551
  /**
549
552
  * Translate the given value
550
553
  *
551
- * @author Jelle De Loecker <jelle@elevenways.be>
554
+ * @author Jelle De Loecker <jelle@elevenways.be>
552
555
  * @since 1.1.4
553
556
  * @version 1.3.0
554
557
  */
@@ -601,7 +604,7 @@ SchemaField.setMethod(function translateRecord(prefixes, record, allow_empty) {
601
604
  /**
602
605
  * Cast an entry
603
606
  *
604
- * @author Jelle De Loecker <jelle@elevenways.be>
607
+ * @author Jelle De Loecker <jelle@elevenways.be>
605
608
  * @since 1.3.16
606
609
  * @version 1.3.16
607
610
  */
@@ -612,10 +615,10 @@ SchemaField.setMethod(function castEntry(value, to_datasource) {
612
615
  /**
613
616
  * Cast the value to a document
614
617
  *
615
- * @author Jelle De Loecker <jelle@elevenways.be>
618
+ * @author Jelle De Loecker <jelle@elevenways.be>
616
619
  * @since 1.1.5
617
620
  * @version 1.1.5
618
621
  */
619
- SchemaField.setMethod(function cast(value, to_datasource) {
622
+ SchemaField.setCastFunction(function cast(value, to_datasource) {
620
623
  return value;
621
624
  });
@@ -0,0 +1,92 @@
1
+ /**
2
+ * A Settings field lets you add settings to something
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.4.0
8
+ * @version 1.4.0
9
+ */
10
+ const Settings = Function.inherits('Alchemy.Field.Schema', function Settings(schema, name, options) {
11
+
12
+ if (!options?.setting_group) {
13
+ throw new Error('A settings field requires a `setting_group` option with');
14
+ }
15
+
16
+ // A custom schema should NOT be passed to this class, this class uses
17
+ // a fixed schema that should not be altered.
18
+ // But because that's exactly what happens when cloning (like preparing
19
+ // the data to be sent to Hawkejs) we have to allow it anyway
20
+ if (!options.schema) {
21
+ let settings_schema = alchemy.createSchema();
22
+
23
+ settings_schema.addField('setting_id', 'Enum', {
24
+ description: 'The setting id',
25
+ values : options.setting_group.createEnumMap(),
26
+ });
27
+
28
+ settings_schema.addField('configuration', 'Schema', {
29
+ description: 'The actual configuration of the setting',
30
+ schema : 'setting_id',
31
+ });
32
+
33
+ options.schema = settings_schema;
34
+ }
35
+
36
+ Settings.super.call(this, schema, name, options);
37
+ });
38
+
39
+ /**
40
+ * Is this schema field always an array?
41
+ *
42
+ * @author Jelle De Loecker <jelle@elevenways.be>
43
+ * @since 1.4.0
44
+ * @version 1.4.0
45
+ *
46
+ * @return {Boolean}
47
+ */
48
+ Settings.setProperty('force_array_contents', true);
49
+
50
+ /**
51
+ * Cast the given value to this field's type
52
+ *
53
+ * @author Jelle De Loecker <jelle@elevenways.be>
54
+ * @since 1.4.0
55
+ * @version 1.4.0
56
+ *
57
+ * @param {*} value
58
+ *
59
+ * @return {Settings}
60
+ */
61
+ Settings.setCastFunction(function cast(value) {
62
+
63
+ let result = this.options.setting_group.generateValue();
64
+
65
+ if (value) {
66
+ result.setValueSilently(value);
67
+ }
68
+
69
+ return result;
70
+ });
71
+
72
+ /**
73
+ * Prepare the value of this field to be stored in the database
74
+ *
75
+ * @author Jelle De Loecker <jelle@elevenways.be>
76
+ * @since 1.4.0
77
+ * @version 1.4.0
78
+ *
79
+ * @param {*} value The field's own value
80
+ * @param {Object} data The main record
81
+ * @param {Datasource} datasource The datasource instance
82
+ *
83
+ * @return {*}
84
+ */
85
+ Settings.setMethod(function _toDatasource(value, data, datasource, callback) {
86
+
87
+ if (value) {
88
+ value = value.toDatasourceArray();
89
+ }
90
+
91
+ _toDatasource.super.call(this, value, data, datasource, callback);
92
+ });