alchemymvc 1.4.0-alpha.2 → 1.4.0-alpha.4

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 (61) hide show
  1. package/lib/app/assets/stylesheets/{alchemy-info.less → alchemy-info.scss} +2 -0
  2. package/lib/app/behaviour/publishable_behaviour.js +1 -3
  3. package/lib/app/behaviour/revision_behaviour.js +35 -20
  4. package/lib/app/behaviour/sluggable_behaviour.js +8 -8
  5. package/lib/app/conduit/loopback_conduit.js +23 -8
  6. package/lib/app/datasource/mongo_datasource.js +318 -286
  7. package/lib/app/helper/alchemy_helper.js +5 -3
  8. package/lib/app/helper/enum_values.js +38 -16
  9. package/lib/app/helper/router_helper.js +36 -21
  10. package/lib/app/helper_controller/controller.js +15 -4
  11. package/lib/app/helper_datasource/00-nosql_datasource.js +1 -1
  12. package/lib/app/helper_datasource/05-fallback_datasource.js +62 -83
  13. package/lib/app/helper_datasource/10-datasource_operational_context.js +153 -0
  14. package/lib/app/helper_datasource/read_operational_context.js +196 -0
  15. package/lib/app/helper_datasource/remote_datasource.js +51 -24
  16. package/lib/app/helper_datasource/remove_operational_context.js +10 -0
  17. package/lib/app/helper_datasource/save_operational_context.js +194 -0
  18. package/lib/app/helper_datasource/schema_operational_context.js +109 -0
  19. package/lib/app/helper_field/00-objectid_field.js +1 -3
  20. package/lib/app/helper_field/11-date_field.js +13 -16
  21. package/lib/app/helper_field/15-local_temporal_field.js +13 -16
  22. package/lib/app/helper_field/20-decimal_field.js +12 -15
  23. package/lib/app/helper_field/30-meta_field.js +27 -0
  24. package/lib/app/helper_field/40-foreign_key_field.js +39 -0
  25. package/lib/app/helper_field/association_alias_field.js +12 -0
  26. package/lib/app/helper_field/belongsto_field.js +2 -2
  27. package/lib/app/helper_field/big_int_field.js +13 -16
  28. package/lib/app/helper_field/datetime_field.js +6 -9
  29. package/lib/app/helper_field/enum_field.js +13 -0
  30. package/lib/app/helper_field/habtm_field.js +1 -5
  31. package/lib/app/helper_field/hasoneparent_field.js +2 -6
  32. package/lib/app/helper_field/mixed_field.js +13 -14
  33. package/lib/app/helper_field/object_field.js +6 -7
  34. package/lib/app/helper_field/password_field.js +12 -9
  35. package/lib/app/helper_field/schema_field.js +318 -198
  36. package/lib/app/helper_field/settings_field.js +6 -6
  37. package/lib/app/helper_model/document.js +20 -22
  38. package/lib/app/helper_model/model.js +180 -25
  39. package/lib/app/model/system_task_model.js +13 -4
  40. package/lib/bootstrap.js +5 -0
  41. package/lib/class/behaviour.js +1 -25
  42. package/lib/class/datasource.js +119 -272
  43. package/lib/class/element.js +16 -0
  44. package/lib/class/field.js +95 -93
  45. package/lib/class/model.js +33 -42
  46. package/lib/class/operational_context.js +129 -0
  47. package/lib/class/route.js +6 -7
  48. package/lib/class/router.js +2 -2
  49. package/lib/class/schema.js +3 -21
  50. package/lib/class/schema_client.js +51 -7
  51. package/lib/core/alchemy.js +10 -3
  52. package/lib/core/alchemy_functions.js +6 -1
  53. package/lib/core/client_alchemy.js +19 -5
  54. package/lib/core/middleware.js +436 -64
  55. package/lib/core/setting.js +1 -1
  56. package/lib/core/stage.js +6 -0
  57. package/lib/scripts/create_shared_constants.js +36 -11
  58. package/lib/scripts/preload_modules.js +0 -1
  59. package/lib/stages/00-load_core.js +9 -0
  60. package/lib/stages/50-routes.js +2 -0
  61. package/package.json +5 -4
