@contember/engine-actions 2.1.0-alpha.3 → 2.1.0-alpha.30

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 (251) hide show
  1. package/dist/development/index.cjs +10 -5
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +10 -5
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/development/src/ActionsExecutionContainerHookFactory.cjs +3 -3
  6. package/dist/development/src/ActionsExecutionContainerHookFactory.cjs.map +1 -1
  7. package/dist/development/src/ActionsExecutionContainerHookFactory.js +3 -3
  8. package/dist/development/src/ActionsExecutionContainerHookFactory.js.map +1 -1
  9. package/dist/development/src/authorization/ActionsAuthorizationActions.cjs +2 -0
  10. package/dist/development/src/authorization/ActionsAuthorizationActions.cjs.map +1 -1
  11. package/dist/development/src/authorization/ActionsAuthorizationActions.js +2 -0
  12. package/dist/development/src/authorization/ActionsAuthorizationActions.js.map +1 -1
  13. package/dist/development/src/dispatch/EventsRepository.cjs +17 -4
  14. package/dist/development/src/dispatch/EventsRepository.cjs.map +1 -1
  15. package/dist/development/src/dispatch/EventsRepository.js +17 -4
  16. package/dist/development/src/dispatch/EventsRepository.js.map +1 -1
  17. package/dist/development/src/dispatch/ProjectDispatcher.cjs +2 -2
  18. package/dist/development/src/dispatch/ProjectDispatcher.cjs.map +1 -1
  19. package/dist/development/src/dispatch/ProjectDispatcher.js +1 -1
  20. package/dist/development/src/dispatch/ProjectDispatcher.js.map +1 -1
  21. package/dist/development/src/dispatch/WebhookTargetHandler.cjs +3 -0
  22. package/dist/development/src/dispatch/WebhookTargetHandler.cjs.map +1 -1
  23. package/dist/development/src/dispatch/WebhookTargetHandler.js +3 -0
  24. package/dist/development/src/dispatch/WebhookTargetHandler.js.map +1 -1
  25. package/dist/development/src/graphql/http/ActionsApiMiddlewareFactory.cjs +1 -0
  26. package/dist/development/src/graphql/http/ActionsApiMiddlewareFactory.cjs.map +1 -1
  27. package/dist/development/src/graphql/http/ActionsApiMiddlewareFactory.js +1 -0
  28. package/dist/development/src/graphql/http/ActionsApiMiddlewareFactory.js.map +1 -1
  29. package/dist/development/src/graphql/resolvers/ResolversFactory.cjs +7 -2
  30. package/dist/development/src/graphql/resolvers/ResolversFactory.cjs.map +1 -1
  31. package/dist/development/src/graphql/resolvers/ResolversFactory.js +7 -2
  32. package/dist/development/src/graphql/resolvers/ResolversFactory.js.map +1 -1
  33. package/dist/development/src/graphql/resolvers/mutation/RetryEventMutationResolver.cjs +21 -0
  34. package/dist/development/src/graphql/resolvers/mutation/RetryEventMutationResolver.cjs.map +1 -0
  35. package/dist/development/src/graphql/resolvers/mutation/RetryEventMutationResolver.js +21 -0
  36. package/dist/development/src/graphql/resolvers/mutation/RetryEventMutationResolver.js.map +1 -0
  37. package/dist/development/src/graphql/resolvers/mutation/StopEventMutationResolver.cjs +19 -0
  38. package/dist/development/src/graphql/resolvers/mutation/StopEventMutationResolver.cjs.map +1 -0
  39. package/dist/development/src/graphql/resolvers/mutation/StopEventMutationResolver.js +19 -0
  40. package/dist/development/src/graphql/resolvers/mutation/StopEventMutationResolver.js.map +1 -0
  41. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.cjs +14 -1
  42. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.cjs.map +1 -1
  43. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.js +14 -1
  44. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.js.map +1 -1
  45. package/dist/development/src/graphql/schema/actions.graphql.cjs +18 -4
  46. package/dist/development/src/graphql/schema/actions.graphql.cjs.map +1 -1
  47. package/dist/development/src/graphql/schema/actions.graphql.js +18 -4
  48. package/dist/development/src/graphql/schema/actions.graphql.js.map +1 -1
  49. package/dist/development/src/migrations/2025-05-28-160000-action-event-user.cjs +16 -0
  50. package/dist/development/src/migrations/2025-05-28-160000-action-event-user.cjs.map +1 -0
  51. package/dist/development/src/migrations/2025-05-28-160000-action-event-user.js +17 -0
  52. package/dist/development/src/migrations/2025-05-28-160000-action-event-user.js.map +1 -0
  53. package/dist/development/src/migrations/index.cjs +3 -1
  54. package/dist/development/src/migrations/index.cjs.map +1 -1
  55. package/dist/development/src/migrations/index.js +3 -1
  56. package/dist/development/src/migrations/index.js.map +1 -1
  57. package/dist/development/src/migrations/snapshot.cjs +5 -2
  58. package/dist/development/src/migrations/snapshot.cjs.map +1 -1
  59. package/dist/development/src/migrations/snapshot.js +5 -2
  60. package/dist/development/src/migrations/snapshot.js.map +1 -1
  61. package/dist/development/src/model/EventByIdQuery.cjs +17 -0
  62. package/dist/development/src/model/EventByIdQuery.cjs.map +1 -0
  63. package/dist/development/src/model/EventByIdQuery.js +17 -0
  64. package/dist/development/src/model/EventByIdQuery.js.map +1 -0
  65. package/dist/development/src/triggers/TriggerHandler.cjs +12 -11
  66. package/dist/development/src/triggers/TriggerHandler.cjs.map +1 -1
  67. package/dist/development/src/triggers/TriggerHandler.js +12 -11
  68. package/dist/development/src/triggers/TriggerHandler.js.map +1 -1
  69. package/dist/development/src/triggers/TriggerIndirectChangesFetcher.cjs +44 -2
  70. package/dist/development/src/triggers/TriggerIndirectChangesFetcher.cjs.map +1 -1
  71. package/dist/development/src/triggers/TriggerIndirectChangesFetcher.js +44 -2
  72. package/dist/development/src/triggers/TriggerIndirectChangesFetcher.js.map +1 -1
  73. package/dist/development/src/triggers/TriggerListenersStore.cjs.map +1 -1
  74. package/dist/development/src/triggers/TriggerListenersStore.js.map +1 -1
  75. package/dist/development/src/triggers/TriggerPayloadBuilder.cjs +20 -5
  76. package/dist/development/src/triggers/TriggerPayloadBuilder.cjs.map +1 -1
  77. package/dist/development/src/triggers/TriggerPayloadBuilder.js +20 -5
  78. package/dist/development/src/triggers/TriggerPayloadBuilder.js.map +1 -1
  79. package/dist/development/src/triggers/TriggerPayloadManager.cjs.map +1 -1
  80. package/dist/development/src/triggers/TriggerPayloadManager.js.map +1 -1
  81. package/dist/development/src/triggers/TriggerPayloadPersister.cjs +9 -5
  82. package/dist/development/src/triggers/TriggerPayloadPersister.cjs.map +1 -1
  83. package/dist/development/src/triggers/TriggerPayloadPersister.js +9 -5
  84. package/dist/development/src/triggers/TriggerPayloadPersister.js.map +1 -1
  85. package/dist/development/src/utils/notifyChannel.cjs +9 -0
  86. package/dist/development/src/utils/notifyChannel.cjs.map +1 -0
  87. package/dist/development/src/utils/notifyChannel.js +9 -0
  88. package/dist/development/src/utils/notifyChannel.js.map +1 -0
  89. package/dist/production/index.cjs +10 -5
  90. package/dist/production/index.cjs.map +1 -1
  91. package/dist/production/index.js +10 -5
  92. package/dist/production/index.js.map +1 -1
  93. package/dist/production/src/ActionsExecutionContainerHookFactory.cjs +3 -3
  94. package/dist/production/src/ActionsExecutionContainerHookFactory.cjs.map +1 -1
  95. package/dist/production/src/ActionsExecutionContainerHookFactory.js +3 -3
  96. package/dist/production/src/ActionsExecutionContainerHookFactory.js.map +1 -1
  97. package/dist/production/src/authorization/ActionsAuthorizationActions.cjs +2 -0
  98. package/dist/production/src/authorization/ActionsAuthorizationActions.cjs.map +1 -1
  99. package/dist/production/src/authorization/ActionsAuthorizationActions.js +2 -0
  100. package/dist/production/src/authorization/ActionsAuthorizationActions.js.map +1 -1
  101. package/dist/production/src/dispatch/EventsRepository.cjs +17 -4
  102. package/dist/production/src/dispatch/EventsRepository.cjs.map +1 -1
  103. package/dist/production/src/dispatch/EventsRepository.js +17 -4
  104. package/dist/production/src/dispatch/EventsRepository.js.map +1 -1
  105. package/dist/production/src/dispatch/ProjectDispatcher.cjs +2 -2
  106. package/dist/production/src/dispatch/ProjectDispatcher.cjs.map +1 -1
  107. package/dist/production/src/dispatch/ProjectDispatcher.js +1 -1
  108. package/dist/production/src/dispatch/ProjectDispatcher.js.map +1 -1
  109. package/dist/production/src/dispatch/WebhookTargetHandler.cjs +3 -0
  110. package/dist/production/src/dispatch/WebhookTargetHandler.cjs.map +1 -1
  111. package/dist/production/src/dispatch/WebhookTargetHandler.js +3 -0
  112. package/dist/production/src/dispatch/WebhookTargetHandler.js.map +1 -1
  113. package/dist/production/src/graphql/http/ActionsApiMiddlewareFactory.cjs +1 -0
  114. package/dist/production/src/graphql/http/ActionsApiMiddlewareFactory.cjs.map +1 -1
  115. package/dist/production/src/graphql/http/ActionsApiMiddlewareFactory.js +1 -0
  116. package/dist/production/src/graphql/http/ActionsApiMiddlewareFactory.js.map +1 -1
  117. package/dist/production/src/graphql/resolvers/ResolversFactory.cjs +7 -2
  118. package/dist/production/src/graphql/resolvers/ResolversFactory.cjs.map +1 -1
  119. package/dist/production/src/graphql/resolvers/ResolversFactory.js +7 -2
  120. package/dist/production/src/graphql/resolvers/ResolversFactory.js.map +1 -1
  121. package/dist/production/src/graphql/resolvers/mutation/RetryEventMutationResolver.cjs +21 -0
  122. package/dist/production/src/graphql/resolvers/mutation/RetryEventMutationResolver.cjs.map +1 -0
  123. package/dist/production/src/graphql/resolvers/mutation/RetryEventMutationResolver.js +21 -0
  124. package/dist/production/src/graphql/resolvers/mutation/RetryEventMutationResolver.js.map +1 -0
  125. package/dist/production/src/graphql/resolvers/mutation/StopEventMutationResolver.cjs +19 -0
  126. package/dist/production/src/graphql/resolvers/mutation/StopEventMutationResolver.cjs.map +1 -0
  127. package/dist/production/src/graphql/resolvers/mutation/StopEventMutationResolver.js +19 -0
  128. package/dist/production/src/graphql/resolvers/mutation/StopEventMutationResolver.js.map +1 -0
  129. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.cjs +14 -1
  130. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.cjs.map +1 -1
  131. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.js +14 -1
  132. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.js.map +1 -1
  133. package/dist/production/src/graphql/schema/actions.graphql.cjs +18 -4
  134. package/dist/production/src/graphql/schema/actions.graphql.cjs.map +1 -1
  135. package/dist/production/src/graphql/schema/actions.graphql.js +18 -4
  136. package/dist/production/src/graphql/schema/actions.graphql.js.map +1 -1
  137. package/dist/production/src/migrations/2025-05-28-160000-action-event-user.cjs +16 -0
  138. package/dist/production/src/migrations/2025-05-28-160000-action-event-user.cjs.map +1 -0
  139. package/dist/production/src/migrations/2025-05-28-160000-action-event-user.js +17 -0
  140. package/dist/production/src/migrations/2025-05-28-160000-action-event-user.js.map +1 -0
  141. package/dist/production/src/migrations/index.cjs +3 -1
  142. package/dist/production/src/migrations/index.cjs.map +1 -1
  143. package/dist/production/src/migrations/index.js +3 -1
  144. package/dist/production/src/migrations/index.js.map +1 -1
  145. package/dist/production/src/migrations/snapshot.cjs +5 -2
  146. package/dist/production/src/migrations/snapshot.cjs.map +1 -1
  147. package/dist/production/src/migrations/snapshot.js +5 -2
  148. package/dist/production/src/migrations/snapshot.js.map +1 -1
  149. package/dist/production/src/model/EventByIdQuery.cjs +17 -0
  150. package/dist/production/src/model/EventByIdQuery.cjs.map +1 -0
  151. package/dist/production/src/model/EventByIdQuery.js +17 -0
  152. package/dist/production/src/model/EventByIdQuery.js.map +1 -0
  153. package/dist/production/src/triggers/TriggerHandler.cjs +12 -11
  154. package/dist/production/src/triggers/TriggerHandler.cjs.map +1 -1
  155. package/dist/production/src/triggers/TriggerHandler.js +12 -11
  156. package/dist/production/src/triggers/TriggerHandler.js.map +1 -1
  157. package/dist/production/src/triggers/TriggerIndirectChangesFetcher.cjs +44 -2
  158. package/dist/production/src/triggers/TriggerIndirectChangesFetcher.cjs.map +1 -1
  159. package/dist/production/src/triggers/TriggerIndirectChangesFetcher.js +44 -2
  160. package/dist/production/src/triggers/TriggerIndirectChangesFetcher.js.map +1 -1
  161. package/dist/production/src/triggers/TriggerListenersStore.cjs.map +1 -1
  162. package/dist/production/src/triggers/TriggerListenersStore.js.map +1 -1
  163. package/dist/production/src/triggers/TriggerPayloadBuilder.cjs +20 -5
  164. package/dist/production/src/triggers/TriggerPayloadBuilder.cjs.map +1 -1
  165. package/dist/production/src/triggers/TriggerPayloadBuilder.js +20 -5
  166. package/dist/production/src/triggers/TriggerPayloadBuilder.js.map +1 -1
  167. package/dist/production/src/triggers/TriggerPayloadManager.cjs.map +1 -1
  168. package/dist/production/src/triggers/TriggerPayloadManager.js.map +1 -1
  169. package/dist/production/src/triggers/TriggerPayloadPersister.cjs +9 -5
  170. package/dist/production/src/triggers/TriggerPayloadPersister.cjs.map +1 -1
  171. package/dist/production/src/triggers/TriggerPayloadPersister.js +9 -5
  172. package/dist/production/src/triggers/TriggerPayloadPersister.js.map +1 -1
  173. package/dist/production/src/utils/notifyChannel.cjs +9 -0
  174. package/dist/production/src/utils/notifyChannel.cjs.map +1 -0
  175. package/dist/production/src/utils/notifyChannel.js +9 -0
  176. package/dist/production/src/utils/notifyChannel.js.map +1 -0
  177. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  178. package/dist/types/authorization/ActionsAuthorizationActions.d.ts +10 -0
  179. package/dist/types/authorization/ActionsAuthorizationActions.d.ts.map +1 -1
  180. package/dist/types/dispatch/EventsRepository.d.ts +2 -1
  181. package/dist/types/dispatch/EventsRepository.d.ts.map +1 -1
  182. package/dist/types/dispatch/WebhookTargetHandler.d.ts.map +1 -1
  183. package/dist/types/graphql/http/ActionsApiMiddlewareFactory.d.ts.map +1 -1
  184. package/dist/types/graphql/resolvers/ActionsContext.d.ts +3 -0
  185. package/dist/types/graphql/resolvers/ActionsContext.d.ts.map +1 -1
  186. package/dist/types/graphql/resolvers/ResolversFactory.d.ts +4 -2
  187. package/dist/types/graphql/resolvers/ResolversFactory.d.ts.map +1 -1
  188. package/dist/types/graphql/resolvers/mutation/RetryEventMutationResolver.d.ts +11 -0
  189. package/dist/types/graphql/resolvers/mutation/RetryEventMutationResolver.d.ts.map +1 -0
  190. package/dist/types/graphql/resolvers/mutation/StopEventMutationResolver.d.ts +11 -0
  191. package/dist/types/graphql/resolvers/mutation/StopEventMutationResolver.d.ts.map +1 -0
  192. package/dist/types/graphql/resolvers/mutation/index.d.ts +2 -0
  193. package/dist/types/graphql/resolvers/mutation/index.d.ts.map +1 -1
  194. package/dist/types/graphql/resolvers/query/EventsQueryResolver.d.ts +3 -0
  195. package/dist/types/graphql/resolvers/query/EventsQueryResolver.d.ts.map +1 -1
  196. package/dist/types/graphql/schema/actions.graphql.d.ts.map +1 -1
  197. package/dist/types/graphql/schema/index.d.ts +45 -2
  198. package/dist/types/graphql/schema/index.d.ts.map +1 -1
  199. package/dist/types/index.d.ts.map +1 -1
  200. package/dist/types/migrations/2025-05-28-160000-action-event-user.d.ts +3 -0
  201. package/dist/types/migrations/2025-05-28-160000-action-event-user.d.ts.map +1 -0
  202. package/dist/types/migrations/index.d.ts.map +1 -1
  203. package/dist/types/migrations/snapshot.d.ts.map +1 -1
  204. package/dist/types/model/EventByIdQuery.d.ts +8 -0
  205. package/dist/types/model/EventByIdQuery.d.ts.map +1 -0
  206. package/dist/types/model/types.d.ts +3 -0
  207. package/dist/types/model/types.d.ts.map +1 -1
  208. package/dist/types/triggers/TriggerHandler.d.ts.map +1 -1
  209. package/dist/types/triggers/TriggerIndirectChangesFetcher.d.ts +11 -3
  210. package/dist/types/triggers/TriggerIndirectChangesFetcher.d.ts.map +1 -1
  211. package/dist/types/triggers/TriggerListenersStore.d.ts +2 -2
  212. package/dist/types/triggers/TriggerListenersStore.d.ts.map +1 -1
  213. package/dist/types/triggers/TriggerPayloadBuilder.d.ts.map +1 -1
  214. package/dist/types/triggers/TriggerPayloadManager.d.ts +2 -1
  215. package/dist/types/triggers/TriggerPayloadManager.d.ts.map +1 -1
  216. package/dist/types/triggers/TriggerPayloadPersister.d.ts +7 -3
  217. package/dist/types/triggers/TriggerPayloadPersister.d.ts.map +1 -1
  218. package/dist/types/tsconfig.tsbuildinfo +1 -1
  219. package/dist/types/utils/notifyChannel.d.ts +4 -0
  220. package/dist/types/utils/notifyChannel.d.ts.map +1 -0
  221. package/graphql.codegen.yml +2 -2
  222. package/package.json +15 -15
  223. package/src/ActionsExecutionContainerHookFactory.ts +3 -3
  224. package/src/authorization/ActionsAuthorizationActions.ts +2 -0
  225. package/src/dispatch/EventsRepository.ts +24 -5
  226. package/src/dispatch/ProjectDispatcher.ts +1 -1
  227. package/src/dispatch/WebhookTargetHandler.ts +3 -0
  228. package/src/graphql/http/ActionsApiMiddlewareFactory.ts +1 -0
  229. package/src/graphql/resolvers/ActionsContext.ts +1 -0
  230. package/src/graphql/resolvers/ResolversFactory.ts +6 -1
  231. package/src/graphql/resolvers/mutation/RetryEventMutationResolver.ts +22 -0
  232. package/src/graphql/resolvers/mutation/StopEventMutationResolver.ts +19 -0
  233. package/src/graphql/resolvers/mutation/index.ts +2 -0
  234. package/src/graphql/resolvers/query/EventsQueryResolver.ts +14 -0
  235. package/src/graphql/schema/actions.graphql.ts +18 -4
  236. package/src/graphql/schema/index.ts +54 -1
  237. package/src/index.ts +9 -5
  238. package/src/migrations/2025-05-28-160000-action-event-user.ts +16 -0
  239. package/src/migrations/index.ts +2 -0
  240. package/src/migrations/snapshot.ts +5 -2
  241. package/src/model/EventByIdQuery.ts +21 -0
  242. package/src/model/types.ts +3 -0
  243. package/src/triggers/TriggerHandler.ts +12 -11
  244. package/src/triggers/TriggerIndirectChangesFetcher.ts +62 -3
  245. package/src/triggers/TriggerListenersStore.ts +2 -2
  246. package/src/triggers/TriggerPayloadBuilder.ts +18 -1
  247. package/src/triggers/TriggerPayloadManager.ts +2 -1
  248. package/src/triggers/TriggerPayloadPersister.ts +9 -3
  249. package/src/utils/notifyChannel.ts +6 -0
  250. package/tests/cases/unit/generator.test.ts +1 -1
  251. package/tests/cases/unit/webhookHandler.test.ts +9 -0
