alchemymvc 1.1.10 → 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/datasource/mongo_datasource.js +75 -10
- package/lib/app/helper/backed_map.js +257 -0
- package/lib/app/helper/enum_values.js +125 -0
- package/lib/app/helper/router_helper.js +7 -1
- 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 +78 -20
- 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_field/enum_field.js +9 -36
- package/lib/app/helper_field/schema_field.js +11 -21
- package/lib/app/helper_model/criteria.js +73 -18
- package/lib/app/helper_model/data_provider.js +92 -0
- package/lib/app/helper_model/field_config.js +115 -5
- package/lib/app/helper_model/field_set.js +27 -1
- package/lib/app/helper_model/model.js +45 -7
- package/lib/app/helper_model/remote_data_provider.js +35 -0
- package/lib/app/model/alchemy_migration_model.js +33 -0
- package/lib/bootstrap.js +25 -0
- package/lib/class/datasource.js +2 -2
- package/lib/class/element.js +6 -1
- package/lib/class/field.js +7 -1
- package/lib/class/migration.js +138 -0
- package/lib/class/model.js +11 -19
- package/lib/class/schema.js +23 -14
- package/lib/core/base.js +12 -3
- package/lib/core/client_alchemy.js +14 -0
- package/lib/init/alchemy.js +1807 -1779
- package/lib/init/functions.js +5 -2
- package/lib/init/load_functions.js +16 -5
- package/package.json +12 -12
- package/CHANGELOG.md +0 -462
|
@@ -388,15 +388,26 @@ Criteria.setMethod(function clone() {
|
|
|
388
388
|
*
|
|
389
389
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
390
390
|
* @since 1.1.0
|
|
391
|
-
* @version 1.
|
|
391
|
+
* @version 1.2.0
|
|
392
392
|
*
|
|
393
|
-
* @return {
|
|
393
|
+
* @return {String[]}
|
|
394
394
|
*/
|
|
395
395
|
Criteria.setMethod(function getFieldsToSelect() {
|
|
396
396
|
|
|
397
|
-
|
|
397
|
+
let result;
|
|
398
398
|
|
|
399
|
-
|
|
399
|
+
if (this.options.select.fields && this.options.select.fields.length) {
|
|
400
|
+
result = this.options.select.fields.slice(0);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Fields can sometimes be required for a query (like in a join) but they
|
|
404
|
+
// won't be selected if other fields are explicitly set.
|
|
405
|
+
// So in that case: add these special fields to the projection
|
|
406
|
+
if (result && this.options.select.query_fields && this.options.select.query_fields) {
|
|
407
|
+
result.push(...this.options.select.query_fields);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return result || [];
|
|
400
411
|
});
|
|
401
412
|
|
|
402
413
|
/**
|
|
@@ -663,7 +674,7 @@ Criteria.setMethod(function page(page, page_size) {
|
|
|
663
674
|
*
|
|
664
675
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
665
676
|
* @since 1.1.0
|
|
666
|
-
* @version 1.
|
|
677
|
+
* @version 1.2.0
|
|
667
678
|
*
|
|
668
679
|
* @param {String|Array} field
|
|
669
680
|
*
|
|
@@ -681,12 +692,6 @@ Criteria.setMethod(function select(field) {
|
|
|
681
692
|
}
|
|
682
693
|
} else {
|
|
683
694
|
|
|
684
|
-
if (typeof field == 'object') {
|
|
685
|
-
if (field instanceof Classes.Alchemy.Criteria.FieldConfig || field.name) {
|
|
686
|
-
field = field.name;
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
|
|
690
695
|
if (this._select) {
|
|
691
696
|
context = this._select.parse(field);
|
|
692
697
|
} else {
|
|
@@ -1383,7 +1388,7 @@ Select.setMethod(Blast.checksumSymbol, function toChecksum() {
|
|
|
1383
1388
|
*
|
|
1384
1389
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1385
1390
|
* @since 1.1.0
|
|
1386
|
-
* @version 1.
|
|
1391
|
+
* @version 1.2.0
|
|
1387
1392
|
*
|
|
1388
1393
|
* @param {String} name
|
|
1389
1394
|
*
|
|
@@ -1419,9 +1424,39 @@ Select.setMethod(function addAssociation(name) {
|
|
|
1419
1424
|
this.associations[name].association_name = name;
|
|
1420
1425
|
}
|
|
1421
1426
|
|
|
1427
|
+
// Get the association data
|
|
1428
|
+
try {
|
|
1429
|
+
let info = this.criteria.model.getAssociation(name);
|
|
1430
|
+
|
|
1431
|
+
if (info) {
|
|
1432
|
+
// Make sure the localkey is added to the resultset
|
|
1433
|
+
this.requireFieldForQuery(info.options.localKey);
|
|
1434
|
+
}
|
|
1435
|
+
} catch (err) {
|
|
1436
|
+
console.warn('Failed to find "' + name + '" association for ' + this.criteria.model.modelName);
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1422
1439
|
return this.associations[name];
|
|
1423
1440
|
});
|
|
1424
1441
|
|
|
1442
|
+
/**
|
|
1443
|
+
* Require a field for query purposes
|
|
1444
|
+
*
|
|
1445
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
1446
|
+
* @since 1.2.0
|
|
1447
|
+
* @version 1.2.0
|
|
1448
|
+
*
|
|
1449
|
+
* @param {String} path
|
|
1450
|
+
*/
|
|
1451
|
+
Select.setMethod(function requireFieldForQuery(path) {
|
|
1452
|
+
|
|
1453
|
+
if (!this.query_fields) {
|
|
1454
|
+
this.query_fields = [];
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
this.query_fields.push(path);
|
|
1458
|
+
});
|
|
1459
|
+
|
|
1425
1460
|
/**
|
|
1426
1461
|
* Add a field
|
|
1427
1462
|
*
|
|
@@ -1445,17 +1480,33 @@ Select.setMethod(function addField(path) {
|
|
|
1445
1480
|
*
|
|
1446
1481
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1447
1482
|
* @since 1.1.0
|
|
1448
|
-
* @version 1.
|
|
1483
|
+
* @version 1.2.0
|
|
1449
1484
|
*
|
|
1450
|
-
* @param {String} path
|
|
1485
|
+
* @param {String|Object} path
|
|
1451
1486
|
*
|
|
1452
1487
|
* @return {Criteria|Null} A criteria object if the context has changed
|
|
1453
1488
|
*/
|
|
1454
1489
|
Select.setMethod(function parse(path) {
|
|
1455
1490
|
|
|
1456
|
-
|
|
1491
|
+
let context,
|
|
1457
1492
|
select = this,
|
|
1458
|
-
parsed
|
|
1493
|
+
parsed;
|
|
1494
|
+
|
|
1495
|
+
if (typeof path == 'object' && path && path.name) {
|
|
1496
|
+
|
|
1497
|
+
if (path.path) {
|
|
1498
|
+
path = path.path;
|
|
1499
|
+
} else {
|
|
1500
|
+
let obj = path;
|
|
1501
|
+
path = obj.name;
|
|
1502
|
+
|
|
1503
|
+
if (obj.association) {
|
|
1504
|
+
path = obj.association + '.' + path;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
parsed = Criteria.parsePath(path, this.criteria);
|
|
1459
1510
|
|
|
1460
1511
|
// Associations were found,
|
|
1461
1512
|
// like "Comment._id" or "Comment.User"
|
|
@@ -1470,7 +1521,7 @@ Select.setMethod(function parse(path) {
|
|
|
1470
1521
|
continue;
|
|
1471
1522
|
}
|
|
1472
1523
|
|
|
1473
|
-
select =
|
|
1524
|
+
select = select.addAssociation(name);
|
|
1474
1525
|
}
|
|
1475
1526
|
}
|
|
1476
1527
|
|
|
@@ -1489,7 +1540,7 @@ Select.setMethod(function parse(path) {
|
|
|
1489
1540
|
*
|
|
1490
1541
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1491
1542
|
* @since 1.1.0
|
|
1492
|
-
* @version 1.
|
|
1543
|
+
* @version 1.2.0
|
|
1493
1544
|
*
|
|
1494
1545
|
* @param {Criteria} criteria
|
|
1495
1546
|
*
|
|
@@ -1507,6 +1558,10 @@ Select.setMethod(function cloneForCriteria(criteria) {
|
|
|
1507
1558
|
clone.fields = this.fields.slice(0);
|
|
1508
1559
|
}
|
|
1509
1560
|
|
|
1561
|
+
if (this.query_fields && this.query_fields.length) {
|
|
1562
|
+
clone.query_fields = this.query_fields.slice(0);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1510
1565
|
if (this.associations) {
|
|
1511
1566
|
let key;
|
|
1512
1567
|
|
|
@@ -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
|
+
});
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
9
9
|
* @since 1.1.3
|
|
10
|
-
* @version 1.
|
|
10
|
+
* @version 1.2.0
|
|
11
11
|
*
|
|
12
12
|
* @param {string} path
|
|
13
13
|
* @param {Object} options
|
|
@@ -20,12 +20,18 @@ const FieldConfig = Fn.inherits('Alchemy.Base', 'Alchemy.Criteria', function Fie
|
|
|
20
20
|
// The full path to the value
|
|
21
21
|
this.path = null;
|
|
22
22
|
|
|
23
|
+
// The local path to the value (subfields)
|
|
24
|
+
this.local_path = null;
|
|
25
|
+
|
|
23
26
|
// The pieces of the path
|
|
24
27
|
this.pieces = null;
|
|
25
28
|
|
|
26
29
|
// The association this belongs to
|
|
27
30
|
this.association = null;
|
|
28
31
|
|
|
32
|
+
// The main model this field is in
|
|
33
|
+
this.model = null;
|
|
34
|
+
|
|
29
35
|
this.options = options || {};
|
|
30
36
|
|
|
31
37
|
if (path) {
|
|
@@ -69,6 +75,94 @@ FieldConfig.setProperty(function title() {
|
|
|
69
75
|
return title;
|
|
70
76
|
});
|
|
71
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
|
+
|
|
72
166
|
/**
|
|
73
167
|
* Return an object for json-drying this list
|
|
74
168
|
*
|
|
@@ -89,7 +183,7 @@ FieldConfig.setMethod(function toDry() {
|
|
|
89
183
|
*
|
|
90
184
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
91
185
|
* @since 1.1.3
|
|
92
|
-
* @version 1.
|
|
186
|
+
* @version 1.2.0
|
|
93
187
|
*
|
|
94
188
|
* @return {Object}
|
|
95
189
|
*/
|
|
@@ -97,6 +191,7 @@ FieldConfig.setMethod(function toJSON() {
|
|
|
97
191
|
return {
|
|
98
192
|
name : this.name,
|
|
99
193
|
path : this.path,
|
|
194
|
+
local_path : this.local_path,
|
|
100
195
|
association : this.association,
|
|
101
196
|
options : this.options,
|
|
102
197
|
};
|
|
@@ -107,7 +202,7 @@ FieldConfig.setMethod(function toJSON() {
|
|
|
107
202
|
*
|
|
108
203
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
109
204
|
* @since 1.1.3
|
|
110
|
-
* @version 1.
|
|
205
|
+
* @version 1.2.0
|
|
111
206
|
*
|
|
112
207
|
* @param {string} path
|
|
113
208
|
*/
|
|
@@ -120,6 +215,7 @@ FieldConfig.setMethod(function parsePath(path) {
|
|
|
120
215
|
} else if (path.indexOf('.') == -1) {
|
|
121
216
|
this.name = path;
|
|
122
217
|
this.path = path;
|
|
218
|
+
this.local_path = path;
|
|
123
219
|
this.pieces = [path];
|
|
124
220
|
return;
|
|
125
221
|
} else {
|
|
@@ -132,13 +228,27 @@ FieldConfig.setMethod(function parsePath(path) {
|
|
|
132
228
|
|
|
133
229
|
this.path = path;
|
|
134
230
|
this.pieces = pieces;
|
|
231
|
+
this.local_path = '';
|
|
135
232
|
|
|
136
233
|
for (i = 0; i < pieces.length; i++) {
|
|
137
234
|
piece = pieces[i];
|
|
138
235
|
|
|
139
|
-
if (
|
|
140
|
-
|
|
236
|
+
if (piece[0].isUpperCase()) {
|
|
237
|
+
|
|
238
|
+
if (this.association) {
|
|
239
|
+
this.association += '.';
|
|
240
|
+
} else {
|
|
241
|
+
this.association = '';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this.association += piece;
|
|
141
245
|
continue;
|
|
246
|
+
} else {
|
|
247
|
+
if (this.local_path) {
|
|
248
|
+
this.local_path += '.';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
this.local_path += piece;
|
|
142
252
|
}
|
|
143
253
|
}
|
|
144
254
|
|
|
@@ -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;
|
|
@@ -403,7 +403,7 @@ Model.setMethod(function getFindOptions(options) {
|
|
|
403
403
|
*
|
|
404
404
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
405
405
|
* @since 1.1.0
|
|
406
|
-
* @version 1.
|
|
406
|
+
* @version 1.2.0
|
|
407
407
|
*
|
|
408
408
|
* @param {String} alias
|
|
409
409
|
*
|
|
@@ -415,7 +415,30 @@ Model.setMethod(function getAssociation(alias) {
|
|
|
415
415
|
throw new Error('Unable to find ' + this.constructor.name + ' schema associations');
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
-
let config
|
|
418
|
+
let config;
|
|
419
|
+
|
|
420
|
+
// @TODO: Test nested association getting
|
|
421
|
+
if (alias && alias.indexOf('.') > -1) {
|
|
422
|
+
let pieces = alias.split('.'),
|
|
423
|
+
context = this,
|
|
424
|
+
piece,
|
|
425
|
+
temp;
|
|
426
|
+
|
|
427
|
+
for (piece of pieces) {
|
|
428
|
+
temp = context.getAssociation(piece);
|
|
429
|
+
|
|
430
|
+
if (!temp) {
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
context = this.getModel(temp.modelName);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// The config s the last association gotten
|
|
438
|
+
config = temp;
|
|
439
|
+
} else {
|
|
440
|
+
config = this.schema.associations[alias];
|
|
441
|
+
}
|
|
419
442
|
|
|
420
443
|
if (!config) {
|
|
421
444
|
throw new Error('Unable to find ' + JSON.stringify(alias) + ' association in ' + this.constructor.name + ' model');
|
|
@@ -1401,15 +1424,30 @@ Model.setProperty(function associations() {
|
|
|
1401
1424
|
*
|
|
1402
1425
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1403
1426
|
* @since 1.0.0
|
|
1404
|
-
* @version 1.
|
|
1427
|
+
* @version 1.2.0
|
|
1405
1428
|
*
|
|
1406
|
-
* @param {
|
|
1429
|
+
* @param {string} path The path to the field
|
|
1407
1430
|
*
|
|
1408
1431
|
* @return {Object}
|
|
1409
1432
|
*/
|
|
1410
|
-
Model.setMethod(function getField(
|
|
1411
|
-
|
|
1412
|
-
|
|
1433
|
+
Model.setMethod(function getField(path) {
|
|
1434
|
+
|
|
1435
|
+
if (path.indexOf('.') > -1) {
|
|
1436
|
+
let config = new Classes.Alchemy.Criteria.FieldConfig(path);
|
|
1437
|
+
|
|
1438
|
+
// If part of the path is an association, look for that now
|
|
1439
|
+
if (config.association) {
|
|
1440
|
+
let association = this.getAssociation(config.association);
|
|
1441
|
+
let model = this.getModel(association.modelName);
|
|
1442
|
+
return model.getField(config.local_path);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
// If not, just use the local_path
|
|
1446
|
+
path = config.local_path;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
return this.schema.getField(path);
|
|
1450
|
+
});
|
|
1413
1451
|
|
|
1414
1452
|
// Make this class easily available
|
|
1415
1453
|
Hawkejs.Model = Model;
|
|
@@ -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
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Alchemy Migration Model class
|
|
3
|
+
*
|
|
4
|
+
* @constructor
|
|
5
|
+
*
|
|
6
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
7
|
+
* @since 1.2.0
|
|
8
|
+
* @version 1.2.0
|
|
9
|
+
*/
|
|
10
|
+
const AlchemyMigration = Function.inherits('Alchemy.Model.App', 'AlchemyMigration');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Constitute the class wide schema
|
|
14
|
+
*
|
|
15
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
16
|
+
* @since 1.2.0
|
|
17
|
+
* @version 1.2.0
|
|
18
|
+
*/
|
|
19
|
+
AlchemyMigration.constitute(function addTaskFields() {
|
|
20
|
+
|
|
21
|
+
// The name of the migration
|
|
22
|
+
this.addField('name', 'String');
|
|
23
|
+
|
|
24
|
+
// The full path of the file
|
|
25
|
+
this.addField('path', 'String');
|
|
26
|
+
|
|
27
|
+
// When the migration ended
|
|
28
|
+
this.addField('ended', 'Datetime');
|
|
29
|
+
|
|
30
|
+
// Was there an error?
|
|
31
|
+
this.addField('error', 'String');
|
|
32
|
+
|
|
33
|
+
});
|
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
|
*/
|
|
@@ -61,6 +77,15 @@ require('./core/base');
|
|
|
61
77
|
*/
|
|
62
78
|
require('./core/client_base');
|
|
63
79
|
|
|
80
|
+
/**
|
|
81
|
+
* The migration class
|
|
82
|
+
*
|
|
83
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
84
|
+
* @since 1.2.0
|
|
85
|
+
* @version 1.2.0
|
|
86
|
+
*/
|
|
87
|
+
require('./class/migration');
|
|
88
|
+
|
|
64
89
|
var hawkejs_options = {
|
|
65
90
|
server : false,
|
|
66
91
|
make_commonjs: true,
|
package/lib/class/datasource.js
CHANGED
|
@@ -165,7 +165,7 @@ Datasource.setMethod(function getSchema(schema) {
|
|
|
165
165
|
*
|
|
166
166
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
167
167
|
* @since 0.2.0
|
|
168
|
-
* @version 1.
|
|
168
|
+
* @version 1.2.0
|
|
169
169
|
*
|
|
170
170
|
* @param {Schema|Model} schema
|
|
171
171
|
* @param {Object} data
|
|
@@ -187,7 +187,7 @@ Datasource.setMethod(function toDatasource(schema, data, callback) {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
if (!schema) {
|
|
190
|
-
log.todo('Schema not found: not normalizing data');
|
|
190
|
+
log.todo('Schema not found: not normalizing data', data);
|
|
191
191
|
pledge = Pledge.resolve(data);
|
|
192
192
|
pledge.done(callback);
|
|
193
193
|
return pledge;
|
package/lib/class/element.js
CHANGED
|
@@ -23,12 +23,17 @@ Function.getNamespace('Alchemy.Element').setStatic('default_element_prefix', 'al
|
|
|
23
23
|
*
|
|
24
24
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
25
25
|
* @since 1.1.3
|
|
26
|
-
* @version 1.1
|
|
26
|
+
* @version 1.2.1
|
|
27
27
|
*
|
|
28
28
|
* @return {RURL}
|
|
29
29
|
*/
|
|
30
30
|
Element.setMethod(function getCurrentUrl() {
|
|
31
31
|
if (Blast.isBrowser) {
|
|
32
|
+
|
|
33
|
+
if (hawkejs.scene.opening_url && hawkejs.scene.opening_url.url) {
|
|
34
|
+
return Blast.Classes.RURL.parse(hawkejs.scene.opening_url.url);
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
return Blast.Classes.RURL.parse(window.location);
|
|
33
38
|
} else if (this.hawkejs_renderer && this.hawkejs_renderer.variables && this.hawkejs_renderer.variables.__url) {
|
|
34
39
|
return this.hawkejs_renderer.variables.__url.clone();
|