@universis/webhooks 1.1.1

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.
Files changed (38) hide show
  1. package/.gitlab-ci.yml +40 -0
  2. package/LICENSE +163 -0
  3. package/README.md +113 -0
  4. package/dist/SchemaLoader.d.ts +4 -0
  5. package/dist/SchemaLoader.js +46 -0
  6. package/dist/SchemaLoader.js.map +1 -0
  7. package/dist/WebHookService.d.ts +11 -0
  8. package/dist/WebHookService.js +272 -0
  9. package/dist/WebHookService.js.map +1 -0
  10. package/dist/config/models/WebHook.json +182 -0
  11. package/dist/config/models/WebHookAction.json +85 -0
  12. package/dist/config/models/WebHookConfiguration.json +66 -0
  13. package/dist/config/scope.access.js +30 -0
  14. package/dist/config/scope.access.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +3 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/listeners/OnWebHook.js +33 -0
  19. package/dist/listeners/OnWebHook.js.map +1 -0
  20. package/dist/listeners/OnWebHookAction.js +53 -0
  21. package/dist/listeners/OnWebHookAction.js.map +1 -0
  22. package/dist/listeners/package.json +3 -0
  23. package/jest.config.js +202 -0
  24. package/jsconfig.json +8 -0
  25. package/package.json +65 -0
  26. package/src/SchemaLoader.d.ts +4 -0
  27. package/src/SchemaLoader.js +46 -0
  28. package/src/WebHookService.d.ts +11 -0
  29. package/src/WebHookService.js +275 -0
  30. package/src/config/models/WebHook.json +182 -0
  31. package/src/config/models/WebHookAction.json +85 -0
  32. package/src/config/models/WebHookConfiguration.json +66 -0
  33. package/src/config/scope.access.js +34 -0
  34. package/src/index.d.ts +2 -0
  35. package/src/index.js +2 -0
  36. package/src/listeners/OnWebHook.js +37 -0
  37. package/src/listeners/OnWebHookAction.js +56 -0
  38. package/src/listeners/package.json +3 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebHookService.js","names":["_common","require","_scope","_data","_SchemaLoader","_superagent","_interopRequireDefault","_query","_jsonLogger","_path","_rotatingFileStream","_dataModelFilter","_OnWebHookAction","e","__esModule","default","WebHookService","ApplicationService","constructor","app","schemaLoader","getConfiguration","getStrategy","SchemaLoaderStrategy","loaders","push","SchemaLoader","builder","getService","ODataModelBuilder","clean","container","subscribe","scopeAccess","ScopeAccessConfiguration","elements","unshift","WebHookScopeAccessElements","options","Object","assign","logLevel","logFormat","logDir","path","join","process","cwd","getSourceAt","resolve","logFile","logStream","createStream","interval","logger","JsonLogger","level","format","stdout","stderr","info","self","setTimeout","refresh","context","getApplication","createContext","items","model","asQueryable","take","silent","getAllItems","length","item","about","Promise","reject","afterSave","state","DataObjectState","Insert","target","err","warn","name","error","finalizeAsync","filterObjectAsync","filter","parser","DataModelFilterParser","$expand","$where","parseAsync","q","DataQueryable","query","primaryKey","id","prepare","Delete","where","equal","exists","count","emit","event","extraArgs","previous","application","newContext","x","action","active","select","config","username","owner","when","skip","findArgs","keys","forEach","key","value","and","viewAdapter","WebHooks","targetModel","entitySet","getEntityTypeEntitySet","origin","list","getList","total","user","send","url","result","request","set","contentType","entityType","lastResponse","status","db","executeAsync","QueryExpression","update","JSON","stringify","debug","exports"],"sources":["../src/WebHookService.js"],"sourcesContent":["// noinspection NpmUsedModulesInstalled\n\nimport {ApplicationService} from '@themost/common';\nimport {WebHookScopeAccessElements} from './config/scope.access';\nimport {\n DataObjectState,\n DataQueryable,\n ODataModelBuilder,\n SchemaLoaderStrategy\n} from '@themost/data';\nimport {SchemaLoader} from './SchemaLoader';\nimport request from 'superagent';\nimport {QueryExpression} from '@themost/query';\nimport { JsonLogger } from '@themost/json-logger';\nimport path from 'path';\nimport { createStream } from 'rotating-file-stream';\nimport {DataModelFilterParser} from '@themost/data/data-model-filter.parser';\nimport { afterSave } from './listeners/OnWebHookAction';\n\nclass WebHookService extends ApplicationService {\n constructor(app) {\n super(app);\n /**\n * @type {import('@themost/data').DefaultSchemaLoaderStrategy}\n */\n const schemaLoader = app.getConfiguration().getStrategy(SchemaLoaderStrategy);\n schemaLoader.loaders.push(new SchemaLoader(app.getConfiguration()));\n /**\n * @type {import('@themost/data').ODataModelBuilder}\n */\n const builder = app.getService(ODataModelBuilder);\n if (builder) {\n builder.clean(true);\n }\n // extend universis api scope access configuration\n if (app && app.container) {\n app.container.subscribe((container) => {\n if (container) {\n // add extra scope access elements\n const scopeAccess = app.getConfiguration().getStrategy(function ScopeAccessConfiguration() {\n });\n if (scopeAccess != null) {\n scopeAccess.elements.unshift(...WebHookScopeAccessElements);\n }\n }\n });\n }\n\n // configure logger\n // get options from configuration\n const options = Object.assign({\n logLevel: 'info',\n logFormat: 'raw',\n logDir: path.join(process.cwd(), 'log')\n }, app.getConfiguration().getSourceAt('settings/universis/webhooks'));\n const logDir = options.logDir ? path.resolve(options.logDir) : path.join(process.cwd(), 'log');\n const logFile = 'webhooks.log';\n // create a rotating write stream\n // noinspection JSValidateTypes\n const logStream = createStream(logFile, {\n interval: '1d', // rotate daily\n path: logDir\n });\n this.logger = new JsonLogger({\n level: options.logLevel,\n format: options.logFormat,\n stdout: logStream,\n stderr: logStream\n });\n this.logger.info(`Universis WebHookService initialized with log level \"${options.logLevel}\"`);\n\n if (app) {\n const self = this;\n setTimeout(() => {\n (async () => {\n await self.refresh();\n })();\n }, 1000);\n }\n\n }\n\n /**\n * Refresh web hook actions\n * @returns {Promise<void>}\n */\n async refresh() {\n /**\n * @type {import('@themost/data').DataContext}\n */\n let context;\n try {\n // noinspection JSUnresolvedReference\n context = this.getApplication().createContext();\n this.logger.info('Registering existing web hook actions');\n const items = await context.model('WebHookAction').asQueryable().take(-1).silent().getAllItems();\n if (items.length > 0) {\n this.logger.info(`Found ${items.length} web hook action(s). The operation will automatically register event listeners to the underlying data models.`);\n }\n for (const item of items) {\n const model = context.model(item.about);\n if (model) {\n await new Promise((resolve, reject) => {\n afterSave({ state: DataObjectState.Insert, target: item, model}, (err) => {\n if (err) {\n return reject(err);\n }\n return resolve();\n });\n });\n } else {\n this.logger.warn(`Cannot register web hook action with name \"${item.name || 'unknown'}\" because model \"${item.about}\" does not exist.`);\n }\n }\n } catch(err) {\n this.logger.error('An error occurred when registering existing web hooks');\n this.logger.error(err);\n } finally {\n if (context) {\n await context.finalizeAsync()\n }\n }\n }\n\n /**\n *\n * @param {import('@themost/data').DataModel} model\n * @param {*} target\n * @param {string} filter\n * @param {number} state\n * @returns {Promise<boolean>}\n */\n async filterObjectAsync(model, target, filter, state) {\n const parser = new DataModelFilterParser(model);\n const { $expand, $where } = await parser.parseAsync(filter)\n const q = new DataQueryable(model);\n Object.assign(q.query, {\n $where,\n $expand\n });\n const { primaryKey } = model;\n const id = target[primaryKey];\n q.prepare();\n if (state !== DataObjectState.Delete) {\n q.where(primaryKey).equal(id);\n }\n const exists = await q.count();\n return (exists > 0);\n }\n\n /**\n * Emit web hook events\n * @param {import('@themost/data').DataEventArgs} event\n * @param {{action?: string, emit?: boolean}} extraArgs\n */\n emit(event, extraArgs) {\n const context = event.model.context;\n // get previous and current state of the entity\n const { previous, target, state, model } = event;\n /**\n * @type {import('@themost/express').ExpressDataApplication|import('@themost/common').ApplicationBase}\n */\n const application = context.application;\n // noinspection JSUnresolvedReference\n /**\n * @type {import('@themost/express').ExpressDataContext|import('@themost/data').DataContext}\n */\n const newContext = application.createContext();\n const about = model.name;\n const self = this;\n (async function() {\n // noinspection JSUnresolvedReference\n const q = newContext.model('WebHook').asQueryable().where((x, about, state) => {\n // noinspection JSBitwiseOperatorUsage\n return (x.action.about === about) && (x.action.state === state) && (x.active === true);\n }, about, state).select((x) => {\n return {\n id: x.id,\n config: x.config,\n action: x.action,\n about: x.action.about,\n emit: x.emit,\n username: x.owner.name,\n filter: x.action.filter,\n when: x.action.when\n }\n }).silent().take(25).skip(0);\n // apply extra arguments for finding web hooks\n const findArgs = Object.assign({ emit: true }, extraArgs || {});\n q.prepare();\n Object.keys(findArgs).forEach((key) => {\n const value = findArgs[key];\n q.query.$where ? q.and(key).equal(value) : q.where(key).equal(value);\n });\n\n const { viewAdapter: WebHooks } = newContext.model('WebHook');\n const targetModel = newContext.model(about);\n // get entity set\n const builder = application.getService(ODataModelBuilder);\n const entitySet = builder.getEntityTypeEntitySet(targetModel.name)\n const { primaryKey: key } = targetModel;\n // get origin\n const origin = context.getConfiguration().getSourceAt('settings/universis/api/origin');\n /**\n * @type {{total: number, skip: number, value: Array<{ id: string,config: { url: string, insecure: boolean, secret?: string, contentType: string }, emit: boolean, username: string,action: string,about: string,filter: string,when: string}>}} list\n */\n let list = await q.getList();\n if (list.total > 0) {\n while (list.total >= (list.skip + list.value.length)) {\n for (const item of list.value) {\n // set context user\n newContext.user = {\n name: item.username || 'anonymous'\n }\n try {\n let send = true;\n if (state === DataObjectState.Insert) {\n // validate the current state of a new object\n const filter = item.when || item.filter;\n send = await self.filterObjectAsync(targetModel, target, filter, state);\n } else {\n // validate previous state\n send = await self.filterObjectAsync(targetModel, previous, item.when, state);\n // validate current state\n if (send && item.filter) {\n if (state === DataObjectState.Delete) {\n send = await self.filterObjectAsync(targetModel, previous, item.filter, state);\n } else {\n send = await self.filterObjectAsync(targetModel, target, item.filter, state);\n }\n }\n }\n if (send) {\n self.logger.info(`Sending web hook for model \"${about}\" to url \"${item.config.url}\"`);\n // send web hook request\n const result = await request('post', item.config.url)\n .set('Content-Type', item.config.contentType)\n .send({\n event: item.action,\n entityType: targetModel.name,\n entitySet: entitySet && entitySet.name,\n origin: origin,\n target: {\n id: (state === DataObjectState.Insert) ? target[key] : previous[key],\n }\n });\n const lastResponse = {\n status: result.status\n };\n self.logger.info(`Web hook for model \"${about}\" to url ${item.config.url} returned status ${result.status}`);\n // update last response with an ad-hoc query\n await newContext.db.executeAsync(\n new QueryExpression().update(WebHooks).set({\n lastResponse: JSON.stringify(lastResponse),\n }).where('id').equal(item.id)\n , []);\n } else {\n self.logger.debug(`Web hook for model \"${about}\" and object with identifier ${target[key]} to url \"${item.config.url}\" was filtered and not sent`);\n }\n } catch (err) {\n self.logger.error(`Error sending web hook for model \"${about}\" to url \"${item.config.url}\"`);\n self.logger.error(err);\n }\n }\n list = await q.take(25).skip(list.skip + list.value.length);\n }\n }\n })();\n }\n\n}\n\nexport {\n WebHookService\n}"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,182 @@
