alchemymvc 1.3.19 → 1.3.21

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 (42) hide show
  1. package/lib/app/behaviour/sluggable_behaviour.js +0 -0
  2. package/lib/app/datasource/mongo_datasource.js +94 -1
  3. package/lib/app/element/time_ago.js +0 -0
  4. package/lib/app/helper/alchemy_helper.js +8 -4
  5. package/lib/app/helper_controller/controller.js +1 -0
  6. package/lib/app/helper_datasource/00-nosql_datasource.js +0 -0
  7. package/lib/app/helper_field/{date_field.js → 11-date_field.js} +1 -3
  8. package/lib/app/helper_field/15-local_temporal_field.js +100 -0
  9. package/lib/app/helper_field/20-decimal_field.js +105 -0
  10. package/lib/app/helper_field/big_int_field.js +7 -13
  11. package/lib/app/helper_field/fixed_decimal_field.js +44 -0
  12. package/lib/app/helper_field/local_date_field.js +39 -0
  13. package/lib/app/helper_field/local_date_time_field.js +39 -0
  14. package/lib/app/helper_field/local_time_field.js +39 -0
  15. package/lib/app/helper_field/mixed_field.js +73 -0
  16. package/lib/app/helper_field/schema_field.js +121 -35
  17. package/lib/app/helper_model/criteria.js +13 -0
  18. package/lib/app/helper_model/document.js +229 -0
  19. package/lib/app/helper_model/field_set.js +0 -0
  20. package/lib/app/helper_model/model.js +91 -18
  21. package/lib/app/model/alchemy_task_history_model.js +0 -0
  22. package/lib/bootstrap.js +0 -0
  23. package/lib/class/conduit.js +2 -2
  24. package/lib/class/datasource.js +80 -0
  25. package/lib/class/document.js +27 -0
  26. package/lib/class/field.js +110 -0
  27. package/lib/class/inode_file.js +0 -0
  28. package/lib/class/model.js +50 -28
  29. package/lib/class/path_evaluator.js +16 -9
  30. package/lib/class/route.js +4 -1
  31. package/lib/class/router.js +4 -2
  32. package/lib/class/schema_client.js +163 -20
  33. package/lib/class/session.js +0 -0
  34. package/lib/class/task.js +48 -2
  35. package/lib/class/task_service.js +37 -8
  36. package/lib/core/base.js +19 -4
  37. package/lib/core/client_alchemy.js +84 -1
  38. package/lib/core/middleware.js +27 -7
  39. package/lib/init/alchemy.js +4 -1
  40. package/lib/init/constants.js +23 -0
  41. package/lib/init/requirements.js +0 -0
  42. package/package.json +3 -3
File without changes
@@ -1,4 +1,5 @@
1
- var MongoClient = alchemy.use('mongodb').MongoClient;
1
+ const mongo = alchemy.use('mongodb'),
2
+ MongoClient = mongo.MongoClient;
2
3
 
