@steedos/objectql 2.1.16 → 2.1.20
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/actions/field_updates.js +28 -21
- package/lib/actions/field_updates.js.map +1 -1
- package/lib/actions/workflow_notifications.js +1 -1
- package/lib/actions/workflow_notifications.js.map +1 -1
- package/lib/actions/workflow_rule.js +2 -2
- package/lib/actions/workflow_rule.js.map +1 -1
- package/lib/driver/metadata.d.ts +40 -0
- package/lib/driver/metadata.js +201 -0
- package/lib/driver/metadata.js.map +1 -0
- package/lib/types/object.js +24 -7
- package/lib/types/object.js.map +1 -1
- package/lib/types/schema.d.ts +2 -0
- package/lib/types/schema.js +2 -0
- package/lib/types/schema.js.map +1 -1
- package/package.json +9 -8
- package/src/actions/field_updates.ts +15 -12
- package/src/actions/workflow_notifications.ts +1 -1
- package/src/actions/workflow_rule.ts +2 -2
- package/src/driver/metadata.ts +213 -0
- package/src/types/object.ts +25 -6
- package/src/types/schema.ts +2 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { Dictionary } from "@salesforce/ts-types";
|
|
2
|
+
import { SteedosDriver } from ".";
|
|
3
|
+
import { SteedosQueryOptions, SteedosIDType, SteedosObjectType } from "../types";
|
|
4
|
+
import { SteedosDriverConfig } from "./driver";
|
|
5
|
+
import { SteedosFieldDBType } from "./fieldDBType";
|
|
6
|
+
import mingo = require('mingo');
|
|
7
|
+
import steedosFilters = require('@steedos/filters');
|
|
8
|
+
import odataV4Mongodb = require('odata-v4-mongodb');
|
|
9
|
+
import clone = require("clone");
|
|
10
|
+
import _ = require('underscore');
|
|
11
|
+
|
|
12
|
+
export class MetadataDriver implements SteedosDriver {
|
|
13
|
+
databaseVersion?: string;
|
|
14
|
+
config?: SteedosDriverConfig;
|
|
15
|
+
connect() {
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
close() {
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
formatFiltersToMongoQuery(filters) {
|
|
23
|
+
let emptyFilters = {};
|
|
24
|
+
let odataQuery = "";
|
|
25
|
+
if (_.isString(filters)) {
|
|
26
|
+
odataQuery = filters;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
odataQuery = steedosFilters.formatFiltersToODataQuery(filters)
|
|
30
|
+
}
|
|
31
|
+
if(!odataQuery){
|
|
32
|
+
return emptyFilters;
|
|
33
|
+
}
|
|
34
|
+
let query = odataV4Mongodb.createFilter(odataQuery);
|
|
35
|
+
return query;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getMongoFilters(filters) {
|
|
39
|
+
let emptyFilters = {};
|
|
40
|
+
if (_.isUndefined(filters)) {
|
|
41
|
+
return emptyFilters;
|
|
42
|
+
}
|
|
43
|
+
if (_.isString(filters) && !filters.length) {
|
|
44
|
+
return emptyFilters
|
|
45
|
+
}
|
|
46
|
+
if (_.isArray(filters) && !filters.length) {
|
|
47
|
+
return emptyFilters
|
|
48
|
+
}
|
|
49
|
+
let mongoFilters = this.formatFiltersToMongoQuery(filters);
|
|
50
|
+
return mongoFilters
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getMongoFieldsOptions(fields) {
|
|
54
|
+
if (typeof fields == "string") {
|
|
55
|
+
fields = (fields).split(",").map((n) => { return n.trim(); });
|
|
56
|
+
}
|
|
57
|
+
if (!(fields && fields.length)) {
|
|
58
|
+
return {}
|
|
59
|
+
}
|
|
60
|
+
let projection = {};
|
|
61
|
+
(fields).forEach((field) => {
|
|
62
|
+
if (field) {
|
|
63
|
+
projection[field] = 1;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return projection;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getMongoOptions(options) {
|
|
70
|
+
if (_.isUndefined(options)) {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
let result: any = {};
|
|
74
|
+
let projection = this.getMongoFieldsOptions(options.fields);
|
|
75
|
+
let sort = this.getMongoSortOptions(options.sort);
|
|
76
|
+
result.projection = projection;
|
|
77
|
+
result.sort = sort;
|
|
78
|
+
result.limit = options.top;
|
|
79
|
+
result.skip = options.skip;
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
getMongoSortOptions(sort) {
|
|
84
|
+
let result = undefined;
|
|
85
|
+
if (sort && typeof sort === "string") {
|
|
86
|
+
let arraySort= sort.split(",").map((n) => { return n.trim(); });
|
|
87
|
+
let stringSort = "";
|
|
88
|
+
arraySort.forEach((n) => {
|
|
89
|
+
if (n) {
|
|
90
|
+
stringSort += `${n},`
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
stringSort = stringSort.replace(/,$/g, "");
|
|
94
|
+
result = odataV4Mongodb.createQuery(`$orderby=${stringSort}`).sort;
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
getAggregateOptions(options){
|
|
100
|
+
if (_.isUndefined(options)) {
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
let result = [];
|
|
104
|
+
let projection = this.getMongoFieldsOptions(options.fields);
|
|
105
|
+
let sort = this.getMongoSortOptions(options.sort);
|
|
106
|
+
if (!_.isEmpty(projection)) {
|
|
107
|
+
result.push({ $project: projection });
|
|
108
|
+
}
|
|
109
|
+
if (!_.isEmpty(sort)) {
|
|
110
|
+
result.push({ $sort: sort });
|
|
111
|
+
}
|
|
112
|
+
if (options.skip) {
|
|
113
|
+
result.push({ $skip: options.skip });
|
|
114
|
+
}
|
|
115
|
+
if (options.top) {
|
|
116
|
+
result.push({ $limit: options.top });
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
queryMetadata(collection, queryOptions, spaceId){
|
|
122
|
+
const _collection = clone(collection);
|
|
123
|
+
_.each(_collection, function(item){ item.space = spaceId})
|
|
124
|
+
let mongoFilters = this.getMongoFilters(queryOptions.filters);
|
|
125
|
+
let mongoOptions = this.getMongoOptions(queryOptions);
|
|
126
|
+
// console.log(`mongoFilters`, JSON.stringify(mongoFilters));
|
|
127
|
+
// console.log(`mongoOptions`, mongoOptions);
|
|
128
|
+
let query = new mingo.Query(mongoFilters, mongoOptions.projectio)
|
|
129
|
+
let cursor = query.find(_collection);
|
|
130
|
+
if(mongoOptions.sort){
|
|
131
|
+
cursor.sort(mongoOptions.sort)
|
|
132
|
+
}
|
|
133
|
+
// if(mongoOptions.skip){
|
|
134
|
+
// cursor.skip(mongoOptions.skip)
|
|
135
|
+
// }
|
|
136
|
+
// if(mongoOptions.limit){
|
|
137
|
+
// cursor.limit(mongoOptions.limit)
|
|
138
|
+
// }
|
|
139
|
+
return cursor;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
getSupportedColumnTypes(): SteedosFieldDBType[] {
|
|
144
|
+
throw new Error("Method not implemented.");
|
|
145
|
+
}
|
|
146
|
+
find(collection: any, query: SteedosQueryOptions, spaceId?: SteedosIDType) {
|
|
147
|
+
const result = this.queryMetadata(collection, query, spaceId).all();
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
aggregate(collection: any, query: SteedosQueryOptions, externalPipeline: any, spaceId?: SteedosIDType) {
|
|
151
|
+
const result = this.queryMetadata(collection, query, spaceId).all();
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
findOne(collection: any, id: SteedosIDType, query: SteedosQueryOptions, spaceId?: SteedosIDType) {
|
|
155
|
+
throw new Error("Method not implemented.");
|
|
156
|
+
}
|
|
157
|
+
insert(collection: any, doc: Dictionary<any>, spaceId?: SteedosIDType) {
|
|
158
|
+
throw new Error("Method not implemented.");
|
|
159
|
+
}
|
|
160
|
+
update(collection: any, id: SteedosQueryOptions | SteedosIDType, doc: Dictionary<any>, spaceId?: SteedosIDType) {
|
|
161
|
+
throw new Error("Method not implemented.");
|
|
162
|
+
}
|
|
163
|
+
updateOne(collection: any, id: SteedosQueryOptions | SteedosIDType, doc: Dictionary<any>, spaceId?: SteedosIDType) {
|
|
164
|
+
throw new Error("Method not implemented.");
|
|
165
|
+
}
|
|
166
|
+
updateMany?(collection: any, queryFilters: any, doc: Dictionary<any>, spaceId?: SteedosIDType) {
|
|
167
|
+
throw new Error("Method not implemented.");
|
|
168
|
+
}
|
|
169
|
+
delete(collection: any, id: SteedosQueryOptions | SteedosIDType, spaceId?: SteedosIDType) {
|
|
170
|
+
throw new Error("Method not implemented.");
|
|
171
|
+
}
|
|
172
|
+
directUpdate(collection: any, id: SteedosQueryOptions | SteedosIDType, doc: Dictionary<any>, spaceId?: SteedosIDType) {
|
|
173
|
+
throw new Error("Method not implemented.");
|
|
174
|
+
}
|
|
175
|
+
directFind(collection: any, query: SteedosQueryOptions, spaceId?: SteedosIDType) {
|
|
176
|
+
throw new Error("Method not implemented.");
|
|
177
|
+
}
|
|
178
|
+
directInsert(collection: any, doc: Dictionary<any>, spaceId?: SteedosIDType) {
|
|
179
|
+
throw new Error("Method not implemented.");
|
|
180
|
+
}
|
|
181
|
+
directDelete(collection: any, id: SteedosQueryOptions | SteedosIDType, spaceId?: SteedosIDType) {
|
|
182
|
+
throw new Error("Method not implemented.");
|
|
183
|
+
}
|
|
184
|
+
directAggregate?(collection: any, query: SteedosQueryOptions, externalPipeline: any, spaceId?: SteedosIDType) {
|
|
185
|
+
throw new Error("Method not implemented.");
|
|
186
|
+
}
|
|
187
|
+
directAggregatePrefixalPipeline?(collection: any, query: SteedosQueryOptions, prefixalPipeline: any, spaceId?: SteedosIDType) {
|
|
188
|
+
throw new Error("Method not implemented.");
|
|
189
|
+
}
|
|
190
|
+
count(collection: any, query: SteedosQueryOptions, spaceId?: SteedosIDType) {
|
|
191
|
+
const result = this.queryMetadata(collection, query, spaceId).count();
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
dropEntities?() {
|
|
195
|
+
throw new Error("Method not implemented.");
|
|
196
|
+
}
|
|
197
|
+
registerEntities?(objects: Dictionary<SteedosObjectType>) {
|
|
198
|
+
throw new Error("Method not implemented.");
|
|
199
|
+
}
|
|
200
|
+
dropTables?() {
|
|
201
|
+
throw new Error("Method not implemented.");
|
|
202
|
+
}
|
|
203
|
+
createTables?(objects: Dictionary<SteedosObjectType>) {
|
|
204
|
+
throw new Error("Method not implemented.");
|
|
205
|
+
}
|
|
206
|
+
init(objects: Dictionary<SteedosObjectType>) {
|
|
207
|
+
throw new Error("Method not implemented.");
|
|
208
|
+
}
|
|
209
|
+
_makeNewID?(tableName?: string) {
|
|
210
|
+
throw new Error("Method not implemented.");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
}
|
package/src/types/object.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { runValidationRules } from './validation_rules';
|
|
|
14
14
|
import { brokeEmitEvents } from "./object_events";
|
|
15
15
|
import { translationObject } from "@steedos/i18n";
|
|
16
16
|
import { getObjectLayouts } from "./object_layouts";
|
|
17
|
+
import { sortBy } from 'lodash';
|
|
17
18
|
declare var Creator: any;
|
|
18
19
|
const clone = require('clone')
|
|
19
20
|
|
|
@@ -942,6 +943,7 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
|
|
942
943
|
if(layouts && layouts.length > 0){
|
|
943
944
|
const layout = layouts[0];
|
|
944
945
|
let _fields = {};
|
|
946
|
+
let sort_no = 1;
|
|
945
947
|
_.each(layout.fields, function(_item){
|
|
946
948
|
_fields[_item.field_name] = objectConfig.fields[_item.field_name]
|
|
947
949
|
if(_fields[_item.field_name]){
|
|
@@ -962,6 +964,9 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
|
|
962
964
|
if(_item.visible_on){
|
|
963
965
|
_fields[_item.field_name].visible_on = _item.visible_on
|
|
964
966
|
}
|
|
967
|
+
|
|
968
|
+
_fields[_item.field_name].sort_no = sort_no;
|
|
969
|
+
sort_no++;
|
|
965
970
|
}
|
|
966
971
|
})
|
|
967
972
|
|
|
@@ -976,22 +981,36 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
|
|
976
981
|
|
|
977
982
|
_.each(difference, function(fieldApiName){
|
|
978
983
|
objectConfig.fields[fieldApiName].hidden = true;
|
|
984
|
+
objectConfig.fields[fieldApiName].sort_no = 99999;
|
|
979
985
|
})
|
|
980
986
|
|
|
981
|
-
let _buttons = {};
|
|
982
987
|
_.each(layout.buttons, function(button){
|
|
983
988
|
const action = objectConfig.actions[button.button_name];
|
|
984
989
|
if(action){
|
|
985
990
|
if(button.visible_on){
|
|
986
|
-
action.
|
|
991
|
+
action._visible = button.visible_on;
|
|
987
992
|
}
|
|
988
|
-
_buttons[button.button_name] = action
|
|
989
993
|
}
|
|
990
994
|
})
|
|
991
|
-
|
|
995
|
+
|
|
996
|
+
const layoutButtonsName = _.pluck(layout.buttons,'button_name');
|
|
997
|
+
_.each(objectConfig.actions, function(action){
|
|
998
|
+
if(!_.include(layoutButtonsName, action.name)){
|
|
999
|
+
action.visible = false
|
|
1000
|
+
action._visible = function(){return false}.toString()
|
|
1001
|
+
}
|
|
1002
|
+
})
|
|
992
1003
|
// _object.allow_customActions = userObjectLayout.custom_actions || []
|
|
993
1004
|
// _object.exclude_actions = userObjectLayout.exclude_actions || []
|
|
994
1005
|
objectConfig.related_lists = layout.related_lists || []
|
|
1006
|
+
_.each(objectConfig.related_lists, (related_list)=>{
|
|
1007
|
+
if(related_list.sort_field_name && _.isArray(related_list.sort_field_name) && related_list.sort_field_name.length > 0){
|
|
1008
|
+
related_list.sort = [];
|
|
1009
|
+
_.each(related_list.sort_field_name, (fName)=>{
|
|
1010
|
+
related_list.sort.push({field_name: fName, order: related_list.sort_order || 'asc'})
|
|
1011
|
+
})
|
|
1012
|
+
}
|
|
1013
|
+
})
|
|
995
1014
|
}
|
|
996
1015
|
|
|
997
1016
|
// TODO object layout 是否需要控制审批记录显示?
|
|
@@ -1031,7 +1050,7 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
|
|
1031
1050
|
const related_lists = [];
|
|
1032
1051
|
|
|
1033
1052
|
const objectConfig: any = await this.callMetadataObjectServiceAction('getOriginalObject', {objectApiName: this.name});
|
|
1034
|
-
_.each(objectConfig.fields, function(field, key){
|
|
1053
|
+
_.each(sortBy(objectConfig.fields, function(o) { return o.sort_no; }), function(field, key){
|
|
1035
1054
|
const layoutField: any = {};
|
|
1036
1055
|
layoutField.field_name = field.name || key;
|
|
1037
1056
|
layoutField.is_readonly = field.readonly;
|
|
@@ -1208,7 +1227,7 @@ export class SteedosObjectType extends SteedosObjectProperties {
|
|
|
1208
1227
|
}
|
|
1209
1228
|
|
|
1210
1229
|
private async runBeforeTriggers(method: string, context: SteedosTriggerContextConfig) {
|
|
1211
|
-
if (method === 'count') {
|
|
1230
|
+
if (method === 'count' || method === "findOne") {
|
|
1212
1231
|
method = 'find';
|
|
1213
1232
|
}
|
|
1214
1233
|
let meteorWhen = `before${method.charAt(0).toLocaleUpperCase()}${_.rest([...method]).join('')}`
|
package/src/types/schema.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { getFromContainer } from 'typeorm';
|
|
|
9
9
|
// import { preloadDBObjectFields, preloadDBObjectButtons } from '../dynamic-load';
|
|
10
10
|
import { buildGraphQLSchema } from '../graphql';
|
|
11
11
|
import { MetadataRegister } from '../metadata-register';
|
|
12
|
+
import { MetadataDriver } from '../driver/metadata';
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
const defaultDatasourceName = 'default';
|
|
@@ -25,6 +26,7 @@ export class SteedosSchema {
|
|
|
25
26
|
private _broker: any = null;
|
|
26
27
|
private _metadataBroker: any = null;
|
|
27
28
|
metadataRegister: MetadataRegister = null;
|
|
29
|
+
metadataDriver = new MetadataDriver();
|
|
28
30
|
public get metadataBroker(): any {
|
|
29
31
|
return this._metadataBroker;
|
|
30
32
|
}
|