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.
- package/lib/app/helper_component/paginate_component.js +43 -98
- package/lib/app/helper_controller/conduit.js +11 -9
- package/lib/app/helper_datasource/00-nosql_datasource.js +5 -1
- package/lib/app/helper_field/05-string_field.js +1 -3
- package/lib/app/helper_field/belongsto_field.js +1 -20
- package/lib/app/helper_model/data_provider.js +92 -0
- package/lib/app/helper_model/field_config.js +91 -0
- package/lib/app/helper_model/field_set.js +27 -1
- package/lib/app/helper_model/remote_data_provider.js +35 -0
- package/lib/bootstrap.js +16 -0
- package/lib/class/schema.js +9 -2
- package/lib/core/base.js +12 -3
- package/lib/init/alchemy.js +22 -8
- package/lib/init/functions.js +1 -1
- package/lib/init/load_functions.js +8 -3
- package/package.json +2 -2
|
@@ -8,151 +8,98 @@
|
|
|
8
8
|
* @since 0.0.1
|
|
9
9
|
* @version 1.0.0
|
|
10
10
|
*/
|
|
11
|
-
|
|
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@
|
|
16
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
19
17
|
* @since 0.0.1
|
|
20
|
-
* @version 1.
|
|
18
|
+
* @version 1.2.2
|
|
21
19
|
*
|
|
22
20
|
* @param {Model} model
|
|
23
|
-
* @param {
|
|
24
|
-
* @param {Function} callback
|
|
21
|
+
* @param {Criteria} criteria
|
|
25
22
|
*
|
|
26
23
|
* @return {Pledge}
|
|
27
24
|
*/
|
|
28
|
-
Paginate.setMethod(function find(model,
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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 (!
|
|
63
|
-
|
|
40
|
+
if (!name) {
|
|
41
|
+
name = model.name;
|
|
42
|
+
criteria.setOption('name', name);
|
|
64
43
|
}
|
|
65
44
|
|
|
66
|
-
if (
|
|
67
|
-
|
|
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 (
|
|
51
|
+
if (skipless === true) {
|
|
72
52
|
sort = {_id: 1};
|
|
73
53
|
} else {
|
|
74
54
|
sort = {};
|
|
75
|
-
sort[
|
|
55
|
+
sort[skipless] = 1;
|
|
76
56
|
}
|
|
77
57
|
|
|
78
|
-
|
|
79
|
-
|
|
58
|
+
criteria.sort(sort);
|
|
80
59
|
} else {
|
|
81
60
|
|
|
82
61
|
// If no page has been given
|
|
83
|
-
if (typeof
|
|
84
|
-
|
|
62
|
+
if (typeof page != 'number') {
|
|
63
|
+
page = conduit.param('page');
|
|
85
64
|
}
|
|
86
65
|
|
|
87
|
-
if (
|
|
88
|
-
|
|
66
|
+
if (page < 0 || !page) {
|
|
67
|
+
page = 1;
|
|
89
68
|
}
|
|
90
69
|
|
|
91
|
-
|
|
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
|
-
|
|
74
|
+
let new_sort = {};
|
|
98
75
|
|
|
99
76
|
order = conduit.param('order');
|
|
100
77
|
|
|
101
78
|
if (typeof order == 'string' && order.toLowerCase() == 'desc') {
|
|
102
|
-
|
|
79
|
+
new_sort[sort] = -1;
|
|
103
80
|
} else {
|
|
104
|
-
|
|
81
|
+
new_sort[sort] = 1;
|
|
105
82
|
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
options.limit = options.pageSize;
|
|
110
83
|
|
|
111
|
-
|
|
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
|
-
|
|
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 (
|
|
135
|
-
|
|
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
|
-
|
|
96
|
+
criteria.where(skipless).gt(last_id);
|
|
148
97
|
}
|
|
149
|
-
|
|
150
|
-
options.conditions.$and.push(entry);
|
|
151
98
|
}
|
|
152
99
|
|
|
153
|
-
|
|
100
|
+
criteria.setOption('available', true);
|
|
154
101
|
|
|
155
|
-
pledge = model.find('all',
|
|
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 :
|
|
170
|
-
size :
|
|
116
|
+
page : page,
|
|
117
|
+
size : page_size,
|
|
171
118
|
items : result.available,
|
|
172
|
-
pages : Math.ceil(result.available/
|
|
173
|
-
skipless :
|
|
119
|
+
pages : Math.ceil(result.available/page_size),
|
|
120
|
+
skipless : skipless
|
|
174
121
|
};
|
|
175
122
|
|
|
176
|
-
if (
|
|
123
|
+
if (skipless && result.length) {
|
|
177
124
|
entry.last_id = result.last()._id;
|
|
178
125
|
}
|
|
179
126
|
|
|
180
|
-
PageInfo[
|
|
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.
|
|
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
|
-
|
|
125
|
-
let
|
|
124
|
+
if (conduit) {
|
|
125
|
+
for (let key in options) {
|
|
126
|
+
let info = Blast.Classes.Develry.Request.getMethodInfo(key);
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
if (info && info.method != 'GET') {
|
|
129
|
+
conduit.method = info.method.toLowerCase();
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
130
132
|
}
|
|
131
|
-
}
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
|
|
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.
|
|
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',
|
|
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
|
-
|
|
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.
|
|
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
|
*/
|
package/lib/class/schema.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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@
|
|
419
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
420
420
|
* @since 1.0.0
|
|
421
|
-
* @version 1.
|
|
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
|
-
|
|
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
|
|
package/lib/init/alchemy.js
CHANGED
|
@@ -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.
|
|
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(
|
|
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) {
|
package/lib/init/functions.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
848
|
-
|
|
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.
|
|
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.
|
|
25
|
+
"hawkejs" : "~2.2.8",
|
|
26
26
|
"jsondiffpatch" : "~0.4.1",
|
|
27
27
|
"mime" : "~3.0.0",
|
|
28
28
|
"minimist" : "~1.2.5",
|