3
4
  /**
4
5
  * MongoDb Datasource
@@ -102,6 +103,98 @@ Mongo.setProperty('allowed_find_options', [
102
103
  'session'
103
104
  ]);
104
105
 
106
+ /**
107
+ * Convert the given value to a BigInt
108
+ *
109
+ * @author Jelle De Loecker <jelle@elevenways.be>
110
+ * @since 1.3.20
111
+ * @version 1.3.20
112
+ *
113
+ * @param {*} value
114
+ *
115
+ * @return {BigInt}
116
+ */
117
+ Mongo.setMethod(function castToBigInt(value) {
118
+
119
+ if (value == null) {
120
+ return value;
121
+ }
122
+
123
+ if (typeof value == 'object') {
124
+ return value.toBigInt();
125
+ }
126
+
127
+ return BigInt(value);
128
+ });
129
+
130
+ /**
131
+ * Convert the given value from a BigInt (for use in DB)
132
+ *
133
+ * @author Jelle De Loecker <jelle@elevenways.be>
134
+ * @since 1.3.20
135
+ * @version 1.3.20
136
+ *
137
+ * @param {BigInt} value
138
+ *
139
+ * @return {Mongo.Long}
140
+ */
141
+ Mongo.setMethod(function convertBigIntForDatasource(value) {
142
+
143
+ if (value == null) {
144
+ return value;
145
+ }
146
+
147
+ return mongo.Long.fromBigInt(value);
148
+ });
149
+
150
+ /**
151
+ * Convert the given value to a Decimal (for use in JS)
152
+ *
153
+ * @author Jelle De Loecker <jelle@elevenways.be>
154
+ * @since 1.3.20
155
+ * @version 1.3.20
156
+ *
157
+ * @param {*} value
158
+ *
159
+ * @return {BigInt}
160
+ */
161
+ Mongo.setMethod(function castToDecimal(value) {
162
+
163
+ if (value == null) {
164
+ return value;
165
+ }
166
+
167
+ if (typeof value == 'object') {
168
+ value = value.toString();
169
+ }
170
+
171
+ return new Blast.Classes.Develry.Decimal(value);
172
+ });
173
+
174
+ /**
175
+ * Convert the given decimal for use in DB
176
+ *
177
+ * @author Jelle De Loecker <jelle@elevenways.be>
178
+ * @since 1.3.20
179
+ * @version 1.3.20
180
+ *
181
+ * @param {Decimal|String} value
182
+ *
183
+ * @return {Mongo.Decimal128}
184
+ */
185
+ Mongo.setMethod(function convertDecimalForDatasource(value) {
186
+
187
+ if (value == null) {
188
+ return value;
189
+ }
190
+
191
+ if (!(value instanceof Blast.Classes.Develry.Decimal)) {
192
+ value = new Blast.Classes.Develry.Decimal(value);
193
+ }
194
+
195
+ return mongo.Decimal128.fromString(value.toString());
196
+ });
197
+
105
198
  /**
106
199
  * Get find options for the MongoDB server
107
200
  *
File without changes
@@ -30,7 +30,7 @@ Alchemy.setStatic(function onScene(scene, options) {
30
30
  *
31
31
  * @author Jelle De Loecker <jelle@elevenways.be>
32
32
  * @since 0.0.1
33
- * @version 1.2.7
33
+ * @version 1.3.21
34
34
  *
35
35
  * @param {String|Object} options
36
36
  * @param {Object} data
@@ -122,10 +122,14 @@ Alchemy.setMethod(function getResource(options, data, callback) {
122
122
 
123
123
  config = this.view.helpers.Router.routeConfig(options.name);
124
124
 
125
- if (config && config.methods) {
126
- if (config.methods.indexOf('get') == -1) {
125
+ if (config) {
126
+ if (config.methods && config.methods.indexOf('get') == -1) {
127
127
  method = config.methods[0];
128
128
  }
129
+
130
+ if (config.cache != null && options.cache == null) {
131
+ options.cache = config.cache;
132
+ }
129
133
  }
130
134
 
131
135
  // Get the url to the resource
@@ -150,7 +154,7 @@ Alchemy.setMethod(function getResource(options, data, callback) {
150
154
  options[method] = true;
151
155
  }
152
156
 
153
- pledge = hawkejs.scene.fetch(options);
157
+ pledge = this.view.fetch(options);
154
158
  pledge.done(callback);
155
159
 
156
160
  return pledge;
@@ -359,6 +359,7 @@ Controller.setMethod(async function doAction(name, args) {
359
359
  if (route) {
360
360
 
361
361
  if (route.options?.title) {
362
+ // @TODO: Add support for objects with language keys
362
363
  let title = route.options.title;
363
364
 
364
365
  if (alchemy.settings && alchemy.settings.title_suffix) {
File without changes
@@ -7,9 +7,7 @@
7
7
  * @since 0.2.0
8
8
  * @version 1.1.0
9
9
  */
10
- var DateField = Function.inherits('Alchemy.Field', function Date(schema, name, options) {
11
- Date.super.call(this, schema, name, options);
12
- });
10
+ const DateField = Function.inherits('Alchemy.Field', 'Date');
13
11
 
