@steedos/standard-object-database 2.7.1-beta.1 → 2.7.1-beta.3

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.
@@ -0,0 +1,46 @@
1
+ name: object_webhooks
2
+ label: Object Webhook
3
+ description:
4
+ fields:
5
+ name:
6
+ label: Name
7
+ help:
8
+ description:
9
+ object_name:
10
+ label: Object
11
+ help:
12
+ description:
13
+ events:
14
+ label: Events
15
+ help:
16
+ options:
17
+ - label: create
18
+ value: create
19
+ - label: update
20
+ value: update
21
+ - label: delete
22
+ value: delete
23
+ description:
24
+ fields:
25
+ label: Fields
26
+ help:
27
+ description:
28
+ payload_url:
29
+ label: Payload URL
30
+ help:
31
+ description:
32
+ content_type:
33
+ label: Format of Request
34
+ help:
35
+ description:
36
+ active:
37
+ label: Active
38
+ help:
39
+ description:
40
+ space:
41
+ label: Company
42
+ help:
43
+ description:
44
+ listviews:
45
+ all:
46
+ label: All Object Webhooks
@@ -0,0 +1,48 @@
1
+ name: object_webhooks
2
+ label: WebHooks
3
+ description:
4
+ fields:
5
+ name:
6
+ label: 名称
7
+ help:
8
+ description:
9
+ object_name:
10
+ label: 对象
11
+ help:
12
+ description:
13
+ events:
14
+ label: 何时触发
15
+ help:
16
+ options:
17
+ - label: 记录已创建
18
+ value: create
19
+ - label: 记录已更新
20
+ value: update
21
+ - label: 记录已创建或已更新
22
+ value: createAndUpdate
23
+ - label: 记录已删除
24
+ value: delete
25
+ description:
26
+ fields:
27
+ label: 推送字段
28
+ help:
29
+ description:
30
+ payload_url:
31
+ label: URL
32
+ help:
33
+ description:
34
+ content_type:
35
+ label: 请求数据格式
36
+ help:
37
+ description:
38
+ active:
39
+ label: 激活
40
+ help:
41
+ description:
42
+ space:
43
+ label: 所属工作区
44
+ help:
45
+ description:
46
+ listviews:
47
+ all:
48
+ label: 所有
@@ -0,0 +1,5 @@
1
+ name: active
2
+ label: Active
3
+ type: boolean
4
+ defaultValue: true
5
+ sort_no: 80
@@ -0,0 +1,6 @@
1
+ name: condition
2
+ type: text
3
+ sort_no: 40
4
+ is_wide: true
5
+ label: 准入条件
6
+ inlineHelpText: 指定准入条件,减少触发执行次数。最大限度地减少非必要执行次数,这将有助于节省资源。如果您创建将在记录更新时触发,我们建议先定义准入条件。然后,对于何时为更新的记录运行,选择仅在更新记录满足条件要求时选项。
@@ -0,0 +1,5 @@
1
+ name: content_type
2
+ label: Format of Request
3
+ type: text
4
+ defaultValue: '"application/json"'
5
+ hidden: true
@@ -0,0 +1,15 @@
1
+ name: event
2
+ type: select
3
+ label: 何时触发
4
+ required: true
5
+ multiple: false
6
+ sort_no: 30
7
+ options:
8
+ - label: 记录已创建
9
+ value: create
10
+ - label: 记录已更新
11
+ value: update
12
+ - label: 记录已创建或已更新
13
+ value: createAndUpdate
14
+ - label: 记录已删除
15
+ value: delete
@@ -0,0 +1,12 @@
1
+ name: execute_when
2
+ label: 何时运行更新记录的webhook
3
+ type: select
4
+ inlineHelpText: 您可能希望仅在将触发记录从不满足条件要求更改为满足条件要求时运行。在出现此情况时,选择第二个选项。
5
+ visible_on: ${!!condition && (event === 'update' || event === 'createAndUpdate')}
6
+ sort_no: 50
7
+ is_wide: true
8
+ options:
9
+ - label: 每次更新记录并满足条件要求
10
+ value: trueEveryTime
11
+ - label: 仅在更新记录以满足条件要求时
12
+ value: trueOnChangeOnly
@@ -0,0 +1,27 @@
1
+ name: fields
2
+ type: lookup
3
+ label: Fields
4
+ multiple: true
5
+ is_wide: true
6
+ sort_no: 60
7
+ depend_on:
8
+ - object_name
9
+ optionsFunction: !!js/function |
10
+ function(values) {
11
+ var _object, _options, fields, icon, object_name;
12
+ object_name = values.object_name;
13
+ if (!object_name) {
14
+ return [];
15
+ }
16
+ _options = [];
17
+ _object = Creator.getObject(object_name);
18
+ fields = _object.fields;
19
+ icon = _object.icon;
20
+ _.forEach(fields, function(f, k) {
21
+ return _options.push({
22
+ label: f.label || k,
23
+ value: k
24
+ });
25
+ });
26
+ return _options;
27
+ }
@@ -0,0 +1,5 @@
1
+ name: name
2
+ type: text
3
+ label: Name
4
+ required: true
5
+ sort_no: 10
@@ -0,0 +1,8 @@
1
+ name: object_name
2
+ type: lookup
3
+ reference_to: objects
4
+ reference_to_field: name
5
+ label: Object
6
+ required: true
7
+ index: true
8
+ sort_no: 20
@@ -0,0 +1,7 @@
1
+ name: payload_url
2
+ label: Payload URL
3
+ type: text
4
+ is_wide: true
5
+ # regEx: /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/i
6
+ required: true
7
+ sort_no: 70
@@ -0,0 +1,9 @@
1
+ name: all
2
+ columns:
3
+ - name
4
+ - object_name
5
+ - event
6
+ - payload_url
7
+ - active
8
+ label: All Object Webhooks
9
+ filter_scope: space
@@ -0,0 +1,5 @@
1
+ name: object_webhooks
2
+ label: Object Webhook
3
+ icon: output
4
+ hidden: true
5
+ version: 2
@@ -0,0 +1,7 @@
1
+ permission_set_id: admin
2
+ allowCreate: true
3
+ allowDelete: true
4
+ allowEdit: true
5
+ allowRead: true
6
+ modifyAllRecords: true
7
+ viewAllRecords: true
@@ -0,0 +1,7 @@
1
+ permission_set_id: user
2
+ allowCreate: false
3
+ allowDelete: false
4
+ allowEdit: false
5
+ allowRead: false
6
+ modifyAllRecords: false
7
+ viewAllRecords: false
@@ -0,0 +1,51 @@
1
+ {
2
+ "type": "service",
3
+ "body": [{
4
+ "type": "steedos-object-form",
5
+ "label": "Object Webhook",
6
+ "objectApiName": "object_webhooks",
7
+ "recordId": "${recordId}",
8
+ "mode": "edit",
9
+ "layout": "horizontal",
10
+
11
+ "fieldsExtend": {
12
+ "condition": {
13
+ "amis": {
14
+ "type": "service",
15
+ "schemaApi": {
16
+ "method": "get",
17
+ "url": "/service/api/amis-metadata-objects/objects/${object_name}/fields/options",
18
+ "cache": 30000,
19
+ "adaptor": "const visibleOnVariables = SteedosUI.getFormulaVariables(payload.data.options);\n const defaultValueVariables = [visibleOnVariables[1]];\n const variables = [];\n const varItem = {\n label: '对象字段',\n children: _.map(payload.data.options, (item)=>{\n return {\n label: item.label,\n value: item.value\n }\n })\n };\n variables.push(varItem);\n payload.data={label: '准入条件', type:'input-formula', name: 'condition', variables: variables} \n return payload;",
20
+ "trackExpression": "${object_name}",
21
+ "sendOn": "${object_name}"
22
+ }
23
+ }
24
+ },
25
+ "execute_when":{
26
+ "amis": {
27
+ "type": "radios",
28
+ "inline": false
29
+ }
30
+ },
31
+ "event": {
32
+ "amis":{
33
+ "type": "radios",
34
+ "inline": false
35
+ }
36
+ }
37
+ },
38
+ "form": {
39
+ "id": "steedos_object_webhooks_form"
40
+ },
41
+ "id": "u:e17c57cce896",
42
+ "tabsMode": "line"
43
+ }],
44
+ "data": {
45
+ "context": {},
46
+ "visibleOnVariables": "",
47
+ "defaultValueVariables": ""
48
+ },
49
+ "name": "object_webhooks_form",
50
+ "id": "steedos_object_webhooks_service"
51
+ }
@@ -0,0 +1,12 @@
1
+ name: object_webhooks_form
2
+ is_active: true
3
+ label: 对象字段表单
4
+ object_name: object_webhooks
5
+ pageAssignments:
6
+ - type: orgDefault
7
+ page: object_webhooks_form
8
+ desktop: true
9
+ mobile: true
10
+ render_engine: amis
11
+ type: form
12
+ widgets: []
@@ -0,0 +1,136 @@
1
+ /*
2
+ * @Author: baozhoutao@steedos.com
3
+ * @Date: 2024-04-23 14:35:03
4
+ * @LastEditors: baozhoutao@steedos.com
5
+ * @LastEditTime: 2024-04-26 12:02:56
6
+ * @Description:
7
+ */
8
+
9
+ const BullMqMixin = require('moleculer-bullmq');
10
+ const axios = require('axios');
11
+ const { evaluate } = require("amis-formula")
12
+ const serviceObjectMixin = require('@steedos/service-object-mixin');
13
+
14
+ module.exports = {
15
+ name: "object_webhooks",
16
+ mixins: [serviceObjectMixin, BullMqMixin],
17
+ settings: {
18
+ bullmq: {
19
+ client: process.env.QUEUE_BACKEND,
20
+ worker: { concurrency: 50 }
21
+ }
22
+ },
23
+ events: {
24
+ "*.inserted": async function(ctx){
25
+ // TODO 校验是否是objectql的记录新增事件. 使用@objectApiName + .inserted 后,与ctx.eventName对比,看是否相同
26
+ const { objectApiName, id, spaceId, userId } = ctx.params;
27
+ if(objectApiName && id && spaceId){
28
+ await this.addQueue(ctx, objectApiName, "create", id, spaceId, userId)
29
+ }
30
+ },
31
+ "*.updated": async function(ctx){
32
+ // TODO 校验是否是objectql的记录新增事件. 使用@objectApiName + .updated 后,与ctx.eventName对比,看是否相同
33
+ const { objectApiName, id, spaceId, userId, previousDoc } = ctx.params;
34
+ if(objectApiName && id && spaceId){
35
+ await this.addQueue(ctx, objectApiName, "update", id, spaceId, userId, previousDoc)
36
+ }
37
+ },
38
+ "*.deleted": async function(ctx){
39
+ // TODO 校验是否是objectql的记录新增事件. 使用@objectApiName + .deleted 后,与ctx.eventName对比,看是否相同
40
+ const { objectApiName, id, spaceId, userId, previousDoc } = ctx.params;
41
+ if(objectApiName && id){
42
+ await this.addQueue(ctx, objectApiName, "delete", id, spaceId, userId, previousDoc)
43
+ }
44
+ }
45
+ },
46
+ actions: {
47
+ send: {
48
+ queue: true,
49
+ async handler(ctx) {
50
+ const { url, data } = ctx.params
51
+ const result = await axios.post(url, data);
52
+ ctx.locals.job.updateProgress(100)
53
+ console.log('====>send', url, data.doc?.name)
54
+ return result.data;
55
+ }
56
+ }
57
+ },
58
+ methods: {
59
+
60
+ async addQueue(ctx, objectName, actionName, recordId, spaceId, userId, previousDoc){
61
+ const hooks = await this.getObjectWebhooks(objectName, spaceId)
62
+ if(hooks.length === 0) return
63
+
64
+ let newDoc;
65
+ if(recordId && (actionName === 'update' || actionName === 'create')){
66
+ newDoc = await this.getObject(objectName).findOne(recordId)
67
+ }
68
+ let sender;
69
+ let space;
70
+ if(userId && spaceId){
71
+ const userSession = await ctx.call('@steedos/service-accounts.getUserSession', {userId, spaceId})
72
+ if(userSession){
73
+ sender = {
74
+ id: userSession.userId,
75
+ username: userSession.username,
76
+ name: userSession.name,
77
+ email: userSession.email
78
+ }
79
+
80
+ space = {
81
+ id: userSession.space._id,
82
+ name: userSession.space.name
83
+ }
84
+ }
85
+ }
86
+
87
+ for (const hook of hooks) {
88
+
89
+ if(hook.event != 'createAndUpdate' && hook.event != actionName){
90
+ continue;
91
+ }
92
+
93
+ if(hook.event == 'createAndUpdate' && actionName != 'create' && actionName != 'update'){
94
+ continue;
95
+ }
96
+
97
+ const { execute_when, condition } = hook;
98
+
99
+ if(hook.event == 'createAndUpdate' && actionName == 'create' && execute_when == 'trueOnChangeOnly'){
100
+ continue;
101
+ }
102
+
103
+ if(condition){
104
+
105
+ if(actionName == 'update' && execute_when === 'trueOnChangeOnly'){
106
+ const oldResult = evaluate(condition, previousDoc);
107
+ if(oldResult){
108
+ continue;
109
+ }
110
+ }
111
+
112
+ const result = evaluate(condition, newDoc);
113
+ if(!result){
114
+ continue;
115
+ }
116
+ }
117
+ let data = newDoc || previousDoc;
118
+ if(hook.fields && hook.fields.length > 0){
119
+ data = _.map(data, hook.fields)
120
+ }
121
+ await this.queue(ctx, 'object_webhooks', 'send', { url: hook.payload_url, data: {
122
+ action: actionName,
123
+ object_name: objectName,
124
+ doc: data,
125
+ sender: sender,
126
+ space: space
127
+ }, space: spaceId, user: userId }, { priority: 10 })
128
+ }
129
+ },
130
+ async getObjectWebhooks(objectName, spaceId){
131
+ const SERVICE_NAME = 'metadata-cachers-service'
132
+ const hooks = await global.broker.call(`${SERVICE_NAME}.find`, {metadataName: 'object_webhooks', filters: ['object_name', '=', objectName], spaceId});
133
+ return hooks;
134
+ }
135
+ }
136
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steedos/standard-object-database",
3
- "version": "2.7.1-beta.1",
3
+ "version": "2.7.1-beta.3",
4
4
  "main": "package.service.js",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -12,10 +12,13 @@
12
12
  "description": "steedos package",
13
13
  "dependencies": {
14
14
  "@steedos-widgets/amis-lib": "^1.0.22",
15
- "@steedos/metadata-core": "2.7.1-beta.1",
16
- "@steedos/standard-objects": "2.7.1-beta.1"
15
+ "@steedos/metadata-core": "2.7.1-beta.3",
16
+ "@steedos/service-object-mixin": "2.7.1-beta.3",
17
+ "@steedos/standard-objects": "2.7.1-beta.3",
18
+ "amis-formula": "~6.3.0",
19
+ "moleculer-bullmq": "3.0.0"
17
20
  },
18
21
  "repository": {},
19
22
  "license": "MIT",
20
- "gitHead": "869f9bbc7438f42da31a8bfd91c83f088fe88079"
23
+ "gitHead": "f154c292cacb12408aa6383e8667a3f6dcd38fb6"
21
24
  }