@@ -0,0 +1,21 @@
1
+ import { DatabaseQuery, DatabaseQueryable, SelectBuilder } from '@contember/database'
2
+ import { EventRow } from './types'
3
+
4
+ export class EventByIdQuery extends DatabaseQuery<EventRow | null> {
5
+ constructor(
6
+ private readonly id: string,
7
+ ) {
8
+ super()
9
+ }
10
+
11
+ async fetch(queryable: DatabaseQueryable): Promise<EventRow | null> {
12
+ const result = await SelectBuilder.create<EventRow>()
13
+ .from('actions_event')
14
+ .select('*')
15
+ .where({
16
+ id: this.id,
17
+ })
18
+ .getResult(queryable.db)
19
+ return this.fetchOneOrNull(result)
20
+ }
21
+ }
@@ -14,6 +14,9 @@ export type EventRow = {
14
14
  target: string
15
15
  priority: number
16
16
  trigger: string
17
+ identity_id: string | null
18
+ ip_address: string | null
19
+ user_agent: string | null
17
20
  payload: ActionsPayload.AnyEventPayload
18
21
  log: any[]
19
22
  }
@@ -71,28 +71,28 @@ export class TriggerHandler {
71
71
 
72
72
  private async directUpdateHandler(event: AfterUpdateEvent) {
73
73
  const updateListeners = this.listenersStore.getUpdateListeners(event.entity.name)
74
- updateListeners.map(listener => {
74
+ await Promise.all(updateListeners.map(listener => {
75
75
  if (event.data.some(it => listener.fields.has(it.fieldName) && it.value !== it.old)) {
76
- this.payloadManager.add({
76
+ return this.payloadManager.add({
77
77
  listener,
78
78
  entity: event.entity,
79
79
  primary: event.id,
80
80
  cause: event,
81
81
  })
82
82
  }
83
- })
83
+ }))
84
84
  }
85
85
 
86
86
  private async directCreateHandler(event: AfterInsertEvent) {
87
87
  const createListeners = this.listenersStore.getCreateListener(event.entity.name)
88
- createListeners.map(listener => {
89
- this.payloadManager.add({
88
+ await Promise.all(createListeners.map(listener => {
89
+ return this.payloadManager.add({
90
90
  listener,
91
91
  entity: event.entity,
92
92
  primary: event.id,
93
93
  cause: event,
94
94
  })
95
- })
95
+ }))
96
96
  }
97
97
 
98
98
 
@@ -103,7 +103,7 @@ export class TriggerHandler {
103
103
  private async indirectChangesEntityHandler(event: BeforeDeleteEvent | AfterInsertEvent) {
104
104
  //
105
105
  const indirectEntityListeners = this.listenersStore.getIndirectListeners(event.entity.name)
106
- const promises = indirectEntityListeners.map(listener => this.collectDeepChanges(event, listener, {
106
+ const promises = indirectEntityListeners.map(listener => this.collectDeepChanges(event, listener, {
107
107
  [event.entity.primary]: { eq: event.id },
108
108
  }))
109
109
  await Promise.all(promises)
@@ -149,13 +149,14 @@ export class TriggerHandler {
149
149
  where: Input.Where,
150
150
  ) {
151
151
  const result = await this.changesFetcher.fetch(listener, where)
152
- for (const row of result) {
153
- this.payloadManager.add({
152
+ await Promise.all(result.map(row => {
153
+ return this.payloadManager.add({
154
154
  listener,
155
155
  entity: listener.rootEntity,
156
- primary: row,
156
+ primary: row.id,
157
157
  cause,
158
+ nodes: row.nodes,
158
159
  })
159
- }
160
+ }))
160
161
  }
161
162
  }
@@ -1,12 +1,21 @@
1
1
  import { Mapper, PathFactory, WhereBuilder } from '@contember/engine-content-api'
2
2
  import { IndirectListener, JunctionListener } from './TriggerListenersStore'
3
3
  import { SelectBuilder } from '@contember/database'
4
- import { Input } from '@contember/schema'
4
+ import { ActionsPayload, Input, Model, Schema } from '@contember/schema'
5
+ import { JoinBuilder } from '@contember/engine-content-api'
6
+ import { getTargetEntity } from '@contember/schema-utils'
7
+
8
+ export type TriggerIndirectChangesFetcherResult = {
9
+ id: Input.PrimaryValue
10
+ nodes?: ActionsPayload.EntityEventPathNode[]
11
+ }[]
5
12
 
6
13
  export class TriggerIndirectChangesFetcher {
7
14
  constructor(
15
+ private readonly model: Model.Schema,
8
16
  private readonly mapper: Mapper,
9
17
  private readonly whereBuilder: WhereBuilder,
18
+ private readonly joinBuilder: JoinBuilder,
10
19
  private readonly pathFactory: PathFactory,
11
20
  ) {
12
21
  }
@@ -14,7 +23,11 @@ export class TriggerIndirectChangesFetcher {
14
23
  public async fetch(
15
24
  listener: IndirectListener | JunctionListener,
16
25
  where: Input.Where,
17
- ): Promise<Input.PrimaryValue[]> {
26
+ ): Promise<TriggerIndirectChangesFetcherResult> {
27
+ if (listener.trigger.withNodes) {
28
+ return this.fetchWithNodes(listener, where)
29
+ }
30
+
18
31
  for (let i = listener.path.length - 1; i >= 0; i--) {
19
32
  where = { [listener.path[i]]: where }
20
33
  }
@@ -24,7 +37,53 @@ export class TriggerIndirectChangesFetcher {
24
37
  const path = this.pathFactory.create([])
25
38
  const qbWithWhere = this.whereBuilder.build(qb, listener.rootEntity, path, where)
26
39
 
27
- return (await qbWithWhere.getResult(this.mapper.db)).map(it => it.id)
40
+ return (await qbWithWhere.getResult(this.mapper.db))
28
41
  }
29
42
 
43
+ private async fetchWithNodes(
44
+ listener: IndirectListener | JunctionListener,
45
+ where: Input.Where,
46
+ ): Promise<TriggerIndirectChangesFetcherResult> {
47
+ const basePath = this.pathFactory.create([])
48
+ let path = basePath
49
+ let entity = listener.rootEntity
50
+ let qb = SelectBuilder.create()
51
+ .from(entity.tableName, path.alias)
52
+ .select([path.alias, entity.primaryColumn], path.for(entity.primary).alias)
53
+
54
+ for (let i = 0; i < listener.path.length; i++) {
55
+ const relationName = listener.path[i]
56
+ path = path.for(relationName)
57
+ const targetEntity = getTargetEntity(this.model, entity, relationName)
58
+ if (!targetEntity) {
59
+ throw new Error(`Target entity for relation ${entity.name}::${relationName} not found`)
60
+ }
61
+ qb = this.joinBuilder.join(qb, path, entity, relationName)
62
+
63
+ entity = targetEntity
64
+ qb = qb.select([path.alias, targetEntity.primaryColumn], path.for(targetEntity.primary).alias)
65
+ }
66
+
67
+ const qbWithWhere = this.whereBuilder.build(qb, entity, path, where)
68
+
69
+ const result = await qbWithWhere.getResult(this.mapper.db)
70
+
71
+ return result.map(row => {
72
+ const nodes: ActionsPayload.EntityEventPathNode[] = []
73
+ let entity = listener.rootEntity
74
+ let path = basePath
75
+ const id = row[path.for(entity.primary).alias]
76
+ for (let i = 0; i < listener.path.length; i++) {
77
+ const relationName = listener.path[i]
78
+ const targetEntity = getTargetEntity(this.model, entity, relationName)
79
+ if (!targetEntity) {
80
+ throw new Error(`Target entity for relation ${entity.name}::${relationName} not found`)
81
+ }
82
+ path = path.for(relationName)
83
+ nodes.push({ relation: relationName, entity: targetEntity.name, id: row[path.for(targetEntity.primary).alias] })
84
+ entity = targetEntity
85
+ }
86
+ return { id, nodes }
87
+ })
88
+ }
30
89
  }
@@ -3,7 +3,7 @@ import { TriggerListeners } from './TriggerListeners'
3
3
 
4
4
  export interface IndirectListener {
5
5
  type: 'indirect'
6
- trigger: Actions.AnyTrigger
6
+ trigger: Actions.WatchTrigger
7
7
  rootEntity: Model.Entity
8
8
  fields: Set<string>
9
9
  relations: Set<string>
@@ -12,7 +12,7 @@ export interface IndirectListener {
12
12
 
13
13
  export interface JunctionListener {
14
14
  type: 'junction'
15
- trigger: Actions.AnyTrigger
15
+ trigger: Actions.WatchTrigger
16
16
  rootEntity: Model.Entity
17
17
  path: string[]
18
18
  context: {
@@ -51,6 +51,19 @@ export class TriggerPayloadBuilder {
51
51
  }
52
52
  const payloads: ActionsPayload.WatchEventPayload[] = []
53
53
  for (const eventsByPrimary of Object.values(byPrimary)) {
54
+ const baseEvents: ActionsPayload.BaseEventPayload[] = []
55
+
56
+ const existingEvents = new Set<string>()
57
+ for (const event of eventsByPrimary.events) {
58
+ const baseEvent = this.buildBaseEventPayloads(event)
59
+ const stringRepresentation = JSON.stringify(baseEvent)
60
+ if (existingEvents.has(stringRepresentation)) {
61
+ continue
62
+ }
63
+ existingEvents.add(stringRepresentation)
64
+ baseEvents.push(baseEvent)
65
+ }
66
+
54
67
  payloads.push({
55
68
  operation: 'watch',
56
69
  trigger: events[0].listener.trigger.name,
@@ -58,7 +71,7 @@ export class TriggerPayloadBuilder {
58
71
  id: eventsByPrimary.primary,
59
72
  selection: eventsByPrimary.events.find(it => it.selection)?.selection
60
73
  ?? selections[eventsByPrimary.primary],
61
- events: eventsByPrimary.events.map(it => this.buildBaseEventPayloads(it)),
74
+ events: baseEvents,
62
75
  })
63
76
  }
64
77
  return payloads
@@ -74,6 +87,7 @@ export class TriggerPayloadBuilder {
74
87
  selection,
75
88
  values: Object.fromEntries(event.cause.data.map(it => [it.fieldName, it.value])),
76
89
  path: 'path' in event.listener ? event.listener.path : undefined,
90
+ nodes: event.nodes,
77
91
  }
78
92
  case 'AfterUpdateEvent':
79
93
  case 'BeforeUpdateEvent':
@@ -89,6 +103,7 @@ export class TriggerPayloadBuilder {
89
103
  values: Object.fromEntries(event.cause.data.map(it => [it.fieldName, it.value])),
90
104
  path: 'path' in event.listener ? event.listener.path : undefined,
91
105
  old: Object.fromEntries(afterEvent.data.map(it => [it.fieldName, it.old])),
106
+ nodes: event.nodes,
92
107
  }
93
108
  case 'BeforeDeleteEvent':
94
109
  return {
@@ -97,6 +112,7 @@ export class TriggerPayloadBuilder {
97
112
  id: event.cause.id,
98
113
  selection,
99
114
  path: 'path' in event.listener ? event.listener.path : undefined,
115
+ nodes: event.nodes,
100
116
  }
101
117
  case 'AfterJunctionUpdateEvent':
102
118
  if (event.listener.type !== 'junction') {
@@ -112,6 +128,7 @@ export class TriggerPayloadBuilder {
112
128
  id,
113
129
  inverseId,
114
130
  path: 'path' in event.listener ? event.listener.path : undefined,
131
+ nodes: event.nodes,
115
132
  }
116
133
  default:
117
134
  assertNever(event.cause, it => it.type)
@@ -1,4 +1,4 @@
1
- import { Actions, Input, Model } from '@contember/schema'
1
+ import { Actions, ActionsPayload, Input, Model } from '@contember/schema'
2
2
  import { AnyListener } from './TriggerListenersStore'
3
3
  import { EventCause } from './TriggerHandler'
4
4
  import { TriggerPayloadBuilder } from './TriggerPayloadBuilder'
@@ -11,6 +11,7 @@ export interface FiredEvent {
11
11
  entity: Model.Entity
12
12
  primary: Input.PrimaryValue
13
13
  selection?: any
14
+ nodes?: ActionsPayload.EntityEventPathNode[]
14
15
  }
15
16
 
16
17
  export class TriggerPayloadManager {
@@ -2,8 +2,9 @@ import { Client, InsertBuilder } from '@contember/database'
2
2
  import { Mapper } from '@contember/engine-content-api'
3
3
  import { Actions, ActionsPayload } from '@contember/schema'
4
4
  import { EventRow } from '../model/types'
5
+ import { notify } from '../utils/notifyChannel'
6
+
5
7
 
6
- export const NOTIFY_CHANNEL_NAME = 'actions_event'
7
8
  type EventRowToInsert = Omit<EventRow, 'created_at' | 'visible_at' | 'last_state_change' | 'log'> & {
8
9
  created_at: string | Date
9
10
  visible_at: string | Date
@@ -17,7 +18,9 @@ export class TriggerPayloadPersister {
17
18
  private readonly providers: { uuid: () => string },
18
19
  private readonly projectSlug: string,
19
20
  private readonly stageId: string,
20
- private readonly schemaId?: number,
21
+ private readonly schemaId: number | undefined,
22
+ private readonly identityId: string,
23
+ private readonly userInfo: { ipAddress: string | null; userAgent: string | null },
21
24
  ) {
22
25
  }
23
26
 
@@ -45,10 +48,13 @@ export class TriggerPayloadPersister {
45
48
  payload: it,
46
49
  resolved_at: null,
47
50
  last_state_change: 'now',
51
+ identity_id: this.identityId,
52
+ ip_address: this.userInfo.ipAddress,
53
+ user_agent: this.userInfo.userAgent,
48
54
  })))
49
55
  .execute(this.client)
50
56
  }
51
57
 
52
- await this.client.query('SELECT pg_notify(?, ?)', [NOTIFY_CHANNEL_NAME, this.projectSlug])
58
+ await notify(this.client, this.projectSlug)
53
59
  }
54
60
  }
@@ -0,0 +1,6 @@
1
+ import { Client } from '@contember/database'
2
+
3
+ export const NOTIFY_CHANNEL_NAME = 'actions_event'
4
+ export const notify = async (db: Client, projectSlug: string) => {
5
+ await db.query('SELECT pg_notify(?, ?)', [NOTIFY_CHANNEL_NAME, projectSlug])
6
+ }
@@ -8,7 +8,7 @@ const assert = {
8
8
  equal: (a: any, b: any) => expect(a).toEqual(b),
9
9
  deepStrictEqual: (a: any, b: any) => expect(a).toStrictEqual(b),
10
10
  }
11
- const createTrigger = (watchNode: Actions.SelectionNode): Actions.AnyTrigger => ({
11
+ const createTrigger = (watchNode: Actions.SelectionNode): Actions.WatchTrigger => ({
12
12
  type: 'watch',
13
13
  entity: 'Author',
14
14
  name: 'author_trigger',
@@ -29,6 +29,9 @@ const createTestEvent = (i = 0, row: Partial<EventRow> = {}): EventRow => ({
29
29
  priority: 1,
30
30
  schema_id: 1,
31
31
  state: 'created',
32
+ identity_id: testUuid(i * 10 + 4),
33
+ ip_address: '127.0.0.1',
34
+ user_agent: 'test-agent',
32
35
  ...row,
33
36
  })
34
37
 
@@ -56,6 +59,9 @@ describe('webhook request', () => {
56
59
  meta: {
57
60
  eventId: testUuid(1),
58
61
  transactionId: testUuid(2),
62
+ identityId: testUuid(4),
63
+ ipAddress: '127.0.0.1',
64
+ userAgent: 'test-agent',
59
65
  createdAt: now.toISOString(),
60
66
  lastStateChange: now.toISOString(),
61
67
  numRetries: 0,
@@ -104,6 +110,9 @@ describe('webhook request', () => {
104
110
  meta: {
105
111
  eventId: testUuid(1),
106
112
  transactionId: testUuid(2),
113
+ identityId: testUuid(4),
114
+ ipAddress: '127.0.0.1',
115
+ userAgent: 'test-agent',
107
116
  createdAt: now.toISOString(),
108
117
  lastStateChange: now.toISOString(),
109
118
  numRetries: 0,