14
12
  /**
15
13
  * Set the datatype name
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The abstract LocalTemporal Field class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.3.20
8
+ * @version 1.3.20
9
+ */
10
+ const LocalTemporal = Function.inherits('Alchemy.Field.Date', 'LocalTemporal');
11
+
12
+ /**
13
+ * Mark this class as being abstract
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 1.3.20
17
+ * @version 1.3.20
18
+ */
19
+ LocalTemporal.makeAbstractClass();
20
+
21
+ /**
22
+ * Cast the given value to this field's type for search in a db
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 1.3.20
26
+ * @version 1.3.20
27
+ *
28
+ * @param {Mixed} value
29
+ * @param {Array} field_paths The path to the field
30
+ *
31
+ * @return {Mixed}
32
+ */
33
+ LocalTemporal.setMethod(function _castCondition(value, field_paths) {
34
+
35
+ if (value == null) {
36
+ return value;
37
+ }
38
+
39
+ value = this.cast(value);
40
+ value = value.toNumericRepresentation();
41
+
42
+ if (typeof value == 'bigint') {
43
+ value = this.datasource.convertBigIntForDatasource(value);
44
+ }
45
+
46
+ return value;
47
+ });
48
+
49
+ /**
50
+ * Prepare the value to be stored in the database
51
+ *
52
+ * @author Jelle De Loecker <jelle@elevenways.be>
53
+ * @since 1.3.20
54
+ * @version 1.3.20
55
+ *
56
+ * @param {Mixed} value The field's own value
57
+ * @param {Object} data The main record
58
+ * @param {Datasource} datasource The datasource instance
59
+ *
60
+ * @return {Mixed}
61
+ */
62
+ LocalTemporal.setMethod(function _toDatasource(value, data, datasource, callback) {
63
+
64
+ value = this.cast(value);
65
+
66
+ if (value) {
67
+ value = value.toNumericRepresentation();
68
+ }
69
+
70
+ if (typeof value == 'bigint') {
71
+ value = this.datasource.convertBigIntForDatasource(value);
72
+ }
73
+
74
+ Blast.nextTick(() => callback(null, value));
75
+ });
76
+
77
+ /**
78
+ * Convert from database to app
79
+ *
80
+ * @author Jelle De Loecker <jelle@elevenways.be>
81
+ * @since 1.3.20
82
+ * @version 1.3.20
83
+ *
84
+ * @param {Object} query The original query
85
+ * @param {Object} options The original query options
86
+ * @param {Mixed} value The field value, as stored in the DB
87
+ * @param {Function} callback
88
+ */
89
+ LocalTemporal.setMethod(function _toApp(query, options, value, callback) {
90
+
91
+ if (value && typeof value == 'object') {
92
+ if (typeof value.getUTCDate != 'function') {
93
+ value = this.datasource.castToBigInt(value);
94
+ }
95
+ }
96
+
97
+ value = this.cast(value);
98
+
99
+ callback(null, value);
100
+ });
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The Decimal Field class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.3.20
8
+ * @version 1.3.20
9
+ */
10
+ const DecimalField = Function.inherits('Alchemy.Field.Number', 'Decimal');
11
+
12
+ /**
13
+ * Cast the given value to this field's type
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 1.3.20
17
+ * @version 1.3.20
18
+ *
19
+ * @param {Mixed} value
20
+ *
21
+ * @return {Decimal}
22
+ */
23
+ DecimalField.setMethod(function cast(value) {
24
+
25
+ // Allow null
26
+ if (value == null) {
27
+ return value;
28
+ }
29
+
30
+ if (value instanceof Classes.Develry.Decimal) {
31
+ value = value.toImmutable();
32
+ } else {
33
+ value = new Classes.Develry.Decimal(value);
34
+ }
35
+
36
+ return value;
37
+ });
38
+
39
+ /**
40
+ * Cast the given value to this field's type for search in a db
41
+ *
42
+ * @author Jelle De Loecker <jelle@elevenways.be>
43
+ * @since 1.3.20
44
+ * @version 1.3.20
45
+ *
46
+ * @param {Mixed} value
47
+ * @param {Array} field_paths The path to the field
48
+ *
49
+ * @return {Mixed}
50
+ */
51
+ DecimalField.setMethod(function _castCondition(value, field_paths) {
52
+
53
+ if (value == null) {
54
+ return value;
55
+ }
56
+
57
+ value = this.cast(value);
58
+ value = this.datasource.convertDecimalForDatasource(value);
59
+
60
+ return value;
61
+ });
62
+
63
+ /**
64
+ * Prepare the value to be stored in the database
65
+ *
66
+ * @author Jelle De Loecker <jelle@elevenways.be>
67
+ * @since 1.3.20
68
+ * @version 1.3.20
69
+ *
70
+ * @param {Mixed} value The field's own value
71
+ * @param {Object} data The main record
72
+ * @param {Datasource} datasource The datasource instance
73
+ *
74
+ * @return {Mixed}
75
+ */
76
+ DecimalField.setMethod(function _toDatasource(value, data, datasource, callback) {
77
+
78
+ value = this.cast(value);
79
+ value = this.datasource.convertDecimalForDatasource(value);
80
+
81
+ Blast.nextTick(() => callback(null, value));
82
+ });
83
+
84
+ /**
85
+ * Convert from database to app
86
+ *
87
+ * @author Jelle De Loecker <jelle@elevenways.be>
88
+ * @since 1.3.20
89
+ * @version 1.3.20
90
+ *
91
+ * @param {Object} query The original query
92
+ * @param {Object} options The original query options
93
+ * @param {Mixed} value The field value, as stored in the DB
94
+ * @param {Function} callback
95
+ */
96
+ DecimalField.setMethod(function _toApp(query, options, value, callback) {
97
+
98
+ if (value && typeof value == 'object') {
99
+ value = value.toString();
100
+ }
101
+
102
+ value = this.cast(value);
103
+
104
+ callback(null, value);
105
+ });
@@ -50,7 +50,7 @@ BigIntField.setMethod(function cast(value) {
50
50
  *
51
51
  * @author Jelle De Loecker <jelle@elevenways.be>
52
52
  * @since 1.3.6
53
- * @version 1.3.6
53
+ * @version 1.3.21
54
54
  *
55
55
  * @param {Mixed} value
56
56
  * @param {Array} field_paths The path to the field
@@ -60,10 +60,7 @@ BigIntField.setMethod(function cast(value) {
60
60
  BigIntField.setMethod(function _castCondition(value, field_paths) {
61
61
 
62
62
  value = this.cast(value);
63
-
64
- if (mongo) {
65
- value = mongo.Long.fromBigInt(value);
66
- }
63
+ value = this.datasource.convertBigIntForDatasource(value);
67
64
 
68
65
  return value;
69
66
  });
@@ -73,7 +70,7 @@ BigIntField.setMethod(function _castCondition(value, field_paths) {
73
70
  *
74
71
  * @author Jelle De Loecker <jelle@elevenways.be>
75
72
  * @since 1.3.6
76
- * @version 1.3.6
73
+ * @version 1.3.20
77
74
  *
78
75
  * @param {Mixed} value The field's own value
79
76
  * @param {Object} data The main record
@@ -84,10 +81,7 @@ BigIntField.setMethod(function _castCondition(value, field_paths) {
84
81
  BigIntField.setMethod(function _toDatasource(value, data, datasource, callback) {
85
82
 
86
83
  value = this.cast(value);
87
-
88
- if (mongo) {
89
- value = mongo.Long.fromBigInt(value);
90
- }
84
+ value = this.datasource.convertBigIntForDatasource(value);
91
85
 
92
86
  callback(null, value);
93
87
  });
@@ -97,7 +91,7 @@ BigIntField.setMethod(function _toDatasource(value, data, datasource, callback)
97
91
  *
98
92
  * @author Jelle De Loecker <jelle@elevenways.be>
99
93
  * @since 1.3.6
100
- * @version 1.3.6
94
+ * @version 1.3.20
101
95
  *
102
96
  * @param {Object} query The original query
103
97
  * @param {Object} options The original query options
@@ -106,8 +100,8 @@ BigIntField.setMethod(function _toDatasource(value, data, datasource, callback)
106
100
  */
107
101
  BigIntField.setMethod(function _toApp(query, options, value, callback) {
108
102
 
109
- if (mongo && value && value.toBigInt) {
110
- value = value.toBigInt();
103
+ if (value) {
104
+ value = this.datasource.castToBigInt(value);
111
105
  }
112
106
 
113
107
  value = this.cast(value);
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The FixedDecimal Field class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.3.20
8
+ * @version 1.3.20
9
+ */
10
+ const FixedDecimalField = Function.inherits('Alchemy.Field.Decimal', function FixedDecimal(schema, name, options) {
11
+
12
+ if (options?.scale == null) {
13
+ throw new Error('FixedDecimal fields require a scale option');
14
+ }
15
+
16
+ FixedDecimal.super.call(this, schema, name, options);
17
+ });
18
+
19
+ /**
20
+ * Cast the given value to this field's type
21
+ *
22
+ * @author Jelle De Loecker <jelle@elevenways.be>
23
+ * @since 1.3.20
24
+ * @version 1.3.20
25
+ *
26
+ * @param {Mixed} value
27
+ *
28
+ * @return {Decimal}
29
+ */
30
+ FixedDecimalField.setMethod(function cast(value) {
31
+
32
+ // Allow null
33
+ if (value == null) {
34
+ return value;
35
+ }
36
+
37
+ if (value instanceof Classes.Develry.Decimal) {
38
+ value = value.toImmutable().toScale(this.options.scale);
39
+ } else {
40
+ value = new Classes.Develry.FixedDecimal(value, this.options.scale);
41
+ }
42
+
43
+ return value;
44
+ });
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The LocalDate Field class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.3.20
8
+ * @version 1.3.20
9
+ */
10
+ const LocalDate = Function.inherits('Alchemy.Field.LocalTemporal', 'LocalDate');
11
+
12
+ /**
13
+ * Set the datatype name
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 1.3.20
17
+ * @version 1.3.20
18
+ */
19
+ LocalDate.setDatatype('date');
20
+
21
+ /**
22
+ * Cast the given value to this field's type
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 1.3.20
26
+ * @version 1.3.20
27
+ *
28
+ * @param {Mixed} value
29
+ *
30
+ * @return {Develry.LocalDate}
31
+ */
32
+ LocalDate.setMethod(function cast(value) {
33
+
34
+ if (value == null || value === '') {
35
+ return null;
36
+ }
37
+
38
+ return Classes.Develry.LocalDate.create(value);
39
+ });
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The LocalDateTime Field class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.3.20
8
+ * @version 1.3.20
9
+ */
10
+ const LocalDateTime = Function.inherits('Alchemy.Field.LocalTemporal', 'LocalDateTime');
11
+
12
+ /**
13
+ * Set the datatype name
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 1.3.20
17
+ * @version 1.3.20
18
+ */
19
+ LocalDateTime.setDatatype('datetime');
20
+
21
+ /**
22
+ * Cast the given value to this field's type
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 1.3.20
26
+ * @version 1.3.20
27
+ *
28
+ * @param {Mixed} value
29
+ *
30
+ * @return {Develry.LocalDateTime}
31
+ */
32
+ LocalDateTime.setMethod(function cast(value) {
33
+
34
+ if (value == null || value === '') {
35
+ return null;
36
+ }
37
+
38
+ return Classes.Develry.LocalDateTime.create(value);
39
+ });
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The LocalTime Field class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.3.20
8
+ * @version 1.3.20
9
+ */
10
+ const LocalTime = Function.inherits('Alchemy.Field.LocalTemporal', 'LocalTime');
11
+
12
+ /**
13
+ * Set the datatype name
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 1.3.20
17
+ * @version 1.3.20
18
+ */
19
+ LocalTime.setDatatype('time');
20
+
21
+ /**
22
+ * Cast the given value to this field's type
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 1.3.20
26
+ * @version 1.3.20
27
+ *
28
+ * @param {Mixed} value
29
+ *
30
+ * @return {Develry.LocalTime}
31
+ */
32
+ LocalTime.setMethod(function cast(value) {
33
+
34
+ if (value == null || value === '') {
35
+ return null;
36
+ }
37
+
38
+ return Classes.Develry.LocalTime.create(value);
39
+ });
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The Mixed Field class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 1.3.21
8
+ * @version 1.3.21
9
+ */
10
+ const MixedField = Function.inherits('Alchemy.Field', 'Mixed');
11
+
12
+ /**
13
+ * Set the datatype name
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 1.3.21
17
+ * @version 1.3.21
18
+ */
19
+ MixedField.setDatatype('object');
20
+
21
+ /**
22
+ * This field value is self-contained
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 1.3.21
26
+ * @version 1.3.21
27
+ */
28
+ MixedField.setSelfContained(true);
29
+
30
+ /**
31
+ * Store objects as strings, if wanted
32
+ *
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
34
+ * @since 1.3.21
35
+ * @version 1.3.21
36
+ *
37
+ * @param {Mixed} value The field's own value
38
+ * @param {Object} data The main record
39
+ * @param {Datasource} datasource The datasource instance
40
+ *
41
+ * @return {Mixed}
42
+ */
43
+ MixedField.setMethod(function _toDatasource(value, data, datasource, callback) {
44
+
45
+ if (value && typeof value == 'object' && !Object.isPlainObject(value)) {
46
+ if (!(value instanceof Date)) {
47
+ value = JSON.toDryObject(value);
48
+ }
49
+ }
50
+
51
+ Blast.nextTick(callback, null, null, value);
52
+ });
53
+
54
+ /**
55
+ * Convert from database to app
56
+ *
57
+ * @author Jelle De Loecker <jelle@elevenways.be>
58
+ * @since 1.3.21
59
+ * @version 1.3.21
60
+ *
61
+ * @param {Object} query The original query
62
+ * @param {Object} options The original query options
63
+ * @param {Mixed} value The field value, as stored in the DB
64
+ * @param {Function} callback
65
+ */
66
+ MixedField.setMethod(function _toApp(query, options, value, callback) {
67
+
68
+ if (value && typeof value == 'object' && typeof value.dry == 'string') {
69
+ value = JSON.unDry(value);
70
+ }
71
+
72
+ callback(null, value);
73
+ });