alchemymvc 1.2.1 → 1.2.2

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.
@@ -8,151 +8,98 @@
8
8
  * @since 0.0.1
9
9
  * @version 1.0.0
10
10
  */
11
- var Paginate = Function.inherits('Alchemy.Client.Component', function Paginate(controller, options) {
12
- Paginate.super.call(this, controller, options);
13
- });
11
+ const Paginate = Function.inherits('Alchemy.Client.Component', 'Paginate');
14
12
 
15
13
  /**
16
14
  * Perform a query
17
15
  *
18
- * @author Jelle De Loecker <jelle@develry.be>
16
+ * @author Jelle De Loecker <jelle@elevenways.be>
19
17
  * @since 0.0.1
20
- * @version 1.0.6
18
+ * @version 1.2.2
21
19
  *
22
20
  * @param {Model} model
23
- * @param {Object} options
24
- * @param {Function} callback
21
+ * @param {Criteria} criteria
25
22
  *
26
23
  * @return {Pledge}
27
24
  */
28
- Paginate.setMethod(function find(model, options, callback) {
29
-
30
- var that = this,
31
- conduit = this.controller.conduit,
32
- conditions,
33
- last_id,
34
- filter,
35
- pledge,
36
- order,
37
- name,
38
- sort;
25
+ Paginate.setMethod(function find(model, criteria) {
26
+
27
+ const conduit = this.controller.conduit;
39
28
 
40
29
  // Get the model if a name has been given
41
30
  if (typeof model == 'string') {
42
31
  model = this.getModel(model);
43
32
  }
44
33
 
45
- // Make sure callback is set correctly
46
- if (typeof options == 'function') {
47
- callback = options;
48
- }
49
-
50
- // Make sure options is an object
51
- if (!options || typeof options != 'object') {
52
- options = {};
53
- }
54
-
55
- // Set the name for this pagination
56
- if (!options.name) {
57
- options.name = model.name;
58
- } else {
59
- options.name = options.name.modelName();
60
- }
34
+ let page_size = criteria.options.page_size || 10,
35
+ skipless = criteria.options.skipless,
36
+ last_id,
37
+ name = criteria.options.name,
38
+ page = criteria.options.page;
61
39
 
62
- if (!options.pageSize) {
63
- options.pageSize = 10;
40
+ if (!name) {
41
+ name = model.name;
42
+ criteria.setOption('name', name);
64
43
  }
65
44
 
66
- if (options.skipless) {
67
- last_id = options.last_id || conduit.param('page');
45
+ if (skipless) {
46
+ let sort;
47
+ last_id = criteria.options.last_id || conduit.param('page');
68
48
 
69
49
  // When it's a skipless pagination,
70
50
  // a sort is always implied
71
- if (options.skipless === true) {
51
+ if (skipless === true) {
72
52
  sort = {_id: 1};
73
53
  } else {
74
54
  sort = {};
75
- sort[options.skipless] = 1;
55
+ sort[skipless] = 1;
76
56
  }
77
57
 
78
- options.sort = sort;
79
-
58
+ criteria.sort(sort);
80
59
  } else {
81
60
 
82
61
  // If no page has been given
83
- if (typeof options.page != 'number') {
84
- options.page = conduit.param('page');
62
+ if (typeof page != 'number') {
63
+ page = conduit.param('page');
85
64
  }
86
65
 
87
- if (options.page < 0 || !options.page) {
88
- options.page = 1;
66
+ if (page < 0 || !page) {
67
+ page = 1;
89
68
  }
90
69
 
91
- options.offset = (options.page-1) * options.pageSize;
92
-
93
- sort = conduit.param('sort');
70
+ let sort = conduit.param('sort');
94
71
 
95
72
  if (sort) {
96
73
  // Always override the sort
97
- options.sort = {};
74
+ let new_sort = {};
98
75
 
99
76
  order = conduit.param('order');
100
77
 
101
78
  if (typeof order == 'string' && order.toLowerCase() == 'desc') {
102
- options.sort[sort] = -1;
79
+ new_sort[sort] = -1;
103
80
  } else {
104
- options.sort[sort] = 1;
81
+ new_sort[sort] = 1;
105
82
  }
106
- }
107
- }
108
-
109
- options.limit = options.pageSize;
110
83
 
111
- if (conduit.param('filter_field') && conduit.param('filter_value')) {
112
- conditions = {};
113
- conditions[conduit.param('filter_field')] = RegExp.interpret('/.*' + conduit.param('filter_value') + '.*/i');
114
- options.conditions = conditions;
115
- }
116
-
117
- filter = conduit.param('filter');
118
-
119
- if (filter) {
120
- if (!conditions) {
121
- conditions = {};
84
+ criteria.sort(new_sort);
122
85
  }
123
86
 
124
- options.conditions = conditions;
125
-
126
- for (name in filter) {
127
- if (filter[name] !== '') {
128
- conditions[name] = RegExp.interpret('/.*' + filter[name] + '.*/i');
129
- }
87
+ if (page) {
88
+ criteria.page(page, page_size);
130
89
  }
131
90
  }
132
91
 
133
92
  if (last_id) {
134
- if (!options.conditions) {
135
- options.conditions = {};
136
- }
137
-
138
- if (!options.conditions.$and) {
139
- options.conditions.$and = [];
140
- }
141
-
142
- let entry = {};
143
-
144
- if (options.skipless === true) {
145
- entry._id = {$gt: alchemy.castObjectId(last_id)};
93
+ if (skipless === true) {
94
+ criteria.where('_id').gt(last_id);
146
95
  } else {
147
- entry[options.skipless] = {$gt: last_id};
96
+ criteria.where(skipless).gt(last_id);
148
97
  }
149
-
150
- options.conditions.$and.push(entry);
151
98
  }
152
99
 
153
- options.available = true;
100
+ criteria.setOption('available', true);
154
101
 
155
- pledge = model.find('all', options, function findAllPaginate(err, result) {
102
+ let pledge = model.find('all', criteria, function findAllPaginate(err, result) {
156
103
 
157
104
  if (err) {
158
105
  return;
@@ -166,21 +113,19 @@ Paginate.setMethod(function find(model, options, callback) {
166
113
  }
167
114
 
168
115
  let entry = {
169
- page : options.page,
170
- size : options.pageSize,
116
+ page : page,
117
+ size : page_size,
171
118
  items : result.available,
172
- pages : Math.ceil(result.available/options.pageSize),
173
- skipless : options.skipless
119
+ pages : Math.ceil(result.available/page_size),
120
+ skipless : skipless
174
121
  };
175
122
 
176
- if (options.skipless && result.length) {
123
+ if (skipless && result.length) {
177
124
  entry.last_id = result.last()._id;
178
125
  }
179
126
 
180
- PageInfo[options.name] = entry;
127
+ PageInfo[name] = entry;
181
128
  });
182
129
 
183
- pledge.handleCallback(callback);
184
-
185
130
  return pledge;
186
131
  });
@@ -34,7 +34,7 @@ var Conduit = Function.inherits('Alchemy.Client.Base', 'Alchemy.Client.Conduit',
34
34
  *
35
35
  * @author Jelle De Loecker <jelle@develry.be>
36
36
  * @since 1.1.0
37
- * @version 1.1.0
37
+ * @version 1.2.2
38
38
  *
39
39
  * @param {RURL} url
40
40
  * @param {Object} options
@@ -121,17 +121,19 @@ Conduit.setStatic(function handleUrlLocal(url, options) {
121
121
  conduit = new Conduit(url, options);
122
122
  }
123
123
 
124
- for (let key in options) {
125
- let info = Blast.Classes.Develry.Request.getMethodInfo(key);
124
+ if (conduit) {
125
+ for (let key in options) {
126
+ let info = Blast.Classes.Develry.Request.getMethodInfo(key);
126
127
 
127
- if (info && info.method != 'GET') {
128
- conduit.method = info.method.toLowerCase();
129
- break;
128
+ if (info && info.method != 'GET') {
129
+ conduit.method = info.method.toLowerCase();
130
+ break;
131
+ }
130
132
  }
131
- }
132
133
 
133
- if (!conduit.method) {
134
- conduit.method = 'get';
134
+ if (!conduit.method) {
135
+ conduit.method = 'get';
136
+ }
135
137
  }
136
138
 
137
139
  Function.series(tasks, function done(err) {
@@ -590,7 +590,7 @@ NoSQL.setStatic(function areComparable(a, b) {
590
590
  *
591
591
  * @author Jelle De Loecker <jelle@develry.be>
592
592
  * @since 1.1.0
593
- * @version 1.1.2
593
+ * @version 1.2.2
594
594
  *
595
595
  * @param {Criteria} criteria
596
596
  * @param {Group} group
@@ -798,6 +798,10 @@ NoSQL.setMethod(function compileCriteria(criteria, group) {
798
798
  {$exists: exists}
799
799
  ];
800
800
 
801
+ if (!entry.field) {
802
+ throw new Error('Could not find field for path "' + entry.target_path + '" in model ' + entry.model.name);
803
+ }
804
+
801
805
  if (entry.field.is_array) {
802
806
  $or.push({[comparator]: []});
803
807
  } else if (entry.field instanceof Classes.Alchemy.Field.String) {
@@ -7,9 +7,7 @@
7
7
  * @since 0.2.0
8
8
  * @version 1.1.0
9
9
  */
10
- var StringField = Function.inherits('Alchemy.Field', function String(schema, name, options) {
11
- String.super.call(this, schema, name, options);
12
- });
10
+ var StringField = Function.inherits('Alchemy.Field', 'String');
13
11
 
14
12
  /**
15
13
  * Set the datatype name
@@ -7,23 +7,4 @@
7
7
  * @since 0.2.0
8
8
  * @version 1.1.0
9
9
  */
10
- var BelongsTo = Function.inherits('Alchemy.Field.ObjectId', function BelongsTo(schema, name, options) {
11
- BelongsTo.super.call(this, schema, name, options);
12
-
13
- // @todo: set index stuff
14
- });
15
-
16
- /**
17
- * Load remote data for some fields
18
- *
19
- * @author Jelle De Loecker <jelle@elevenways.be>
20
- * @since 0.2.0
21
- * @version 0.2.0
22
- *
23
- * @param {Object} config
24
- */
25
- BelongsTo.setMethod(async function loadData(config) {
26
-
27
-
28
-
29
- });
10
+ const BelongsTo = Function.inherits('Alchemy.Field.ObjectId', 'BelongsTo');
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The DataProvider class
3
+ *
4
+ * @author Jelle De Loecker <jelle@elevenways.be>
5
+ * @since 1.2.2
6
+ * @version 1.2.2
7
+ */
8
+ const DataProvider = Function.inherits('Alchemy.Base', 'Alchemy.DataProvider', function DataProvider(config) {
9
+ this.config = config || {};
10
+ });
11
+
12
+
13
+ /**
14
+ * Undry
15
+ *
16
+ * @author Jelle De Loecker <jelle@elevenways.be>
17
+ * @since 1.2.2
18
+ * @version 1.2.2
19
+ *
20
+ * @param {Object} obj
21
+ * @param {Boolean|String} cloned
22
+ *
23
+ * @return {DataProvider}
24
+ */
25
+ DataProvider.setStatic(function unDry(obj) {
26
+ let result = new this(obj.config);
27
+ return result;
28
+ });
29
+
30
+ /**
31
+ * Configure a new config
32
+ *
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
34
+ * @since 1.2.2
35
+ * @version 1.2.2
36
+ */
37
+ DataProvider.setStatic(function addConfig(name, default_value) {
38
+ this.setProperty(name, function getValue() {
39
+
40
+ if (this.config[name] != null) {
41
+ return this.config[name];
42
+ }
43
+
44
+ return default_value;
45
+ }, function setValue(value) {
46
+ return this.config[name] = value;
47
+ });
48
+ });
49
+
50
+ /**
51
+ * The wanted page size
52
+ *
53
+ * @author Jelle De Loecker <jelle@elevenways.be>
54
+ * @since 1.2.2
55
+ * @version 1.2.2
56
+ */
57
+ DataProvider.addConfig('page_size');
58
+
59
+ /**
60
+ * Get all the data
61
+ *
62
+ * @author Jelle De Loecker <jelle@elevenways.be>
63
+ * @since 1.2.2
64
+ * @version 1.2.2
65
+ */
66
+ DataProvider.setAbstractMethod('getAll');
67
+
68
+ /**
69
+ * Get the data for the given page (pages are 1-index based)
70
+ *
71
+ * @author Jelle De Loecker <jelle@elevenways.be>
72
+ * @since 1.2.2
73
+ * @version 1.2.2
74
+ */
75
+ DataProvider.setAbstractMethod('getPage');
76
+
77
+ /**
78
+ * Return an object for json-drying this document
79
+ *
80
+ * @author Jelle De Loecker <jelle@elevenways.be>
81
+ * @since 1.2.2
82
+ * @version 1.2.2
83
+ *
84
+ * @return {Object}
85
+ */
86
+ DataProvider.setMethod(function toDry() {
87
+ return {
88
+ value : {
89
+ config : this.config,
90
+ }
91
+ };
92
+ });
@@ -29,6 +29,9 @@ const FieldConfig = Fn.inherits('Alchemy.Base', 'Alchemy.Criteria', function Fie
29
29
  // The association this belongs to
30
30
  this.association = null;
31
31
 
32
+ // The main model this field is in
33
+ this.model = null;
34
+
32
35
  this.options = options || {};
33
36
 
34
37
  if (path) {
@@ -72,6 +75,94 @@ FieldConfig.setProperty(function title() {
72
75
  return title;
73
76
  });
74
77
 
78
+ /**
79
+ * Set the main model context this field is used for
80
+ * (Actual field can be in an association of this model)
81
+ *
82
+ * @author Jelle De Loecker <jelle@elevenways.be>
83
+ * @since 1.2.2
84
+ * @version 1.2.2
85
+ *
86
+ * @param {String|Model} model
87
+ */
88
+ FieldConfig.setMethod(function setContextModel(model) {
89
+
90
+ if (typeof model == 'string') {
91
+ this.model = model;
92
+ this._model = alchemy.getModel(model);
93
+ } else {
94
+ this._model = model;
95
+ this.model = model.model_name;
96
+ }
97
+ });
98
+
99
+ /**
100
+ * Get the context model this field is used for
101
+ *
102
+ * @author Jelle De Loecker <jelle@elevenways.be>
103
+ * @since 1.2.2
104
+ * @version 1.2.2
105
+ */
106
+ FieldConfig.setMethod(function getContextModel() {
107
+
108
+ if (this._model) {
109
+ return this._model;
110
+ }
111
+
112
+ if (!this.model) {
113
+ return;
114
+ }
115
+
116
+ this._model = alchemy.getModel(this.model);
117
+ return this._model;
118
+ });
119
+
120
+ /**
121
+ * Get the actual model this field is in
122
+ *
123
+ * @author Jelle De Loecker <jelle@elevenways.be>
124
+ * @since 1.2.2
125
+ * @version 1.2.2
126
+ */
127
+ FieldConfig.setMethod(function getModel() {
128
+
129
+ let model = this.getContextModel();
130
+
131
+ if (!model) {
132
+ return;
133
+ }
134
+
135
+ if (this.association) {
136
+ let config = model.getAssociation(this.association);
137
+
138
+ if (config) {
139
+ model = alchemy.getModel(config.modelName);
140
+ } else {
141
+ model = null;
142
+ }
143
+ }
144
+
145
+ return model;
146
+ });
147
+
148
+ /**
149
+ * Get the field definition
150
+ *
151
+ * @author Jelle De Loecker <jelle@elevenways.be>
152
+ * @since 1.2.2
153
+ * @version 1.2.2
154
+ */
155
+ FieldConfig.setMethod(function getFieldDefinition() {
156
+
157
+ let model = this.getModel();
158
+
159
+ if (!model) {
160
+ return;
161
+ }
162
+
163
+ return model.getField(this.local_path);
164
+ });
165
+
75
166
  /**
76
167
  * Return an object for json-drying this list
77
168
  *
@@ -143,6 +143,28 @@ FieldSet.setMethod(function toJSON() {
143
143
  return result;
144
144
  });
145
145
 
146
+ /**
147
+ * Get an instance of the model
148
+ *
149
+ * @author Jelle De Loecker <jelle@elevenways.be>
150
+ * @since 1.2.2
151
+ * @version 1.2.2
152
+ *
153
+ * @return {Model}
154
+ */
155
+ FieldSet.setMethod(function getModel() {
156
+
157
+ if (!this.model) {
158
+ return;
159
+ }
160
+
161
+ if (!this._model) {
162
+ this._model = alchemy.getModel(this.model);
163
+ }
164
+
165
+ return this._model;
166
+ });
167
+
146
168
  /**
147
169
  * Iterator method
148
170
  *
@@ -165,7 +187,7 @@ FieldSet.setMethod(Symbol.iterator, function* iterate() {
165
187
  *
166
188
  * @author Jelle De Loecker <jelle@elevenways.be>
167
189
  * @since 1.1.3
168
- * @version 1.1.3
190
+ * @version 1.2.2
169
191
  *
170
192
  * @param {String} name The name of the field to add
171
193
  * @param {Object} options
@@ -176,6 +198,10 @@ FieldSet.setMethod(function addField(name, options) {
176
198
 
177
199
  let config = new Classes.Alchemy.Criteria.FieldConfig(name, options);
178
200
 
201
+ if (this.model && !config.getContextModel()) {
202
+ config.setContextModel(this.model);
203
+ }
204
+
179
205
  this.fields.set(name, config);
180
206
 
181
207
  return config;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The Remote DataProvider class
3
+ *
4
+ * @author Jelle De Loecker <jelle@elevenways.be>
5
+ * @since 1.2.2
6
+ * @version 1.2.2
7
+ */
8
+ const RemoteDataProvider = Function.inherits('Alchemy.DataProvider', 'Remote');
9
+
10
+ /**
11
+ * The url to load
12
+ *
13
+ * @author Jelle De Loecker <jelle@elevenways.be>
14
+ * @since 1.2.2
15
+ * @version 1.2.2
16
+ */
17
+ RemoteDataProvider.addConfig('source');
18
+
19
+ /**
20
+ * Get all the data
21
+ *
22
+ * @author Jelle De Loecker <jelle@elevenways.be>
23
+ * @since 1.2.2
24
+ * @version 1.2.2
25
+ */
26
+ RemoteDataProvider.setMethod(async function getAll() {
27
+
28
+ if (!this.source) {
29
+ return [];
30
+ }
31
+
32
+ let result = await Blast.fetch(this.source);
33
+
34
+ return result;
35
+ });
package/lib/bootstrap.js CHANGED
@@ -3,6 +3,22 @@
3
3
  var libpath = require('path'),
4
4
  starting;
5
5
 
6
+ /**
7
+ * Calling dynamic `import()` from certain places in the codebase actually
8
+ * causes segfaults. This is a workaround for that.
9
+ *
10
+ * @author Jelle De Loecker <jelle@elevenways.be>
11
+ * @since 1.2.2
12
+ * @version 1.2.2
13
+ *
14
+ * @param {String} path
15
+ *
16
+ * @return {Promise}
17
+ */
18
+ global.doImport = function doImport(path) {
19
+ return import(path);
20
+ };
21
+
6
22
  /**
7
23
  * Extend prototypes
8
24
  */
@@ -287,7 +287,7 @@ Schema.setMethod(function getAssociationArguments(locality, alias, modelName, op
287
287
  *
288
288
  * @author Jelle De Loecker <jelle@develry.be>
289
289
  * @since 0.2.0
290
- * @version 1.1.0
290
+ * @version 1.2.2
291
291
  *
292
292
  * @param {String} alias
293
293
  * @param {String} modelname
@@ -369,7 +369,14 @@ Schema.setMethod(function addAssociation(type, alias, modelName, options) {
369
369
  if (locality == 'internal') {
370
370
 
371
371
  if (!this.getField(options.localKey)) {
372
- this.addField(options.localKey, type, args);
372
+ let field_options = Object.assign({}, args);
373
+
374
+ if (options && options.field_options) {
375
+ Object.assign(field_options, options.field_options);
376
+ field_options.field_options = undefined;
377
+ }
378
+
379
+ this.addField(options.localKey, type, field_options);
373
380
 
374
381
  if (constructor) {
375
382
  doc_class.setFieldGetter(options.localKey);
package/lib/core/base.js CHANGED
@@ -416,19 +416,28 @@ Base.setMethod(function getClassPathAfter(after) {
416
416
  /**
417
417
  * Call a method if it exists or do the callback
418
418
  *
419
- * @author Jelle De Loecker <jelle@develry.be>
419
+ * @author Jelle De Loecker <jelle@elevenways.be>
420
420
  * @since 1.0.0
421
- * @version 1.0.0
421
+ * @version 1.2.2
422
422
  */
423
423
  Base.setMethod(function callOrNext(name, args, next) {
424
424
 
425
+ if (arguments.length == 2 && typeof args == 'function') {
426
+ next = args;
427
+ args = [];
428
+ }
429
+
425
430
  if (typeof this[name] == 'function') {
426
431
 
427
432
  if (next) {
428
433
  args.push(next);
429
434
  }
430
435
 
431
- this[name].apply(this, args);
436
+ try {
437
+ this[name].apply(this, args);
438
+ } catch (err) {
439
+ next(err);
440
+ }
432
441
  } else if (next) {
433
442
  next();
434
443
 
@@ -751,7 +751,6 @@ Alchemy.setMethod(function use(module_name, register_as, options) {
751
751
  return module;
752
752
  });
753
753
 
754
-
755
754
  /**
756
755
  * Look for a module by traversing the filesystem
757
756
  *
@@ -878,7 +877,7 @@ Alchemy.setMethod(function searchModule(startPath, moduleName, recurse) {
878
877
  *
879
878
  * @author Jelle De Loecker <jelle@develry.be>
880
879
  * @since 0.0.1
881
- * @version 1.1.0
880
+ * @version 1.2.2
882
881
  *
883
882
  * @param {String} moduleName
884
883
  * @param {Object} options
@@ -949,20 +948,26 @@ Alchemy.setMethod(function findModule(moduleName, options) {
949
948
  // If the module_path was found, actually require the module
950
949
  if (module_path) {
951
950
 
952
- // Modules are required by default
953
- if (options.require) {
954
- module = require(module_path);
955
- }
956
-
957
951
  // Get the package.json file
958
952
  if (~module_path.indexOf(libpath.sep)) {
959
953
  internal = false;
960
954
 
955
+ let last_piece = moduleName.split(libpath.sep).last(),
956
+ package_path;
957
+
961
958
  let module_dir = libpath.dirname(module_path);
962
959
  result.module_dir = module_dir;
963
960
 
961
+ // If the path doesn't end with the module name, look for it
962
+ if (!module_path.endsWith(last_piece)) {
963
+ package_path = module_path.beforeLast(last_piece) + last_piece;
964
+ package_path = libpath.resolve(package_path, 'package.json');
965
+ } else {
966
+ package_path = libpath.resolve(module_dir, 'package.json');
967
+ }
968
+
964
969
  try {
965
- package_json = require(libpath.resolve(module_dir, 'package.json'));
970
+ package_json = require(package_path);
966
971
  } catch (err) {
967
972
  package_json = false;
968
973
  }
@@ -972,6 +977,15 @@ Alchemy.setMethod(function findModule(moduleName, options) {
972
977
  version: process.versions.node
973
978
  };
974
979
  }
980
+
981
+ // Modules are required by default
982
+ if (options.require) {
983
+ if (package_json && package_json.type == 'module' && !(package_json.main && package_json.module)) {
984
+ module = doImport(module_path)
985
+ } else {
986
+ module = require(module_path);
987
+ }
988
+ }
975
989
  }
976
990
 
977
991
  if (!options.require || module) {
@@ -1082,7 +1082,7 @@ Alchemy.setMethod(function downloadFile(url, options, callback) {
1082
1082
  file = fs.createWriteStream(filepath);
1083
1083
 
1084
1084
  if (res.statusCode == 404) {
1085
- err = new Error('Path does not exist');
1085
+ err = new Error('Path "' + url + '" does not exist');
1086
1086
  err.number = 404;
1087
1087
 
1088
1088
  return callback(err);
@@ -813,7 +813,7 @@ Alchemy.setMethod(function startPlugins(names) {
813
813
  *
814
814
  * @author Jelle De Loecker <jelle@develry.be>
815
815
  * @since 0.0.1
816
- * @version 1.1.0
816
+ * @version 1.2.2
817
817
  *
818
818
  * @param {String|Array} names
819
819
  * @param {Boolean} attempt_require
@@ -844,8 +844,13 @@ Alchemy.setMethod(function requirePlugin(names, attempt_require) {
844
844
  temp = alchemy.usePlugin(name);
845
845
 
846
846
  if (temp) {
847
- // Also start the plugin!
848
- alchemy.startPlugins(name);
847
+ let plugin_stage = alchemy.sputnik.get('plugins');
848
+
849
+ if (!plugin_stage || plugin_stage.started) {
850
+ // If the plugin stage has already started,
851
+ // manually start this plugin now
852
+ alchemy.startPlugins(name);
853
+ }
849
854
  continue;
850
855
  }
851
856
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alchemymvc",
3
3
  "description": "MVC framework for Node.js",
4
- "version": "1.2.1",
4
+ "version": "1.2.2",
5
5
  "author": "Jelle De Loecker <jelle@elevenways.be>",
6
6
  "keywords": [
7
7
  "alchemy",
@@ -22,7 +22,7 @@
22
22
  "chokidar" : "~3.5.3",
23
23
  "formidable" : "~1.2.2",
24
24
  "graceful-fs" : "~4.2.9",
25
- "hawkejs" : "~2.2.3",
25
+ "hawkejs" : "~2.2.8",
26
26
  "jsondiffpatch" : "~0.4.1",
27
27
  "mime" : "~3.0.0",
28
28
  "minimist" : "~1.2.5",