@steedos/standard-object-database 2.5.0-beta.14 → 2.5.0-beta.15
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/main/default/objectTranslations/object_triggers.zh-CN/object_triggers.zh-CN.objectTranslation.yml +3 -5
- package/main/default/objects/2.object_triggers.observe.object.js +42 -34
- package/main/default/objects/object_triggers.object.yml +52 -51
- package/main/default/objects/objects.core.js +0 -28
- package/main/default/pages/object_detail.page.amis.json +13 -0
- package/main/default/routes/amis_listview_design.router.js +1 -1
- package/main/default/services/database-objects.service.js +115 -0
- package/main/default/services/suggestions.service.js +185 -0
- package/main/default/triggers/object_triggers.trigger.js +53 -34
- package/package.json +2 -2
- package/main/default/objects/object_triggers.core.js +0 -58
- package/main/default/objects/object_triggers.object.js +0 -65
|
@@ -14,14 +14,12 @@ fields:
|
|
|
14
14
|
label: 运行时
|
|
15
15
|
help:
|
|
16
16
|
description:
|
|
17
|
-
|
|
17
|
+
isEnabled:
|
|
18
18
|
label: 已启用
|
|
19
19
|
help:
|
|
20
20
|
description:
|
|
21
|
-
|
|
22
|
-
label:
|
|
23
|
-
执行的脚本 <a target="_blank"
|
|
24
|
-
href="https://developer.steedos.com/developer/object_trigger">查看帮助</a>
|
|
21
|
+
handler:
|
|
22
|
+
label: 内容
|
|
25
23
|
help:
|
|
26
24
|
description:
|
|
27
25
|
listviews:
|
|
@@ -1,35 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*
|
|
2
|
+
* @Author: baozhoutao@steedos.com
|
|
3
|
+
* @Date: 2022-08-05 14:17:44
|
|
4
|
+
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
+
* @LastEditTime: 2023-04-21 17:06:15
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
// var objectql = require('@steedos/objectql');
|
|
9
|
+
// var triggerCore = require('./object_triggers.core.js');
|
|
3
10
|
|
|
4
|
-
Meteor.startup(function () {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
11
|
+
// Meteor.startup(function () {
|
|
12
|
+
// var _change, _remove;
|
|
13
|
+
// _change = function (document) {
|
|
14
|
+
// console.log("object_triggers===> _change");
|
|
15
|
+
// triggerCore.loadObjectTrigger(document)
|
|
16
|
+
// };
|
|
17
|
+
// _remove = function (document) {
|
|
18
|
+
// triggerCore.removeObjectTrigger(document);
|
|
19
|
+
// };
|
|
20
|
+
// var config = objectql.getSteedosConfig();
|
|
21
|
+
// if(config.tenant && config.tenant.saas){
|
|
22
|
+
// return ;
|
|
23
|
+
// }else{
|
|
24
|
+
// Creator.getCollection("object_triggers").find({is_enable: true}, {
|
|
25
|
+
// fields: {
|
|
26
|
+
// created: 0,
|
|
27
|
+
// created_by: 0,
|
|
28
|
+
// modified: 0,
|
|
29
|
+
// modified_by: 0
|
|
30
|
+
// }
|
|
31
|
+
// }).observe({
|
|
32
|
+
// added: function (newDocument) {
|
|
33
|
+
// return _change(newDocument);
|
|
34
|
+
// },
|
|
35
|
+
// changed: function (newDocument, oldDocument) {
|
|
36
|
+
// return _change(newDocument);
|
|
37
|
+
// },
|
|
38
|
+
// removed: function (oldDocument) {
|
|
39
|
+
// return _remove(oldDocument);
|
|
40
|
+
// }
|
|
41
|
+
// });
|
|
42
|
+
// }
|
|
43
|
+
// });
|
|
@@ -1,94 +1,95 @@
|
|
|
1
1
|
name: object_triggers
|
|
2
2
|
icon: apex
|
|
3
3
|
label: Object Triggers
|
|
4
|
+
version: 2.0
|
|
4
5
|
hidden: true
|
|
5
6
|
fields:
|
|
6
|
-
|
|
7
|
+
_name:
|
|
7
8
|
type: text
|
|
8
9
|
label: Name
|
|
9
10
|
searchable: true
|
|
10
11
|
index: true
|
|
11
12
|
required: true
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
name:
|
|
14
|
+
data_type: text
|
|
15
|
+
formula: listenTo.name+"_"+_name
|
|
16
|
+
formula_blank_value: blanks
|
|
17
|
+
type: formula
|
|
18
|
+
visible_on: "{{false}}"
|
|
19
|
+
listenTo:
|
|
16
20
|
label: Object
|
|
17
21
|
type: master_detail
|
|
18
22
|
reference_to: objects
|
|
19
23
|
reference_to_field: name
|
|
20
24
|
required: true
|
|
21
|
-
# on:
|
|
22
|
-
# label: 运行于
|
|
23
|
-
# type: lookup
|
|
24
|
-
# required: true
|
|
25
|
-
# optionsFunction: !<tag:yaml.org,2002:js/function> |-
|
|
26
|
-
# function () {
|
|
27
|
-
# return [{
|
|
28
|
-
# label: "客户端",
|
|
29
|
-
# value: "client",
|
|
30
|
-
# icon: "address"
|
|
31
|
-
# }, {
|
|
32
|
-
# label: "服务端",
|
|
33
|
-
# value: "server",
|
|
34
|
-
# icon: "address"
|
|
35
|
-
# }];
|
|
36
|
-
# }
|
|
37
25
|
when:
|
|
38
26
|
label: Execution Time Option
|
|
39
|
-
type:
|
|
27
|
+
type: select
|
|
40
28
|
required: true
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
29
|
+
multiple: true
|
|
30
|
+
is_wide: true
|
|
31
|
+
options: [{
|
|
44
32
|
label: "新增记录之前",
|
|
45
|
-
value: "beforeInsert"
|
|
46
|
-
icon: "asset_relationship"
|
|
33
|
+
value: "beforeInsert"
|
|
47
34
|
}, {
|
|
48
35
|
label: "新增记录之后",
|
|
49
|
-
value: "afterInsert"
|
|
50
|
-
icon: "asset_relationship"
|
|
36
|
+
value: "afterInsert"
|
|
51
37
|
}, {
|
|
52
38
|
label: "修改记录之前",
|
|
53
|
-
value: "beforeUpdate"
|
|
54
|
-
icon: "asset_relationship"
|
|
39
|
+
value: "beforeUpdate"
|
|
55
40
|
}, {
|
|
56
41
|
label: "修改记录之后",
|
|
57
|
-
value: "afterUpdate"
|
|
58
|
-
icon: "asset_relationship"
|
|
42
|
+
value: "afterUpdate"
|
|
59
43
|
}, {
|
|
60
44
|
label: "删除记录之前",
|
|
61
|
-
value: "beforeDelete"
|
|
62
|
-
icon: "asset_relationship"
|
|
45
|
+
value: "beforeDelete"
|
|
63
46
|
}, {
|
|
64
47
|
label: "删除记录之后",
|
|
65
|
-
value: "afterDelete"
|
|
66
|
-
icon: "asset_relationship"
|
|
48
|
+
value: "afterDelete"
|
|
67
49
|
}, {
|
|
68
50
|
label: "查下记录之前",
|
|
69
|
-
value: "beforeFind"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
is_enable:
|
|
74
|
-
label: Enable
|
|
51
|
+
value: "beforeFind"
|
|
52
|
+
}]
|
|
53
|
+
isEnabled:
|
|
54
|
+
label: Enabled
|
|
75
55
|
type: boolean
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
56
|
+
defaultValue: true
|
|
57
|
+
handler:
|
|
58
|
+
label: Handler
|
|
59
|
+
type: code
|
|
60
|
+
language: javascript
|
|
80
61
|
is_wide: true
|
|
62
|
+
required: true
|
|
63
|
+
defaultValue: |-
|
|
64
|
+
const { params, getObject, getUser, call } = ctx;
|
|
65
|
+
editorDidMount: |-
|
|
66
|
+
if(window._registerCompletionItemProviderTrigger){
|
|
67
|
+
return ;
|
|
68
|
+
}
|
|
69
|
+
window._registerCompletionItemProviderTrigger = true;
|
|
70
|
+
const result = Steedos.authRequest("/service/api/suggestions/trigger.d.ts", {async: false});
|
|
71
|
+
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
|
72
|
+
result
|
|
73
|
+
);
|
|
74
|
+
record_permissions:
|
|
75
|
+
type: object
|
|
76
|
+
visible_on: "{{global.mode ==='read' ? true : false}}"
|
|
77
|
+
is_system:
|
|
78
|
+
type: boolean
|
|
79
|
+
label: System
|
|
80
|
+
readonly: true
|
|
81
|
+
visible_on: "{{global.mode ==='read' ? true : false}}"
|
|
82
|
+
disabled: true
|
|
81
83
|
paging:
|
|
82
84
|
enabled: false
|
|
83
85
|
list_views:
|
|
84
86
|
all:
|
|
85
87
|
columns:
|
|
86
88
|
- name
|
|
87
|
-
|
|
88
|
-
- object
|
|
89
|
-
# - 'on'
|
|
89
|
+
- listenTo
|
|
90
90
|
- when
|
|
91
|
-
-
|
|
91
|
+
- isEnabled
|
|
92
|
+
- is_system
|
|
92
93
|
label: All
|
|
93
94
|
filter_scope: space
|
|
94
95
|
permission_set:
|
|
@@ -2,8 +2,6 @@ var objectql = require('@steedos/objectql');
|
|
|
2
2
|
const clone = require('clone');
|
|
3
3
|
const defaultDatasourceName = 'default';
|
|
4
4
|
const defaultDatasourcesName = ['default','meteor'];
|
|
5
|
-
var triggerCore = require('./object_triggers.core.js');
|
|
6
|
-
var permissionCore = require('./permission_objects.core.js');
|
|
7
5
|
|
|
8
6
|
const DB_OBJECT_SERVICE_NAME = '~database-objects';
|
|
9
7
|
|
|
@@ -44,32 +42,6 @@ function getDataSourceName(doc) {
|
|
|
44
42
|
return defaultDatasourceName
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
function loadObjectTriggers(object) {
|
|
48
|
-
Creator.getCollection("object_triggers").find({ space: object.space, object: object.name, is_enable: true }, {
|
|
49
|
-
fields: {
|
|
50
|
-
created: 0,
|
|
51
|
-
created_by: 0,
|
|
52
|
-
modified: 0,
|
|
53
|
-
modified_by: 0
|
|
54
|
-
}
|
|
55
|
-
}).forEach(function (trigger) {
|
|
56
|
-
triggerCore.loadObjectTrigger(trigger);
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function loadObjectPermission(object) {
|
|
61
|
-
Creator.getCollection("permission_objects").find({ space: object.space, object_name: object.name }, {
|
|
62
|
-
fields: {
|
|
63
|
-
created: 0,
|
|
64
|
-
created_by: 0,
|
|
65
|
-
modified: 0,
|
|
66
|
-
modified_by: 0
|
|
67
|
-
}
|
|
68
|
-
}).forEach(function (permission) {
|
|
69
|
-
permissionCore.loadObjectPermission(permission);
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
|
|
73
45
|
|
|
74
46
|
function getObjectFields(object) {
|
|
75
47
|
var object_fields = Creator.getCollection("object_fields").find({
|
|
@@ -111,6 +111,19 @@
|
|
|
111
111
|
}
|
|
112
112
|
]
|
|
113
113
|
},
|
|
114
|
+
{
|
|
115
|
+
"title": "触发器",
|
|
116
|
+
"body": [
|
|
117
|
+
{
|
|
118
|
+
"type": "steedos-object-related-listview",
|
|
119
|
+
"objectApiName": "objects",
|
|
120
|
+
"recordId": "${recordId}",
|
|
121
|
+
"relatedObjectApiName": "object_triggers",
|
|
122
|
+
"relatedKey": "listenTo",
|
|
123
|
+
"perPage": 20
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
},
|
|
114
127
|
{
|
|
115
128
|
"title": "流程映射",
|
|
116
129
|
"body": [
|
|
@@ -41,7 +41,7 @@ router.get('/api/amisListviewDesign', core.requireAuthentication, async function
|
|
|
41
41
|
userId: userSession.userId,
|
|
42
42
|
authToken: userSession.authToken,
|
|
43
43
|
id: req.query.id,
|
|
44
|
-
object_name: record
|
|
44
|
+
object_name: record && record.object_name ? record.object_name : ""
|
|
45
45
|
}
|
|
46
46
|
const options = {}
|
|
47
47
|
ejs.renderFile(filename, data, options, function(err, str){
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: baozhoutao@steedos.com
|
|
3
|
+
* @Date: 2023-04-21 16:25:07
|
|
4
|
+
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
+
* @LastEditTime: 2023-04-24 17:13:00
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
var packageServiceName = '~database-objects'
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
name: packageServiceName,
|
|
12
|
+
namespace: "steedos",
|
|
13
|
+
|
|
14
|
+
dependencies: ['~packages-standard-objects'],
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Actions
|
|
18
|
+
*/
|
|
19
|
+
actions: {
|
|
20
|
+
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Events
|
|
25
|
+
*/
|
|
26
|
+
events: {
|
|
27
|
+
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Methods
|
|
32
|
+
*/
|
|
33
|
+
methods: {
|
|
34
|
+
changeTriggerMetadata: {
|
|
35
|
+
async handler(trigger){
|
|
36
|
+
await this.broker.call(`object_triggers.add`, { apiName: `${trigger.listenTo}.${trigger.name}`, data: trigger }, {
|
|
37
|
+
meta: {
|
|
38
|
+
metadataServiceName: packageServiceName,
|
|
39
|
+
caller: {
|
|
40
|
+
nodeID: this.broker.nodeID,
|
|
41
|
+
service: {
|
|
42
|
+
name: packageServiceName,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}});
|
|
46
|
+
this.broker.broadcast('metadata.object_triggers.change', {apiName: `${trigger.listenTo}.${trigger.name}`, listenTo: trigger.listenTo})
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
removeTriggerMetadata: {
|
|
50
|
+
async handler(trigger){
|
|
51
|
+
await this.broker.call(`object_triggers.delete`, { apiName: `${trigger.listenTo}.${trigger.name}`}, {
|
|
52
|
+
meta: {
|
|
53
|
+
metadataServiceName: packageServiceName,
|
|
54
|
+
caller: {
|
|
55
|
+
nodeID: this.broker.nodeID,
|
|
56
|
+
service: {
|
|
57
|
+
name: packageServiceName,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}});
|
|
61
|
+
this.broker.broadcast('metadata.object_triggers.change', {apiName: `${trigger.listenTo}.${trigger.name}`, listenTo: trigger.listenTo})
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
subTriggers: {
|
|
65
|
+
async handler(){
|
|
66
|
+
return Creator.getCollection("object_triggers").find({}, {
|
|
67
|
+
fields: {
|
|
68
|
+
created: 0,
|
|
69
|
+
created_by: 0,
|
|
70
|
+
modified: 0,
|
|
71
|
+
modified_by: 0
|
|
72
|
+
}
|
|
73
|
+
}).observe({
|
|
74
|
+
added: (newDocument)=>{
|
|
75
|
+
return this.changeTriggerMetadata(newDocument);
|
|
76
|
+
},
|
|
77
|
+
changed: (newDocument, oldDocument) => {
|
|
78
|
+
if(newDocument.name != oldDocument.name){
|
|
79
|
+
this.removeTriggerMetadata(oldDocument);
|
|
80
|
+
}
|
|
81
|
+
return this.changeTriggerMetadata(newDocument);
|
|
82
|
+
},
|
|
83
|
+
removed: (oldDocument) => {
|
|
84
|
+
return this.removeTriggerMetadata(oldDocument);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Service created lifecycle event handler
|
|
93
|
+
*/
|
|
94
|
+
async created() {
|
|
95
|
+
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Service started lifecycle event handler
|
|
100
|
+
*/
|
|
101
|
+
async started() {
|
|
102
|
+
Meteor.startup(async ()=>{
|
|
103
|
+
this.subTriggers = await this.subTriggers();
|
|
104
|
+
})
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Service stopped lifecycle event handler
|
|
109
|
+
*/
|
|
110
|
+
async stopped() {
|
|
111
|
+
// TODO 停止服务时, 需要执行以下操作
|
|
112
|
+
// 1 stop订阅
|
|
113
|
+
// 2 清理元数据
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
const { getObject } = require('@steedos/objectql');
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
name: "suggestions",
|
|
6
|
+
namespace: "steedos",
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Actions
|
|
10
|
+
*/
|
|
11
|
+
actions: {
|
|
12
|
+
triggerTSExtraLib: {
|
|
13
|
+
rest: {
|
|
14
|
+
method: "GET",
|
|
15
|
+
path: "/trigger.d.ts",
|
|
16
|
+
},
|
|
17
|
+
async handler(ctx) {
|
|
18
|
+
let servicesTypes = 'declare const services: {';
|
|
19
|
+
_.each(global.services, (v, k)=>{
|
|
20
|
+
if(this.checkVariableName(k)){
|
|
21
|
+
servicesTypes = `${servicesTypes} ${k}: {`
|
|
22
|
+
_.each(v, (v2, k2)=>{
|
|
23
|
+
servicesTypes = `${servicesTypes} ${k2}: (${this.getParameterNames(v2)}) => any`
|
|
24
|
+
})
|
|
25
|
+
servicesTypes = servicesTypes + '}'
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
servicesTypes = servicesTypes + '}'
|
|
30
|
+
|
|
31
|
+
let objectsTypes = 'declare const objects: {';
|
|
32
|
+
_.each(global.objects, (v, k)=>{
|
|
33
|
+
objectsTypes = `${objectsTypes} ${k}: SteedosObjectType;`
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
objectsTypes = objectsTypes + '}'
|
|
37
|
+
|
|
38
|
+
return `
|
|
39
|
+
declare var _: any;
|
|
40
|
+
declare var moment: any;
|
|
41
|
+
declare var validator: any;
|
|
42
|
+
declare var Filters: any;
|
|
43
|
+
|
|
44
|
+
declare type TriggerParams = {
|
|
45
|
+
isInsert?: boolean;
|
|
46
|
+
isUpdate?: boolean;
|
|
47
|
+
isDelete?: boolean;
|
|
48
|
+
isFind?: boolean;
|
|
49
|
+
isBefore?: boolean;
|
|
50
|
+
isAfter?: boolean;
|
|
51
|
+
isFindOne?: boolean;
|
|
52
|
+
isCount?: boolean;
|
|
53
|
+
id?: SteedosIDType;
|
|
54
|
+
doc?: JsonMap;
|
|
55
|
+
previousDoc?: JsonMap;
|
|
56
|
+
size?: number;
|
|
57
|
+
userId: SteedosIDType;
|
|
58
|
+
spaceId?: SteedosIDType;
|
|
59
|
+
objectName?: string;
|
|
60
|
+
query?: SteedosQueryOptions;
|
|
61
|
+
data?: JsonMap;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare type CTXType = {
|
|
65
|
+
params: TriggerParams;
|
|
66
|
+
meta: any;
|
|
67
|
+
call: any;
|
|
68
|
+
emit: any;
|
|
69
|
+
broadcast: any;
|
|
70
|
+
broker: {
|
|
71
|
+
namespace: string;
|
|
72
|
+
nodeID: string;
|
|
73
|
+
instanceID: string;
|
|
74
|
+
logger: any;
|
|
75
|
+
metadata: any;
|
|
76
|
+
},
|
|
77
|
+
getObject(objectName: string): any;
|
|
78
|
+
getUser(userId: string, spaceId: string): Promise<SteedosUserSession>;
|
|
79
|
+
makeNewID(): string;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
declare var ctx: CTXType;
|
|
83
|
+
|
|
84
|
+
declare type SteedosQueryFilters = any;
|
|
85
|
+
declare type SteedosIDType = number | string;
|
|
86
|
+
declare type SteedosQueryOptions = {
|
|
87
|
+
fields?: Array<string> | string;
|
|
88
|
+
readonly filters?: SteedosQueryFilters;
|
|
89
|
+
readonly top?: number;
|
|
90
|
+
readonly skip?: number;
|
|
91
|
+
readonly sort?: string;
|
|
92
|
+
};
|
|
93
|
+
declare type SteedosUserSession = {
|
|
94
|
+
userId: SteedosIDType;
|
|
95
|
+
spaceId?: string;
|
|
96
|
+
name: string;
|
|
97
|
+
username?: string;
|
|
98
|
+
mobile?: string;
|
|
99
|
+
email?: string;
|
|
100
|
+
utcOffset?: number;
|
|
101
|
+
locale?: string;
|
|
102
|
+
roles?: string[];
|
|
103
|
+
space?: any;
|
|
104
|
+
spaces?: any;
|
|
105
|
+
company?: any;
|
|
106
|
+
companies?: any;
|
|
107
|
+
organization?: any;
|
|
108
|
+
organizations?: any;
|
|
109
|
+
permission_shares?: any;
|
|
110
|
+
company_id?: string;
|
|
111
|
+
company_ids?: string[];
|
|
112
|
+
is_space_admin?: boolean;
|
|
113
|
+
steedos_id?: string;
|
|
114
|
+
};
|
|
115
|
+
declare class SteedosObjectType {
|
|
116
|
+
find(query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
117
|
+
findOne(id: SteedosIDType, query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
118
|
+
insert(doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
119
|
+
update(id: SteedosIDType, doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
120
|
+
delete(id: SteedosIDType, userSession?: SteedosUserSession): Promise<any>;
|
|
121
|
+
directFind(query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
122
|
+
directInsert(doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
123
|
+
directUpdate(id: SteedosIDType, doc: Dictionary<any>, userSession?: SteedosUserSession): Promise<any>;
|
|
124
|
+
directDelete(id: SteedosIDType, userSession?: SteedosUserSession): Promise<any>;
|
|
125
|
+
count(query: SteedosQueryOptions, userSession?: SteedosUserSession): Promise<any>;
|
|
126
|
+
}
|
|
127
|
+
${objectsTypes}
|
|
128
|
+
${servicesTypes}
|
|
129
|
+
`
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Events
|
|
136
|
+
*/
|
|
137
|
+
events: {
|
|
138
|
+
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Methods
|
|
143
|
+
*/
|
|
144
|
+
methods: {
|
|
145
|
+
checkVariableName:(variableName)=>{
|
|
146
|
+
var reg = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
147
|
+
if(reg.test(variableName)){
|
|
148
|
+
var keywords = ['break', 'case', 'catch', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 'if', 'in', 'instanceof', 'new', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void', 'while', 'with', 'true', 'false', 'null', 'undefined', 'NaN', 'Infinity'];
|
|
149
|
+
if(keywords.indexOf(variableName) === -1){
|
|
150
|
+
return true;
|
|
151
|
+
} else {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
getParameterNames:(func)=>{
|
|
159
|
+
const fnStr = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '');
|
|
160
|
+
const result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(/([^\s,]+)/g);
|
|
161
|
+
if (result === null)
|
|
162
|
+
return [];
|
|
163
|
+
else
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Service created lifecycle event handler
|
|
170
|
+
*/
|
|
171
|
+
async created() {
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Service started lifecycle event handler
|
|
176
|
+
*/
|
|
177
|
+
async started() {
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Service stopped lifecycle event handler
|
|
182
|
+
*/
|
|
183
|
+
async stopped() {
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -1,50 +1,69 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* @Author: sunhaolin@hotoa.com
|
|
3
3
|
* @Date: 2021-06-03 15:11:52
|
|
4
|
-
* @LastEditors:
|
|
5
|
-
* @LastEditTime:
|
|
4
|
+
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
+
* @LastEditTime: 2023-04-26 11:45:44
|
|
6
6
|
* @Description:
|
|
7
7
|
*/
|
|
8
|
-
const
|
|
8
|
+
const Cache = require('@steedos/cachers');
|
|
9
|
+
const _ = require('lodash');
|
|
10
|
+
const objectql = require('@steedos/objectql');
|
|
11
|
+
const PERMISSIONS = {
|
|
12
|
+
allowEdit: false,
|
|
13
|
+
allowDelete: false,
|
|
14
|
+
allowRead: true,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const BASERECORD = {
|
|
18
|
+
is_system: true,
|
|
19
|
+
record_permissions: PERMISSIONS
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getSourceTriggers = async()=>{
|
|
23
|
+
return _.map(Cache.getCacher('triggers').get('triggers'), (item)=>{
|
|
24
|
+
return {
|
|
25
|
+
...item.metadata,
|
|
26
|
+
_id: item.metadata.name,
|
|
27
|
+
...BASERECORD
|
|
28
|
+
};
|
|
29
|
+
})
|
|
30
|
+
}
|
|
9
31
|
|
|
10
32
|
module.exports = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if(filters.object){
|
|
14
|
-
let triggers = await InternalData.getObjectTriggers(filters.object, this.userId);
|
|
15
|
-
if(triggers){
|
|
16
|
-
this.data.values = this.data.values.concat(triggers)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
afterAggregate: async function(){
|
|
21
|
-
let filters = InternalData.parserFilters(this.query.filters)
|
|
22
|
-
if(filters.object){
|
|
23
|
-
let triggers = await InternalData.getObjectTriggers(filters.object, this.userId);
|
|
24
|
-
if(triggers){
|
|
25
|
-
this.data.values = this.data.values.concat(triggers)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
33
|
+
beforeFind: async function () {
|
|
34
|
+
delete this.query.fields;
|
|
28
35
|
},
|
|
36
|
+
afterFind: async function(){
|
|
37
|
+
let spaceId = this.spaceId;
|
|
38
|
+
let sourceData = await getSourceTriggers();
|
|
39
|
+
this.data.values = this.data.values.concat(sourceData);
|
|
40
|
+
this.data.values = objectql.getSteedosSchema().metadataDriver.find(this.data.values, this.query, spaceId);
|
|
41
|
+
},
|
|
29
42
|
afterCount: async function(){
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
let triggers = await InternalData.getObjectTriggers(filters.object, this.userId);
|
|
33
|
-
if(triggers){
|
|
34
|
-
this.data.values = this.data.values + triggers.length
|
|
35
|
-
}
|
|
36
|
-
}
|
|
43
|
+
let spaceId = this.spaceId;
|
|
44
|
+
this.data.values = this.data.values + objectql.getSteedosSchema().metadataDriver.count(await getSourceTriggers(), this.query, spaceId);
|
|
37
45
|
},
|
|
38
46
|
afterFindOne: async function(){
|
|
47
|
+
let spaceId = this.spaceId;
|
|
39
48
|
if(_.isEmpty(this.data.values)){
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
let trigger = await InternalData.getObjectTrigger(objectName, this.userId, id);
|
|
44
|
-
if(trigger){
|
|
45
|
-
this.data.values = trigger;
|
|
46
|
-
}
|
|
49
|
+
const records = objectql.getSteedosSchema().metadataDriver.find(await getSourceTriggers(), {filters: ['_id', '=', this.id]}, spaceId);
|
|
50
|
+
if(records.length > 0){
|
|
51
|
+
this.data.values = records[0]
|
|
47
52
|
}
|
|
48
53
|
}
|
|
54
|
+
},
|
|
55
|
+
beforeInsert: async function(){
|
|
56
|
+
const doc = this.doc;
|
|
57
|
+
const count = await objectql.getObject('object_triggers').count({filters: [['_name', '=', doc._name], ['listenTo','=', doc.listenTo]]})
|
|
58
|
+
if(count > 0){
|
|
59
|
+
throw new Error('触发器名称不能重复')
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
beforeUpdate: async function () {
|
|
63
|
+
const doc = this.doc;
|
|
64
|
+
const count = await objectql.getObject('object_triggers').count({filters: [['_name', '=', doc._name], ['listenTo','=', doc.listenTo], ['_id', '!=', this.id]]})
|
|
65
|
+
if(count > 0){
|
|
66
|
+
throw new Error('触发器名称不能重复')
|
|
67
|
+
}
|
|
49
68
|
}
|
|
50
69
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steedos/standard-object-database",
|
|
3
|
-
"version": "2.5.0-beta.
|
|
3
|
+
"version": "2.5.0-beta.15",
|
|
4
4
|
"main": "package.service.js",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
},
|
|
16
16
|
"repository": {},
|
|
17
17
|
"license": "MIT",
|
|
18
|
-
"gitHead": "
|
|
18
|
+
"gitHead": "0b66b1a87086836a5c2bc45875207c29e057cff6"
|
|
19
19
|
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
var objectql = require('@steedos/objectql');
|
|
2
|
-
var objectCore = require('./objects.lib.js');
|
|
3
|
-
const defaultDatasourceName = 'default';
|
|
4
|
-
function reloadObject(objectName, objectDataSourceName){
|
|
5
|
-
const datasource = objectql.getDataSource(objectDataSourceName);
|
|
6
|
-
if(!datasource){
|
|
7
|
-
return
|
|
8
|
-
}
|
|
9
|
-
//获取到最新的对象
|
|
10
|
-
const object = objectql.getObjectConfig(objectName);
|
|
11
|
-
datasource.setObject(object.name, object);
|
|
12
|
-
try {
|
|
13
|
-
if(!objectDataSourceName || objectDataSourceName == defaultDatasourceName){
|
|
14
|
-
Creator.Objects[object.name] = object;
|
|
15
|
-
Creator.loadObjects(object, object.name);
|
|
16
|
-
}
|
|
17
|
-
} catch (error) {
|
|
18
|
-
console.log('error', error);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function loadObjectTrigger(doc){
|
|
23
|
-
var dbObject = objectCore.getObjectFromDB(doc.object);
|
|
24
|
-
var objectDataSourceName = objectCore.getDataSourceName(dbObject);
|
|
25
|
-
|
|
26
|
-
if(!dbObject || !objectCore.canLoadObject(dbObject.name, objectDataSourceName)){
|
|
27
|
-
console.warn('warn: Not loaded. Invalid custom object_triggers -> ', doc.name);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
try {
|
|
31
|
-
//给对象添加触发器
|
|
32
|
-
objectql.addObjectListenerConfig({
|
|
33
|
-
_id: doc._id,
|
|
34
|
-
listenTo: doc.object,
|
|
35
|
-
[doc.when]: eval(`(async function(){${doc.todo}})`)//warn: 此处代码存在风险
|
|
36
|
-
});
|
|
37
|
-
reloadObject(doc.object, objectDataSourceName);
|
|
38
|
-
} catch (error) {
|
|
39
|
-
console.log('info', error.message)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function removeObjectTrigger(doc){
|
|
44
|
-
var dbObject = objectCore.getObjectFromDB(doc.object);
|
|
45
|
-
var objectDataSourceName = objectCore.getDataSourceName(dbObject);
|
|
46
|
-
if(!objectCore.canLoadObject(dbObject.name, objectDataSourceName)){
|
|
47
|
-
console.warn('warn: Not deleted. Invalid custom object -> ', doc.name);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
console.log('remove object trigger', doc._id, doc.object, doc.when);
|
|
51
|
-
objectql.removeObjectListenerConfig(doc._id, doc.object, doc.when);
|
|
52
|
-
reloadObject(doc.object, objectDataSourceName);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
module.exports = {
|
|
57
|
-
loadObjectTrigger,removeObjectTrigger
|
|
58
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
function isRepeatedName(doc, name) {
|
|
3
|
-
var other = Creator.getCollection("object_triggers").find({
|
|
4
|
-
object: doc.object,
|
|
5
|
-
space: doc.space,
|
|
6
|
-
_id: {
|
|
7
|
-
$ne: doc._id
|
|
8
|
-
},
|
|
9
|
-
name: name || doc.name
|
|
10
|
-
}, {
|
|
11
|
-
fields: {
|
|
12
|
-
_id: 1
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
if (other.count() > 0) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
return false;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
function check(userId, doc) {
|
|
22
|
-
// if (Steedos.isSpaceAdmin(userId, doc.space)) {
|
|
23
|
-
// throw new Meteor.Error(500, "只有工作区管理员才能配置触发器");
|
|
24
|
-
// }
|
|
25
|
-
// //TODO 校验关键字:remove、 drop、delete、db、collection、eval等,然后取消 企业版版限制
|
|
26
|
-
// if (doc.on === 'server' && !Steedos.isLegalVersion(doc.space, "workflow.enterprise")) {
|
|
27
|
-
// throw new Meteor.Error(500, "只有企业版支持配置服务端的触发器");
|
|
28
|
-
// }
|
|
29
|
-
return true;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
Creator.Objects.object_triggers.triggers = {
|
|
33
|
-
|
|
34
|
-
"before.delete.server.object_triggers": {
|
|
35
|
-
on: "server",
|
|
36
|
-
when: "before.remove",
|
|
37
|
-
todo: function(userId, doc) {
|
|
38
|
-
check(userId, doc);
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"before.update.server.object_triggers": {
|
|
42
|
-
on: "server",
|
|
43
|
-
when: "before.update",
|
|
44
|
-
todo: function(userId, doc, fieldNames, modifier, options) {
|
|
45
|
-
var ref;
|
|
46
|
-
check(userId, doc);
|
|
47
|
-
if ((modifier != null ? (ref = modifier.$set) != null ? ref.name : void 0 : void 0) && isRepeatedName(doc, modifier.$set.name)) {
|
|
48
|
-
throw new Meteor.Error(500, `名称不能重复${doc.name}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
"before.insert.server.object_triggers": {
|
|
53
|
-
on: "server",
|
|
54
|
-
when: "before.insert",
|
|
55
|
-
todo: function(userId, doc) {
|
|
56
|
-
check(userId, doc);
|
|
57
|
-
if(true){
|
|
58
|
-
throw new Meteor.Error(500, "请在代码中定义trigger");
|
|
59
|
-
}
|
|
60
|
-
if (isRepeatedName(doc)) {
|
|
61
|
-
throw new Meteor.Error(500, "名称不能重复");
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|