@@ -1,3 +1,5 @@
1
+ @use "alchemy";
2
+
1
3
  html {
2
4
  font-family: sans-serif;
3
5
  text-size-adjust: 100%;
@@ -8,9 +8,7 @@
8
8
  * @since 0.1.0
9
9
  * @version 0.3.0
10
10
  */
11
- var Publish = Function.inherits('Alchemy.Behaviour', function PublishableBehaviour(model, options) {
12
- PublishableBehaviour.super.call(this, model, options);
13
- });
11
+ var Publish = Function.inherits('Alchemy.Behaviour', 'PublishableBehaviour');
14
12
 
15
13
  /**
16
14
  * Listen to attachments to schema's
@@ -65,7 +65,7 @@ Revision.setStatic(function getRevisionModel(model) {
65
65
  this.schema.remove('updated');
66
66
 
67
67
  this.addField('record_id', 'ObjectId');
68
- this.addField('revision', 'Number');
68
+ this.addField('revision', 'Integer');
69
69
  this.addField('delta', 'Object');
70
70
 
71
71
  if (Classes.Alchemy.Model.User) {
@@ -100,7 +100,7 @@ Revision.setStatic(function attached(schema, new_options) {
100
100
  const context = schema.model_class;
101
101
 
102
102
  // Add the revision number to the main model
103
- context.addField('__r', 'Number', {
103
+ context.addField('__r', 'Integer', {
104
104
  title: 'Revision',
105
105
  });
106
106
 
@@ -217,30 +217,42 @@ Revision.setMethod(function beforeSave(record, options, creating) {
217
217
  return;
218
218
  }
219
219
 
220
- let that = this,
221
- next = this.wait('series');
220
+ let that = this;
222
221
 
223
- // Find the original record
224
- Model.get(this.model.model_name).findById(record.$pk, async function gotRecord(err, result) {
222
+ let pledge = new Swift();
225
223
 
226
- if (result) {
224
+ // Find the original record
225
+ Model.get(this.model.model_name).findById(record.$pk, function gotRecord(err, result) {
227
226
 
228
- // Get the original data
229
- let ori = await that.model.convertRecordToDatasourceFormat(result);
227
+ if (err || !result) {
228
+ return pledge.resolve();
229
+ }
230
230
 
231
- // Store the original data in a weakmap for later
232
- revision_before.set(options, ori);
231
+ let conversion;
233
232
 
234
- // Increase the revision count by 1
235
- if (ori.__r) {
236
- main.__r = ori.__r+1;
237
- } else {
238
- main.__r = 1;
239
- }
233
+ try {
234
+ conversion = that.model.convertRecordToDatasourceFormat(result);
235
+ } catch (err) {
236
+ return pledge.reject(err);
240
237
  }
241
238
 
242
- next();
239
+ pledge.resolve(Swift.waterfall(
240
+ conversion,
241
+ ori => {
242
+ // Store the original data in a weakmap for later
243
+ revision_before.set(options, ori);
244
+
245
+ // Increase the revision count by 1
246
+ if (ori.__r) {
247
+ main.__r = ori.__r+1;
248
+ } else {
249
+ main.__r = 1;
250
+ }
251
+ }
252
+ ));
243
253
  });
254
+
255
+ return pledge;
244
256
  });
245
257
 
246
258
  /**
@@ -266,9 +278,10 @@ Revision.setMethod(function afterSave(record, options, created) {
266
278
  }
267
279
 
268
280
  let doc = this.model.createDocument(record);
269
- let next = this.wait();
270
281
  const that = this;
271
282
 
283
+ let pledge = new Swift();
284
+
272
285
  // Find the complete saved item
273
286
  Model.get(this.model.model_name).findByPk(doc.$pk, async function gotRecord(err, result) {
274
287
 
@@ -312,6 +325,8 @@ Revision.setMethod(function afterSave(record, options, created) {
312
325
  }
313
326
  }
314
327
 
315
- next();
328
+ pledge.resolve();
316
329
  });
330
+
331
+ return pledge;
317
332
  });
@@ -153,8 +153,7 @@ Sluggable.setMethod(async function beforeSave(data, options, creating) {
153
153
  has_new_value,
154
154
  old_record,
155
155
  new_value,
156
- old_value,
157
- next;
156
+ old_value;
158
157
 
159
158
  // Get the actual record data
160
159
  if (data[that.model.name]) {
@@ -170,9 +169,6 @@ Sluggable.setMethod(async function beforeSave(data, options, creating) {
170
169
  has_new_value = true;
171
170
  }
172
171
 
173
- // Let other event callbacks wait for this one
174
- next = this.wait('series');
175
-
176
172
  if (!creating) {
177
173
  old_record = await this.model.findById(data._id);
178
174
 
@@ -186,7 +182,7 @@ Sluggable.setMethod(async function beforeSave(data, options, creating) {
186
182
  // and we're not explicitly setting a new slug value,
187
183
  // then do nothing
188
184
  if (!creating && old_value && !has_new_value) {
189
- return next();
185
+ return;
190
186
  }
191
187
 
192
188
  let new_data = {};
@@ -198,19 +194,23 @@ Sluggable.setMethod(async function beforeSave(data, options, creating) {
198
194
  Object.assign(new_data, data);
199
195
  }
200
196
 
197
+ let pledge = new Swift();
198
+
201
199
  // Try creating a new slug
202
200
  that.createSlug(new_data, new_value, function createdSlug(err, result) {
203
201
 
204
202
  if (err) {
205
- return next(err);
203
+ return pledge.reject(err);
206
204
  }
207
205
 
208
206
  if (!Object.isEmpty(result)) {
209
207
  data[that.target_field.name] = result;
210
208
  }
211
209
 
212
- next();
210
+ pledge.resolve();
213
211
  });
212
+
213
+ return pledge;
214
214
  });
215
215
 
216
216
  /**
@@ -89,7 +89,7 @@ LoopConduit.setMethod(function copyParentProperties(conduit) {
89
89
  *
90
90
  * @author Jelle De Loecker <jelle@elevenways.be>
91
91
  * @since 1.1.3
92
- * @version 1.3.0
92
+ * @version 1.4.0
93
93
  *
94
94
  * @param {Object} options
95
95
  * @param {Function} callback
@@ -108,17 +108,20 @@ LoopConduit.setMethod(function setOptions(options, callback) {
108
108
  options = JSON.clone(options);
109
109
 
110
110
  for (key in options) {
111
- let set_method = false;
111
+
112
+ // Keep track if a request method has been set
113
+ let got_method = false;
112
114
 
113
115
  info = Classes.Develry.Request.getMethodInfo(key);
114
116
 
115
117
  if (info && options[key]) {
116
118
 
117
- if (info.method == 'get' && set_method) {
118
- // Ignore
119
+ if (info.method == 'get' && got_method) {
120
+ // If a request method has already been set,
121
+ // do not let `get` options overwrite it!
119
122
  } else {
120
123
  this.method = key;
121
- set_method = true;
124
+ got_method = true;
122
125
  }
123
126
 
124
127
  if (info.has_body && typeof options[key] == 'object') {
@@ -131,6 +134,8 @@ LoopConduit.setMethod(function setOptions(options, callback) {
131
134
  this.method = options.method;
132
135
  }
133
136
 
137
+ let route_params = options.params;
138
+
134
139
  if (options.name) {
135
140
  // @TODO: what about path sections?
136
141
  route = this.getRouteByName(options.name);
@@ -147,7 +152,7 @@ LoopConduit.setMethod(function setOptions(options, callback) {
147
152
 
148
153
  // @WARNING: It's best to just generate the URL
149
154
  // and let it parse all the information that way
150
- options.href = this.routeUrl(options.name, options.params, {extra_get_parameters: false});
155
+ options.href = this.routeUrl(options.name, route_params, {extra_get_parameters: false});
151
156
  }
152
157
 
153
158
  if (!this.method) {
@@ -158,6 +163,10 @@ LoopConduit.setMethod(function setOptions(options, callback) {
158
163
 
159
164
  this.original_url = RURL.parse(options.href);
160
165
 
166
+ if (options.get && typeof options.get == 'object') {
167
+ this.original_url.addQuery(options.get);
168
+ }
169
+
161
170
  this.url = this.original_url;
162
171
  this.original_path = this.url.path;
163
172
  this.original_pathname = this.url.pathname;
@@ -169,14 +178,20 @@ LoopConduit.setMethod(function setOptions(options, callback) {
169
178
  this.parseSection();
170
179
 
171
180
  promise = this.parseRoute();
181
+ } else if (options.get && typeof options.get == 'object') {
182
+ if (!this.params) {
183
+ this.params = {};
184
+ }
185
+
186
+ Object.assign(this.params, options.get);
172
187
  }
173
188
 
174
189
  if (options.body) {
175
190
  this.body = options.body;
176
191
  }
177
192
 
178
- if (options.params) {
179
- this.setRouteParameters(options.params);
193
+ if (route_params) {
194
+ this.setRouteParameters(route_params);
180
195
  }
181
196
 
182
197
  if (options.arguments) {