1
+ {
2
+ "$schema": "https://themost-framework.github.io/themost/models/2018/2/schema.json",
3
+ "@id": "https://universis.io/schemas/WebHook",
4
+ "name": "WebHook",
5
+ "title": "WebHooks",
6
+ "hidden": false,
7
+ "sealed": false,
8
+ "abstract": false,
9
+ "version": "1.1.0",
10
+ "fields": [
11
+ {
12
+ "@id": "https://universis.io#id",
13
+ "name": "id",
14
+ "title": "ID",
15
+ "description": "The identifier of the item.",
16
+ "type": "Guid",
17
+ "primary": true,
18
+ "readonly": true,
19
+ "value": {
20
+ "$uuid": 1
21
+ }
22
+ },
23
+ {
24
+ "@id": "http://schema.org/additionalType",
25
+ "name": "additionalType",
26
+ "title": "additionalType",
27
+ "description": "An additional type for the item, typically used for adding more specific types from external vocabularies in microdata syntax. This is a relationship between something and a class that the thing is in. In RDFa syntax, it is better to use the native RDFa syntax - the 'typeof' attribute - for multiple types. Schema.org tools may have only weaker understanding of extra types, in particular those defined externally.",
28
+ "type": "Text",
29
+ "value": "javascript:return this.model.name;",
30
+ "readonly": true
31
+ },
32
+ {
33
+ "@id": "http://schema.org/name",
34
+ "name": "name",
35
+ "title": "name",
36
+ "description": "The name of the item.",
37
+ "type": "Text"
38
+ },
39
+ {
40
+ "@id": "https://universis.io#dateCreated",
41
+ "name": "dateCreated",
42
+ "title": "dateCreated",
43
+ "description": "The date on which this item was created.",
44
+ "type": "DateTime",
45
+ "readonly": true,
46
+ "value": {
47
+ "$now": 1
48
+ }
49
+ },
50
+ {
51
+ "@id": "https://universis.io#dateModified",
52
+ "name": "dateModified",
53
+ "title": "dateModified",
54
+ "description": "The date on which this item was most recently modified.",
55
+ "type": "DateTime",
56
+ "readonly": true,
57
+ "value": {
58
+ "$now": 1
59
+ },
60
+ "calculation": {
61
+ "$now": 1
62
+ }
63
+ },
64
+ {
65
+ "@id": "https://universis.io#owner",
66
+ "name": "owner",
67
+ "title": "owner",
68
+ "description": "The owner of the item.",
69
+ "type": "User",
70
+ "editable": false,
71
+ "nullable": false,
72
+ "value": {
73
+ "$user": 1
74
+ }
75
+ },
76
+ {
77
+ "@id": "https://universis.io#emit",
78
+ "name": "emit",
79
+ "title": "Emit",
80
+ "description": "Specifies whether the webhook should be triggered automatically or not.",
81
+ "type": "Boolean",
82
+ "value": {
83
+ "$value": true
84
+ }
85
+ },
86
+ {
87
+ "@id": "https://universis.io#createdBy",
88
+ "name": "createdBy",
89
+ "title": "createdBy",
90
+ "description": "Created by user.",
91
+ "type": "User",
92
+ "readonly": true,
93
+ "value": {
94
+ "$user": 1
95
+ }
96
+ },
97
+ {
98
+ "@id": "https://universis.io#modifiedBy",
99
+ "name": "modifiedBy",
100
+ "title": "modifiedBy",
101
+ "description": "Last modified by user.",
102
+ "type": "User",
103
+ "readonly": true,
104
+ "value": {
105
+ "$user": 1
106
+ },
107
+ "calculation": {
108
+ "$user": 1
109
+ }
110
+ },
111
+ {
112
+ "@id": "https://universis.io#webHookAction",
113
+ "name": "action",
114
+ "title": "action",
115
+ "description": "Reference to WebHookAction entity that defines the scope of the webhook.",
116
+ "type": "WebHookAction",
117
+ "mapping": {
118
+ "parentModel": "WebHookAction",
119
+ "parentField": "name"
120
+ }
121
+ },
122
+ {
123
+ "@id": "https://universis.io#active",
124
+ "name": "active",
125
+ "title": "Active",
126
+ "description": "Specifies whether the webhook is active or not.",
127
+ "type": "Boolean",
128
+ "nullable": false,
129
+ "value": {
130
+ "$value": true
131
+ }
132
+ },
133
+ {
134
+ "@id": "https://universis.io#webHookConfig",
135
+ "name": "config",
136
+ "title": "WebHook endpoint configuration",
137
+ "description": "Configuration settings for the webhook endpoint e.g. authentication, custom headers etc.",
138
+ "type": "Json",
139
+ "additionalType": "WebHookConfiguration"
140
+ },
141
+ {
142
+ "@id": "https://universis.io#lastResponse",
143
+ "name": "lastResponse",
144
+ "title": "Last Response",
145
+ "description": "Details of the last response received from the webhook endpoint.",
146
+ "type": "Json"
147
+ }
148
+ ],
149
+ "privileges": [
150
+ {
151
+ "mask": 15,
152
+ "type": "global"
153
+ },
154
+ {
155
+ "mask": 15,
156
+ "type": "global",
157
+ "account": "Administrators"
158
+ },
159
+ {
160
+ "mask": 1,
161
+ "type": "self",
162
+ "filter": "owner eq me()",
163
+ "scope": [
164
+ "webhooks:read"
165
+ ]
166
+ },
167
+ {
168
+ "mask": 14,
169
+ "type": "self",
170
+ "filter": "owner eq me()",
171
+ "scope": [
172
+ "webhooks:write"
173
+ ]
174
+ }
175
+ ],
176
+ "constraints": [
177
+ ],
178
+ "seed": [
179
+ ],
180
+ "eventListeners": [
181
+ ]
182
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://themost-framework.github.io/themost/models/2018/2/schema.json",
3
+ "@id": "https://universis.io/schemas/WebHookAction",
4
+ "name": "WebHookAction",
5
+ "title": "WebHookActions",
6
+ "hidden": false,
7
+ "sealed": false,
8
+ "abstract": false,
9
+ "implements": "Thing",
10
+ "version": "1.1.0",
11
+ "fields": [
12
+ {
13
+ "@id": "http://schema.org/name",
14
+ "name": "name",
15
+ "title": "name",
16
+ "description": "The name of the item.",
17
+ "type": "Text",
18
+ "nullable": false
19
+ },
20
+ {
21
+ "@id": "http://schema.org/about",
22
+ "name": "about",
23
+ "type": "Text",
24
+ "title": "About",
25
+ "description": "The name of the entity type to which the webhook applies",
26
+ "nullable": false
27
+ },
28
+ {
29
+ "@id": "https://universis.io#state",
30
+ "name": "state",
31
+ "type": "Integer",
32
+ "title": "Event Types",
33
+ "description": "The type of event that triggers the webhook (e.g., insert, update, delete)",
34
+ "nullable": false
35
+ },
36
+ {
37
+ "@id": "https://universis.io#filter",
38
+ "name": "filter",
39
+ "type": "Text",
40
+ "title": "Filter",
41
+ "description": "Specifies when the webhook should be executed according to the current state of an object. The expression should follow OData $filter query option e.g. studentStatus ne 'active'",
42
+ "nullable": true
43
+ },
44
+ {
45
+ "@id": "https://universis.io#when",
46
+ "name": "when",
47
+ "type": "Text",
48
+ "title": "When",
49
+ "description": "An optional filter expression to further refine when the webhook is triggered according to the previous state of an object. The expression should follow OData $filter query option e.g. studentStatus eq 'active'",
50
+ "nullable": true
51
+ }
52
+ ],
53
+ "privileges": [
54
+ {
55
+ "mask": 15,
56
+ "type": "global"
57
+ },
58
+ {
59
+ "mask": 1,
60
+ "type": "global",
61
+ "account": "*"
62
+ },
63
+ {
64
+ "mask": 15,
65
+ "type": "global",
66
+ "account": "Administrators"
67
+ }
68
+ ],
69
+ "constraints": [
70
+ {
71
+ "type": "unique",
72
+ "@help": "Each item name must be unique because it is used as a reference e.g. create_user or delete_user etc.",
73
+ "fields": [
74
+ "name"
75
+ ]
76
+ }
77
+ ],
78
+ "seed": [
79
+ ],
80
+ "eventListeners": [
81
+ {
82
+ "type": "./listeners/OnWebHookAction"
83
+ }
84
+ ]
85
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "https://themost-framework.github.io/themost/models/2018/2/schema.json",
3
+ "@id": "https://universis.io/schemas/WebHookConfiguration",
4
+ "name": "WebHookConfiguration",
5
+ "title": "WebHookConfigurations",
6
+ "hidden": true,
7
+ "sealed": true,
8
+ "abstract": true,
9
+ "version": "1.1.0",
10
+ "fields": [
11
+ {
12
+ "@id": "https://universis.io#url",
13
+ "name": "url",
14
+ "title": "URL",
15
+ "description": "The URL to which the webhook payloads will be delivered",
16
+ "type": "URL",
17
+ "nullable": false
18
+ },
19
+ {
20
+ "@id": "https://universis.io#contentType",
21
+ "name": "contentType",
22
+ "title": "Content Type",
23
+ "description": "The content type of the payload sent to the webhook URL (e.g., application/json)",
24
+ "type": "Text",
25
+ "nullable": false,
26
+ "value": {
27
+ "$value": "application/json"
28
+ }
29
+ },
30
+ {
31
+ "@id": "https://universis.io#insecure",
32
+ "name": "insecure",
33
+ "title": "Insecure",
34
+ "description": "Indicates whether to skip SSL certificate verification when sending requests to the webhook URL",
35
+ "type": "Boolean",
36
+ "nullable": false,
37
+ "value": {
38
+ "$value": false
39
+ }
40
+ },
41
+ {
42
+ "@id": "https://universis.io#secret",
43
+ "name": "secret",
44
+ "title": "Secret",
45
+ "description": "An optional secret key used to sign the payloads sent to the webhook URL for verification purposes. The signature is included in the 'X-Signature' header of the request.",
46
+ "type": "Text"
47
+ }
48
+ ],
49
+ "privileges": [
50
+ {
51
+ "mask": 15,
52
+ "type": "global"
53
+ },
54
+ {
55
+ "mask": 15,
56
+ "type": "global",
57
+ "account": "Administrators"
58
+ }
59
+ ],
60
+ "constraints": [
61
+ ],
62
+ "seed": [
63
+ ],
64
+ "eventListeners": [
65
+ ]
66
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.WebHookScopeAccessElements = void 0;const WebHookScopeAccessElements = exports.WebHookScopeAccessElements = [
2
+ {
3
+ 'scope': [
4
+ 'webhooks:read'],
5
+
6
+ 'resource': '/api/WebHookActions/?',
7
+ 'access': [
8
+ 'read']
9
+
10
+ },
11
+ {
12
+ 'scope': [
13
+ 'webhooks:read'],
14
+
15
+ 'resource': '/api/WebHooks/?',
16
+ 'access': [
17
+ 'read']
18
+
19
+ },
20
+ {
21
+ 'scope': [
22
+ 'webhooks:write'],
23
+
24
+ 'resource': '/api/WebHooks/?',
25
+ 'access': [
26
+ 'read',
27
+ 'write']
28
+
29
+ }];
30
+ //# sourceMappingURL=scope.access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.access.js","names":["WebHookScopeAccessElements","exports"],"sources":["../../src/config/scope.access.js"],"sourcesContent":["const WebHookScopeAccessElements = [\n {\n 'scope': [\n 'webhooks:read',\n ],\n 'resource': '/api/WebHookActions/?',\n 'access': [\n 'read'\n ]\n },\n {\n 'scope': [\n 'webhooks:read',\n ],\n 'resource': '/api/WebHooks/?',\n 'access': [\n 'read'\n ]\n },\n {\n 'scope': [\n 'webhooks:write',\n ],\n 'resource': '/api/WebHooks/?',\n 'access': [\n 'read',\n 'write'\n ]\n }\n];\n\nexport {\n WebHookScopeAccessElements\n}"],"mappings":"uHAAA,MAAMA,0BAA0B,GAAAC,OAAA,CAAAD,0BAAA,GAAG;AAC/B;EACI,OAAO,EAAE;EACL,eAAe,CAClB;;EACD,UAAU,EAAE,uBAAuB;EACnC,QAAQ,EAAE;EACN,MAAM;;AAEd,CAAC;AACD;EACI,OAAO,EAAE;EACL,eAAe,CAClB;;EACD,UAAU,EAAE,iBAAiB;EAC7B,QAAQ,EAAE;EACN,MAAM;;AAEd,CAAC;AACD;EACI,OAAO,EAAE;EACL,gBAAgB,CACnB;;EACD,UAAU,EAAE,iBAAiB;EAC7B,QAAQ,EAAE;EACN,MAAM;EACN,OAAO;;AAEf,CAAC,CACJ","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export * from './SchemaLoader';
2
+ export * from './WebHookService';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", { value: true });var _SchemaLoader = require("./SchemaLoader");Object.keys(_SchemaLoader).forEach(function (key) {if (key === "default" || key === "__esModule") return;if (key in exports && exports[key] === _SchemaLoader[key]) return;Object.defineProperty(exports, key, { enumerable: true, get: function () {return _SchemaLoader[key];} });});
2
+ var _WebHookService = require("./WebHookService");Object.keys(_WebHookService).forEach(function (key) {if (key === "default" || key === "__esModule") return;if (key in exports && exports[key] === _WebHookService[key]) return;Object.defineProperty(exports, key, { enumerable: true, get: function () {return _WebHookService[key];} });});
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_SchemaLoader","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_WebHookService"],"sources":["../src/index.js"],"sourcesContent":["export * from './SchemaLoader';\nexport * from './WebHookService';"],"mappings":"2EAAA,IAAAA,aAAA,GAAAC,OAAA,mBAAAC,MAAA,CAAAC,IAAA,CAAAH,aAAA,EAAAI,OAAA,WAAAC,GAAA,OAAAA,GAAA,kBAAAA,GAAA,8BAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,aAAA,CAAAK,GAAA,UAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA,IAAAG,UAAA,QAAAC,GAAA,WAAAA,CAAA,UAAAT,aAAA,CAAAK,GAAA;AACA,IAAAK,eAAA,GAAAT,OAAA,qBAAAC,MAAA,CAAAC,IAAA,CAAAO,eAAA,EAAAN,OAAA,WAAAC,GAAA,OAAAA,GAAA,kBAAAA,GAAA,8BAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,eAAA,CAAAL,GAAA,UAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA,IAAAG,UAAA,QAAAC,GAAA,WAAAA,CAAA,UAAAC,eAAA,CAAAL,GAAA","ignoreList":[]}
@@ -0,0 +1,33 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.afterRemove = afterRemove;exports.afterSave = afterSave;var _WebHookService = require("../WebHookService");
2
+
3
+ /**
4
+ * A generic web hook listener for insert or update operations to any data model
5
+ * @param {import('@themost/data').DataEventArgs} event
6
+ * @param {Function} callback
7
+ */
8
+ function afterSave(event, callback) {
9
+ return afterEvent(event, callback);
10
+ }
11
+ /**
12
+ * @param {import('@themost/data').DataEventArgs} event
13
+ * @param {Function} callback
14
+ */
15
+ function afterEvent(event, callback) {
16
+ const { context } = event.model;
17
+ const service = context.application.getService(_WebHookService.WebHookService);
18
+ if (service) {
19
+ service.emit(event);
20
+ }
21
+ return callback();
22
+ }
23
+
24
+ /**
25
+ * A generic web hook for remove operations to any data model
26
+ * @param {import('@themost/data').DataEventArgs} event
27
+ * @param {Function} callback
28
+ */
29
+ function afterRemove(event, callback) {
30
+
31
+ return afterEvent(event, callback);
32
+ }
33
+ //# sourceMappingURL=OnWebHook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnWebHook.js","names":["_WebHookService","require","afterSave","event","callback","afterEvent","context","model","service","application","getService","WebHookService","emit","afterRemove"],"sources":["../../src/listeners/OnWebHook.js"],"sourcesContent":["import {WebHookService} from '../WebHookService';\n\n/**\n * A generic web hook listener for insert or update operations to any data model\n * @param {import('@themost/data').DataEventArgs} event\n * @param {Function} callback\n */\nfunction afterSave(event, callback) {\n return afterEvent(event, callback);\n}\n/**\n * @param {import('@themost/data').DataEventArgs} event\n * @param {Function} callback\n */\nfunction afterEvent(event, callback) {\n const {context} = event.model;\n const service = context.application.getService(WebHookService);\n if (service) {\n service.emit(event);\n }\n return callback();\n}\n\n/**\n * A generic web hook for remove operations to any data model\n * @param {import('@themost/data').DataEventArgs} event\n * @param {Function} callback\n */\nfunction afterRemove(event, callback) {\n\n return afterEvent(event, callback);\n}\n\nexport {\n afterSave,\n afterRemove\n}"],"mappings":"2IAAA,IAAAA,eAAA,GAAAC,OAAA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAASC,SAASA,CAACC,KAAK,EAAEC,QAAQ,EAAE;EAChC,OAAOC,UAAU,CAACF,KAAK,EAAEC,QAAQ,CAAC;AACtC;AACA;AACA;AACA;AACA;AACA,SAASC,UAAUA,CAACF,KAAK,EAAEC,QAAQ,EAAE;EACjC,MAAM,EAACE,OAAO,EAAC,GAAGH,KAAK,CAACI,KAAK;EAC7B,MAAMC,OAAO,GAAGF,OAAO,CAACG,WAAW,CAACC,UAAU,CAACC,8BAAc,CAAC;EAC9D,IAAIH,OAAO,EAAE;IACTA,OAAO,CAACI,IAAI,CAACT,KAAK,CAAC;EACvB;EACA,OAAOC,QAAQ,CAAC,CAAC;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA,SAASS,WAAWA,CAACV,KAAK,EAAEC,QAAQ,EAAE;;EAElC,OAAOC,UAAU,CAACF,KAAK,EAAEC,QAAQ,CAAC;AACtC","ignoreList":[]}
@@ -0,0 +1,53 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.afterSave = afterSave;var _data = require("@themost/data");
2
+ var _path = _interopRequireDefault(require("path"));function _interopRequireDefault(e) {return e && e.__esModule ? e : { default: e };}
3
+ /**
4
+ * After save listener for OneWebHookAction
5
+ * @param {import('@themost/data').DataEventArgs} event
6
+ * @param {Function} callback
7
+ */
8
+ function afterSave(event, callback) {
9
+ if (event.state === _data.DataObjectState.Insert || event.state === _data.DataObjectState.Update) {
10
+ // change the underlying model definition
11
+ const { context } = event.model;
12
+ const schemaLoader = context.getConfiguration().getStrategy(_data.SchemaLoaderStrategy);
13
+ const { about } = event.target;
14
+ if (about) {
15
+ /**
16
+ * @type {import('@themost/common').DataModelProperties}
17
+ */
18
+ const schema = schemaLoader.getModelDefinition(about);
19
+ if (schema) {
20
+ // try to find of previous state listener should be included in the list of event listeners
21
+ schema.eventListeners = schema.eventListeners || [];
22
+ const index = schema.eventListeners.findIndex((item) => {
23
+ return item.type === '@themost/data#previous-state-listener';
24
+ });
25
+ if (index < 0) {
26
+ // insert previous state listener at the beginning of the list
27
+ schema.eventListeners.unshift({
28
+ type: '@themost/data/previous-state-listener'
29
+ });
30
+ }
31
+ const type = _path.default.resolve(__dirname, './OnWebHook');
32
+ const id = '@universis/webhooks/listeners/OnWebHook';
33
+ // try to find if web hook listener should be included in the list of event listeners
34
+ const webHookIndex = schema.eventListeners.findIndex((item) => {
35
+ return item['@id'] === id;
36
+ });
37
+ if (webHookIndex < 0) {
38
+ // add web hook listener at the end of the list
39
+ schema.eventListeners.push({
40
+ '@id': id,
41
+ type
42
+ });
43
+ }
44
+ const service = context.application.getService(function WebHookService() {});
45
+ service.logger.info(`A new web hook action with name "${event.target.name || 'unknown'}" has been registered for model "${about}"`);
46
+ // reset model definition
47
+ schemaLoader.setModelDefinition(schema);
48
+ }
49
+ }
50
+ return callback();
51
+ }
52
+ }
53
+ //# sourceMappingURL=OnWebHookAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnWebHookAction.js","names":["_data","require","_path","_interopRequireDefault","e","__esModule","default","afterSave","event","callback","state","DataObjectState","Insert","Update","context","model","schemaLoader","getConfiguration","getStrategy","SchemaLoaderStrategy","about","target","schema","getModelDefinition","eventListeners","index","findIndex","item","type","unshift","path","resolve","__dirname","id","webHookIndex","push","service","application","getService","WebHookService","logger","info","name","setModelDefinition"],"sources":["../../src/listeners/OnWebHookAction.js"],"sourcesContent":["import {DataObjectState, SchemaLoaderStrategy} from '@themost/data';\nimport path from 'path';\n/**\n * After save listener for OneWebHookAction\n * @param {import('@themost/data').DataEventArgs} event\n * @param {Function} callback\n */\nfunction afterSave(event, callback) {\n if (event.state === DataObjectState.Insert || event.state === DataObjectState.Update) {\n // change the underlying model definition\n const { context } = event.model;\n const schemaLoader = context.getConfiguration().getStrategy(SchemaLoaderStrategy);\n const { about } = event.target;\n if (about) {\n /**\n * @type {import('@themost/common').DataModelProperties}\n */\n const schema = schemaLoader.getModelDefinition(about);\n if (schema) {\n // try to find of previous state listener should be included in the list of event listeners\n schema.eventListeners = schema.eventListeners || [];\n const index = schema.eventListeners.findIndex((item) => {\n return item.type === '@themost/data#previous-state-listener';\n });\n if (index < 0) {\n // insert previous state listener at the beginning of the list\n schema.eventListeners.unshift({\n type: '@themost/data/previous-state-listener'\n });\n }\n const type = path.resolve(__dirname, './OnWebHook');\n const id = '@universis/webhooks/listeners/OnWebHook';\n // try to find if web hook listener should be included in the list of event listeners\n const webHookIndex = schema.eventListeners.findIndex((item) => {\n return item['@id'] === id;\n });\n if (webHookIndex < 0) {\n // add web hook listener at the end of the list\n schema.eventListeners.push({\n '@id': id,\n type\n });\n }\n const service = context.application.getService(function WebHookService() {});\n service.logger.info(`A new web hook action with name \"${event.target.name || 'unknown'}\" has been registered for model \"${about}\"`);\n // reset model definition\n schemaLoader.setModelDefinition(schema);\n }\n }\n return callback();\n }\n}\n\nexport {\n afterSave\n}"],"mappings":"yGAAA,IAAAA,KAAA,GAAAC,OAAA;AACA,IAAAC,KAAA,GAAAC,sBAAA,CAAAF,OAAA,UAAwB,SAAAE,uBAAAC,CAAA,UAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AACxB;AACA;AACA;AACA;AACA;AACA,SAASG,SAASA,CAACC,KAAK,EAAEC,QAAQ,EAAE;EAChC,IAAID,KAAK,CAACE,KAAK,KAAKC,qBAAe,CAACC,MAAM,IAAIJ,KAAK,CAACE,KAAK,KAAKC,qBAAe,CAACE,MAAM,EAAE;IAClF;IACA,MAAM,EAAEC,OAAO,CAAC,CAAC,GAAGN,KAAK,CAACO,KAAK;IAC/B,MAAMC,YAAY,GAAGF,OAAO,CAACG,gBAAgB,CAAC,CAAC,CAACC,WAAW,CAACC,0BAAoB,CAAC;IACjF,MAAM,EAAEC,KAAK,CAAC,CAAC,GAAGZ,KAAK,CAACa,MAAM;IAC9B,IAAID,KAAK,EAAE;MACP;AACZ;AACA;MACY,MAAME,MAAM,GAAGN,YAAY,CAACO,kBAAkB,CAACH,KAAK,CAAC;MACrD,IAAIE,MAAM,EAAE;QACR;QACAA,MAAM,CAACE,cAAc,GAAGF,MAAM,CAACE,cAAc,IAAI,EAAE;QACnD,MAAMC,KAAK,GAAGH,MAAM,CAACE,cAAc,CAACE,SAAS,CAAC,CAACC,IAAI,KAAK;UACpD,OAAOA,IAAI,CAACC,IAAI,KAAK,uCAAuC;QAChE,CAAC,CAAC;QACF,IAAIH,KAAK,GAAG,CAAC,EAAE;UACX;UACAH,MAAM,CAACE,cAAc,CAACK,OAAO,CAAC;YAC1BD,IAAI,EAAE;UACV,CAAC,CAAC;QACN;QACA,MAAMA,IAAI,GAAGE,aAAI,CAACC,OAAO,CAACC,SAAS,EAAE,aAAa,CAAC;QACnD,MAAMC,EAAE,GAAG,yCAAyC;QACpD;QACA,MAAMC,YAAY,GAAGZ,MAAM,CAACE,cAAc,CAACE,SAAS,CAAC,CAACC,IAAI,KAAK;UAC3D,OAAOA,IAAI,CAAC,KAAK,CAAC,KAAKM,EAAE;QAC7B,CAAC,CAAC;QACF,IAAIC,YAAY,GAAG,CAAC,EAAE;UAClB;UACAZ,MAAM,CAACE,cAAc,CAACW,IAAI,CAAC;YACvB,KAAK,EAAEF,EAAE;YACTL;UACJ,CAAC,CAAC;QACN;QACA,MAAMQ,OAAO,GAAGtB,OAAO,CAACuB,WAAW,CAACC,UAAU,CAAC,SAASC,cAAcA,CAAA,EAAG,CAAC,CAAC,CAAC;QAC5EH,OAAO,CAACI,MAAM,CAACC,IAAI,CAAC,oCAAoCjC,KAAK,CAACa,MAAM,CAACqB,IAAI,IAAI,SAAS,oCAAoCtB,KAAK,GAAG,CAAC;QACnI;QACAJ,YAAY,CAAC2B,kBAAkB,CAACrB,MAAM,CAAC;MAC3C;IACJ;IACA,OAAOb,QAAQ,CAAC,CAAC;EACrB;AACJ","ignoreList":[]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "private": true
3
+ }