@webiny/tasks 6.3.0 → 6.4.0-beta.0

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 (203) hide show
  1. package/context.js +31 -43
  2. package/context.js.map +1 -1
  3. package/crud/TaskLogPrivateModel.js +33 -27
  4. package/crud/TaskLogPrivateModel.js.map +1 -1
  5. package/crud/TaskPrivateModel.js +48 -39
  6. package/crud/TaskPrivateModel.js.map +1 -1
  7. package/crud/cleanupTaskSubtree.js +55 -69
  8. package/crud/cleanupTaskSubtree.js.map +1 -1
  9. package/crud/crud.tasks.js +289 -352
  10. package/crud/crud.tasks.js.map +1 -1
  11. package/crud/definition.tasks.js +13 -16
  12. package/crud/definition.tasks.js.map +1 -1
  13. package/crud/service.tasks.js +119 -155
  14. package/crud/service.tasks.js.map +1 -1
  15. package/decorators/RunnableTaskDecorator.js +61 -77
  16. package/decorators/RunnableTaskDecorator.js.map +1 -1
  17. package/decorators/SelfCleaningTaskDecorator.js +75 -89
  18. package/decorators/SelfCleaningTaskDecorator.js.map +1 -1
  19. package/domain/errors.js +35 -39
  20. package/domain/errors.js.map +1 -1
  21. package/events/TaskAfterCreateEvent.js +8 -5
  22. package/events/TaskAfterCreateEvent.js.map +1 -1
  23. package/events/TaskAfterDeleteEvent.js +8 -5
  24. package/events/TaskAfterDeleteEvent.js.map +1 -1
  25. package/events/TaskAfterUpdateEvent.js +8 -5
  26. package/events/TaskAfterUpdateEvent.js.map +1 -1
  27. package/events/TaskBeforeCreateEvent.js +8 -5
  28. package/events/TaskBeforeCreateEvent.js.map +1 -1
  29. package/events/TaskBeforeDeleteEvent.js +8 -5
  30. package/events/TaskBeforeDeleteEvent.js.map +1 -1
  31. package/events/TaskBeforeUpdateEvent.js +8 -5
  32. package/events/TaskBeforeUpdateEvent.js.map +1 -1
  33. package/events/abstractions.js +7 -36
  34. package/events/abstractions.js.map +1 -1
  35. package/events/index.js +0 -2
  36. package/features/AbortTask/AbortTaskUseCase.js +9 -8
  37. package/features/AbortTask/AbortTaskUseCase.js.map +1 -1
  38. package/features/AbortTask/abstractions.js +2 -1
  39. package/features/AbortTask/abstractions.js.map +1 -1
  40. package/features/AbortTask/feature.js +6 -5
  41. package/features/AbortTask/feature.js.map +1 -1
  42. package/features/AbortTask/index.js +0 -2
  43. package/features/CleanupTaskSubtree/CleanupTaskSubtreeUseCase.js +8 -7
  44. package/features/CleanupTaskSubtree/CleanupTaskSubtreeUseCase.js.map +1 -1
  45. package/features/CleanupTaskSubtree/abstractions.js +2 -1
  46. package/features/CleanupTaskSubtree/abstractions.js.map +1 -1
  47. package/features/CleanupTaskSubtree/index.js +0 -2
  48. package/features/GetTask/GetTaskUseCase.js +8 -7
  49. package/features/GetTask/GetTaskUseCase.js.map +1 -1
  50. package/features/GetTask/abstractions.js +2 -1
  51. package/features/GetTask/abstractions.js.map +1 -1
  52. package/features/GetTask/feature.js +6 -5
  53. package/features/GetTask/feature.js.map +1 -1
  54. package/features/GetTask/index.js +0 -2
  55. package/features/GetTaskDefinition/GetTaskDefinitionUseCase.js +18 -16
  56. package/features/GetTaskDefinition/GetTaskDefinitionUseCase.js.map +1 -1
  57. package/features/GetTaskDefinition/abstractions.js +2 -1
  58. package/features/GetTaskDefinition/abstractions.js.map +1 -1
  59. package/features/GetTaskDefinition/feature.js +6 -5
  60. package/features/GetTaskDefinition/feature.js.map +1 -1
  61. package/features/GetTaskDefinition/index.js +0 -2
  62. package/features/ListTaskDefinitions/ListTaskDefinitionsUseCase.js +18 -12
  63. package/features/ListTaskDefinitions/ListTaskDefinitionsUseCase.js.map +1 -1
  64. package/features/ListTaskDefinitions/abstractions.js +2 -1
  65. package/features/ListTaskDefinitions/abstractions.js.map +1 -1
  66. package/features/ListTaskDefinitions/feature.js +6 -5
  67. package/features/ListTaskDefinitions/feature.js.map +1 -1
  68. package/features/ListTaskDefinitions/index.js +0 -2
  69. package/features/ListTasks/ListTasksUseCase.js +8 -7
  70. package/features/ListTasks/ListTasksUseCase.js.map +1 -1
  71. package/features/ListTasks/abstractions.js +2 -1
  72. package/features/ListTasks/abstractions.js.map +1 -1
  73. package/features/ListTasks/feature.js +6 -5
  74. package/features/ListTasks/feature.js.map +1 -1
  75. package/features/ListTasks/index.js +0 -2
  76. package/features/TaskController/TaskController.js +60 -60
  77. package/features/TaskController/TaskController.js.map +1 -1
  78. package/features/TaskController/augmentation.js +0 -3
  79. package/features/TaskController/index.js +0 -5
  80. package/features/TaskExecutionContext/TaskExecutionContext.js +38 -45
  81. package/features/TaskExecutionContext/TaskExecutionContext.js.map +1 -1
  82. package/features/TaskExecutionContext/abstractions.js +2 -10
  83. package/features/TaskExecutionContext/abstractions.js.map +1 -1
  84. package/features/TaskExecutionContext/feature.js +6 -5
  85. package/features/TaskExecutionContext/feature.js.map +1 -1
  86. package/features/TaskExecutionContext/index.js +0 -2
  87. package/features/TriggerTask/TriggerTaskUseCase.js +9 -8
  88. package/features/TriggerTask/TriggerTaskUseCase.js.map +1 -1
  89. package/features/TriggerTask/abstractions.js +2 -1
  90. package/features/TriggerTask/abstractions.js.map +1 -1
  91. package/features/TriggerTask/feature.js +6 -5
  92. package/features/TriggerTask/feature.js.map +1 -1
  93. package/features/TriggerTask/index.js +0 -2
  94. package/global.js +0 -2
  95. package/graphql/checkPermissions.js +16 -35
  96. package/graphql/checkPermissions.js.map +1 -1
  97. package/graphql/index.js +154 -187
  98. package/graphql/index.js.map +1 -1
  99. package/graphql/utils.js +15 -14
  100. package/graphql/utils.js.map +1 -1
  101. package/handler/index.js +46 -53
  102. package/handler/index.js.map +1 -1
  103. package/handler/register.js +7 -15
  104. package/handler/register.js.map +1 -1
  105. package/handler/types.js +0 -3
  106. package/index.js +2 -4
  107. package/package.json +17 -17
  108. package/plugins/TaskServicePlugin.js +9 -6
  109. package/plugins/TaskServicePlugin.js.map +1 -1
  110. package/plugins/index.js +0 -2
  111. package/response/DatabaseResponse.js +113 -132
  112. package/response/DatabaseResponse.js.map +1 -1
  113. package/response/Response.js +78 -96
  114. package/response/Response.js.map +1 -1
  115. package/response/ResponseAbortedResult.js +8 -7
  116. package/response/ResponseAbortedResult.js.map +1 -1
  117. package/response/ResponseContinueResult.js +12 -14
  118. package/response/ResponseContinueResult.js.map +1 -1
  119. package/response/ResponseDoneResult.js +10 -9
  120. package/response/ResponseDoneResult.js.map +1 -1
  121. package/response/ResponseErrorResult.js +9 -8
  122. package/response/ResponseErrorResult.js.map +1 -1
  123. package/response/TaskResponse.js +44 -64
  124. package/response/TaskResponse.js.map +1 -1
  125. package/response/abstractions/Response.js +0 -3
  126. package/response/abstractions/ResponseAbortedResult.js +0 -3
  127. package/response/abstractions/ResponseBaseResult.js +0 -3
  128. package/response/abstractions/ResponseContinueResult.js +0 -3
  129. package/response/abstractions/ResponseDoneResult.js +0 -3
  130. package/response/abstractions/ResponseErrorResult.js +0 -3
  131. package/response/abstractions/TaskResponse.js +0 -3
  132. package/response/abstractions/index.js +0 -2
  133. package/response/index.js +0 -2
  134. package/runner/TaskControl.js +150 -221
  135. package/runner/TaskControl.js.map +1 -1
  136. package/runner/TaskEventValidation.js +12 -13
  137. package/runner/TaskEventValidation.js.map +1 -1
  138. package/runner/TaskManager.js +68 -106
  139. package/runner/TaskManager.js.map +1 -1
  140. package/runner/TaskManagerStore.js +90 -139
  141. package/runner/TaskManagerStore.js.map +1 -1
  142. package/runner/TaskRunner.js +45 -65
  143. package/runner/TaskRunner.js.map +1 -1
  144. package/runner/abstractions/TaskControl.js +0 -3
  145. package/runner/abstractions/TaskEventValidation.js +0 -3
  146. package/runner/abstractions/TaskManager.js +0 -3
  147. package/runner/abstractions/TaskManagerStore.js +0 -3
  148. package/runner/abstractions/TaskRunner.js +0 -3
  149. package/runner/abstractions/index.js +0 -2
  150. package/runner/index.js +0 -2
  151. package/service/EventBridgeEventTransportPlugin.js +43 -42
  152. package/service/EventBridgeEventTransportPlugin.js.map +1 -1
  153. package/service/StepFunctionServicePlugin.js +65 -66
  154. package/service/StepFunctionServicePlugin.js.map +1 -1
  155. package/service/createService.js +10 -13
  156. package/service/createService.js.map +1 -1
  157. package/service/index.js +7 -5
  158. package/service/index.js.map +1 -1
  159. package/tasks/testingRunTask.js +11 -10
  160. package/tasks/testingRunTask.js.map +1 -1
  161. package/types.js +12 -12
  162. package/types.js.map +1 -1
  163. package/utils/ObjectUpdater.js +25 -31
  164. package/utils/ObjectUpdater.js.map +1 -1
  165. package/utils/getErrorProperties.js +5 -4
  166. package/utils/getErrorProperties.js.map +1 -1
  167. package/utils/getObjectProperties.js +8 -15
  168. package/utils/getObjectProperties.js.map +1 -1
  169. package/utils/index.js +0 -2
  170. package/utils/normalizeSelfCleanup.js +13 -12
  171. package/utils/normalizeSelfCleanup.js.map +1 -1
  172. package/events/index.js.map +0 -1
  173. package/features/AbortTask/index.js.map +0 -1
  174. package/features/CleanupTaskSubtree/index.js.map +0 -1
  175. package/features/GetTask/index.js.map +0 -1
  176. package/features/GetTaskDefinition/index.js.map +0 -1
  177. package/features/ListTaskDefinitions/index.js.map +0 -1
  178. package/features/ListTasks/index.js.map +0 -1
  179. package/features/TaskController/augmentation.js.map +0 -1
  180. package/features/TaskController/index.js.map +0 -1
  181. package/features/TaskExecutionContext/index.js.map +0 -1
  182. package/features/TriggerTask/index.js.map +0 -1
  183. package/global.js.map +0 -1
  184. package/handler/types.js.map +0 -1
  185. package/index.js.map +0 -1
  186. package/plugins/index.js.map +0 -1
  187. package/response/abstractions/Response.js.map +0 -1
  188. package/response/abstractions/ResponseAbortedResult.js.map +0 -1
  189. package/response/abstractions/ResponseBaseResult.js.map +0 -1
  190. package/response/abstractions/ResponseContinueResult.js.map +0 -1
  191. package/response/abstractions/ResponseDoneResult.js.map +0 -1
  192. package/response/abstractions/ResponseErrorResult.js.map +0 -1
  193. package/response/abstractions/TaskResponse.js.map +0 -1
  194. package/response/abstractions/index.js.map +0 -1
  195. package/response/index.js.map +0 -1
  196. package/runner/abstractions/TaskControl.js.map +0 -1
  197. package/runner/abstractions/TaskEventValidation.js.map +0 -1
  198. package/runner/abstractions/TaskManager.js.map +0 -1
  199. package/runner/abstractions/TaskManagerStore.js.map +0 -1
  200. package/runner/abstractions/TaskRunner.js.map +0 -1
  201. package/runner/abstractions/index.js.map +0 -1
  202. package/runner/index.js.map +0 -1
  203. package/utils/index.js.map +0 -1
@@ -6,239 +6,168 @@ import { getErrorProperties } from "../utils/getErrorProperties.js";
6
6
  import { AuthenticatedIdentity } from "@webiny/api-core/features/security/IdentityContext/index.js";
7
7
  import { TaskExecutionContext } from "../features/TaskExecutionContext/index.js";
8
8
  import { TaskResultStatus } from "@webiny/api-core/features/task/TaskDefinition/index.js";
9
- export class TaskControl {
10
- constructor(runner, response, context) {
11
- this.runner = runner;
12
- this.context = context;
13
- this.response = response;
14
- }
15
- async run(event) {
16
- const taskId = event.webinyTaskId;
17
- /**
18
- * This is the initial getTask idea.
19
- * We will need to take care of child tasks:
20
- * * child tasks can be in multiple levels (child task creates a child task, etc...).
21
- * * child tasks could be executed in parallel.
22
- */
23
- let task;
24
- try {
25
- task = await this.getTask(taskId);
26
- this.context.security.setIdentity(new AuthenticatedIdentity({
27
- id: task.createdBy.id,
28
- type: task.createdBy.type,
29
- displayName: task.createdBy.displayName ?? "",
30
- context: {
31
- canAccessTenant: true
32
- }
33
- }));
34
- } catch (error) {
35
- /**
36
- * TODO Refactor error handling.
37
- */
38
- // @ts-expect-error
39
- return this.response.error({
40
- ...getErrorProperties(error)
41
- });
42
- }
43
- /**
44
- * Let's get the task definition.
45
- */
46
- const definition = this.context.tasks.getDefinition(task.definitionId);
47
- if (!definition) {
48
- return this.response.error({
49
- error: {
50
- message: `Task "${task.id}" cannot be executed because there is no "${task.definitionId}" definition plugin.`,
51
- code: "TASK_DEFINITION_ERROR",
52
- data: {
53
- definitionId: task.definitionId
54
- }
55
- }
56
- });
57
- }
58
- /**
59
- * Only enable logs if definition explicitly allows them.
60
- */
61
- const databaseLogs = definition.databaseLogs === true;
62
-
63
- /**
64
- * As this as a run of the task, we need to create a new log entry.
65
- */
66
- let taskLog;
67
- try {
68
- taskLog = await this.getTaskLog({
69
- task,
70
- databaseLogs
71
- });
72
- } catch (error) {
73
- return this.response.error({
74
- error
75
- });
9
+ class TaskControl {
10
+ constructor(runner, response, context){
11
+ this.runner = runner;
12
+ this.context = context;
13
+ this.response = response;
76
14
  }
77
- /**
78
- * Make sure that task does not run if it is aborted.
79
- * This will effectively end the Step Function execution with a "success" status.
80
- */
81
- if (task.taskStatus === TaskDataStatus.ABORTED) {
82
- return this.response.aborted();
83
- }
84
- /**
85
- * Do not run if already a success (done).
86
- */
87
- //
88
- else if (task.taskStatus === TaskDataStatus.SUCCESS) {
89
- return this.response.error({
90
- error: {
91
- message: "Task is already done, cannot run it again."
92
- }
93
- });
94
- }
95
- /**
96
- * Do not run if already failed.
97
- */
98
- //
99
- else if (task.taskStatus === TaskDataStatus.FAILED) {
100
- return this.response.error({
101
- error: {
102
- message: "Task has failed, cannot run it again."
15
+ async run(event) {
16
+ const taskId = event.webinyTaskId;
17
+ let task;
18
+ try {
19
+ task = await this.getTask(taskId);
20
+ this.context.security.setIdentity(new AuthenticatedIdentity({
21
+ id: task.createdBy.id,
22
+ type: task.createdBy.type,
23
+ displayName: task.createdBy.displayName ?? "",
24
+ context: {
25
+ canAccessTenant: true
26
+ }
27
+ }));
28
+ } catch (error) {
29
+ return this.response.error({
30
+ ...getErrorProperties(error)
31
+ });
103
32
  }
104
- });
105
- }
106
- const store = new TaskManagerStore({
107
- context: this.context,
108
- task,
109
- log: taskLog,
110
- databaseLogs
111
- });
112
-
113
- // Populate TaskExecutionContext BEFORE executing task
114
- const executionContext = this.context.container.resolve(TaskExecutionContext);
115
- executionContext.setStore(store);
116
- executionContext.setRunner(this.runner);
117
- executionContext.setTimer(this.runner.timer);
118
- executionContext.setResponse(new TaskResponse(this.response));
119
- const manager = new TaskManager(this.context, this.response, store);
120
- const databaseResponse = new DatabaseResponse(this.response, store);
121
- try {
122
- const result = await manager.run(definition);
123
- const responseResult = await databaseResponse.from(result);
124
-
125
- // Get the updated task from store (no database read needed - store maintains local cache)
126
- await this.runEvents(result, definition, store.getTask());
127
- return responseResult;
128
- } catch (ex) {
129
- /**
130
- * We always want to store the error in the task log.
131
- */
132
- return await databaseResponse.from(this.response.error({
133
- error: {
134
- message: ex.message,
135
- code: ex.code || "TASK_ERROR",
136
- stack: ex.stack,
137
- data: {
138
- ...ex.data,
139
- input: task.input
140
- }
33
+ const definition = this.context.tasks.getDefinition(task.definitionId);
34
+ if (!definition) return this.response.error({
35
+ error: {
36
+ message: `Task "${task.id}" cannot be executed because there is no "${task.definitionId}" definition plugin.`,
37
+ code: "TASK_DEFINITION_ERROR",
38
+ data: {
39
+ definitionId: task.definitionId
40
+ }
41
+ }
42
+ });
43
+ const databaseLogs = true === definition.databaseLogs;
44
+ let taskLog;
45
+ try {
46
+ taskLog = await this.getTaskLog({
47
+ task,
48
+ databaseLogs
49
+ });
50
+ } catch (error) {
51
+ return this.response.error({
52
+ error
53
+ });
141
54
  }
142
- }));
143
- } finally {
144
- // Clear execution context after task completes
145
- executionContext.clear();
146
- }
147
- }
148
- async runEvents(result, definition, task) {
149
- if (result.status === TaskResultStatus.ERROR && definition.onError) {
150
- try {
151
- await definition.onError({
152
- task
55
+ if (task.taskStatus === TaskDataStatus.ABORTED) return this.response.aborted();
56
+ if (task.taskStatus === TaskDataStatus.SUCCESS) return this.response.error({
57
+ error: {
58
+ message: "Task is already done, cannot run it again."
59
+ }
153
60
  });
154
- } catch (ex) {
155
- console.error(`Error executing onError hook for task "${task.id}".`);
156
- console.log(getErrorProperties(ex));
157
- }
158
- } else if (result.status === TaskResultStatus.DONE && definition.onDone) {
159
- try {
160
- await definition.onDone({
161
- task
61
+ if (task.taskStatus === TaskDataStatus.FAILED) return this.response.error({
62
+ error: {
63
+ message: "Task has failed, cannot run it again."
64
+ }
162
65
  });
163
- } catch (ex) {
164
- console.error(`Error executing onDone hook for task "${task.id}".`);
165
- console.log(getErrorProperties(ex));
166
- }
167
- }
168
- }
169
- async getTask(id) {
170
- try {
171
- const task = await this.runner.context.tasks.getTask(id);
172
- if (task) {
173
- return task;
174
- }
175
- } catch (ex) {
176
- throw this.response.error({
177
- error: {
178
- message: ex.message,
179
- code: ex.code || "TASK_ERROR",
180
- stack: ex.stack,
181
- data: ex.data
66
+ const store = new TaskManagerStore({
67
+ context: this.context,
68
+ task,
69
+ log: taskLog,
70
+ databaseLogs
71
+ });
72
+ const executionContext = this.context.container.resolve(TaskExecutionContext);
73
+ executionContext.setStore(store);
74
+ executionContext.setRunner(this.runner);
75
+ executionContext.setTimer(this.runner.timer);
76
+ executionContext.setResponse(new TaskResponse(this.response));
77
+ const manager = new TaskManager(this.context, this.response, store);
78
+ const databaseResponse = new DatabaseResponse(this.response, store);
79
+ try {
80
+ const result = await manager.run(definition);
81
+ const responseResult = await databaseResponse.from(result);
82
+ await this.runEvents(result, definition, store.getTask());
83
+ return responseResult;
84
+ } catch (ex) {
85
+ return await databaseResponse.from(this.response.error({
86
+ error: {
87
+ message: ex.message,
88
+ code: ex.code || "TASK_ERROR",
89
+ stack: ex.stack,
90
+ data: {
91
+ ...ex.data,
92
+ input: task.input
93
+ }
94
+ }
95
+ }));
96
+ } finally{
97
+ executionContext.clear();
182
98
  }
183
- });
184
99
  }
185
- throw this.response.error({
186
- error: {
187
- message: `Task "${id}" cannot be executed because it does not exist.`,
188
- code: "TASK_NOT_FOUND"
189
- }
190
- });
191
- }
192
- async getTaskLog(params) {
193
- const {
194
- task,
195
- databaseLogs
196
- } = params;
197
- /**
198
- * If logs are disabled, let's return a mocked one.
199
- */
200
- if (!databaseLogs) {
201
- return {
202
- id: `${task.id}-log`,
203
- createdOn: task.createdOn,
204
- createdBy: task.createdBy,
205
- executionName: task.executionName,
206
- task: task.id,
207
- iteration: task.iterations,
208
- items: []
209
- };
100
+ async runEvents(result, definition, task) {
101
+ if (result.status === TaskResultStatus.ERROR && definition.onError) try {
102
+ await definition.onError({
103
+ task
104
+ });
105
+ } catch (ex) {
106
+ console.error(`Error executing onError hook for task "${task.id}".`);
107
+ console.log(getErrorProperties(ex));
108
+ }
109
+ else if (result.status === TaskResultStatus.DONE && definition.onDone) try {
110
+ await definition.onDone({
111
+ task
112
+ });
113
+ } catch (ex) {
114
+ console.error(`Error executing onDone hook for task "${task.id}".`);
115
+ console.log(getErrorProperties(ex));
116
+ }
210
117
  }
211
- let taskLog = null;
212
- /**
213
- * First we are trying to get existing latest log.
214
- */
215
- try {
216
- taskLog = await this.context.tasks.getLatestLog(task.id);
217
- } catch (error) {
218
- /**
219
- * If error is not the NotFoundError, we need to throw it.
220
- */
221
- if (error.code !== "NOT_FOUND") {
118
+ async getTask(id) {
119
+ try {
120
+ const task = await this.runner.context.tasks.getTask(id);
121
+ if (task) return task;
122
+ } catch (ex) {
123
+ throw this.response.error({
124
+ error: {
125
+ message: ex.message,
126
+ code: ex.code || "TASK_ERROR",
127
+ stack: ex.stack,
128
+ data: ex.data
129
+ }
130
+ });
131
+ }
222
132
  throw this.response.error({
223
- error
133
+ error: {
134
+ message: `Task "${id}" cannot be executed because it does not exist.`,
135
+ code: "TASK_NOT_FOUND"
136
+ }
224
137
  });
225
- }
226
- /**
227
- * Otherwise just continue and create a new log.
228
- */
229
138
  }
230
- const currentIteration = taskLog?.iteration || 0;
231
- try {
232
- return await this.context.tasks.createLog(task, {
233
- executionName: this.response.event.executionName,
234
- iteration: currentIteration + 1
235
- });
236
- } catch (error) {
237
- throw this.response.error({
238
- error
239
- });
139
+ async getTaskLog(params) {
140
+ const { task, databaseLogs } = params;
141
+ if (!databaseLogs) return {
142
+ id: `${task.id}-log`,
143
+ createdOn: task.createdOn,
144
+ createdBy: task.createdBy,
145
+ executionName: task.executionName,
146
+ task: task.id,
147
+ iteration: task.iterations,
148
+ items: []
149
+ };
150
+ let taskLog = null;
151
+ try {
152
+ taskLog = await this.context.tasks.getLatestLog(task.id);
153
+ } catch (error) {
154
+ if ("NOT_FOUND" !== error.code) throw this.response.error({
155
+ error
156
+ });
157
+ }
158
+ const currentIteration = taskLog?.iteration || 0;
159
+ try {
160
+ return await this.context.tasks.createLog(task, {
161
+ executionName: this.response.event.executionName,
162
+ iteration: currentIteration + 1
163
+ });
164
+ } catch (error) {
165
+ throw this.response.error({
166
+ error
167
+ });
168
+ }
240
169
  }
241
- }
242
170
  }
171
+ export { TaskControl };
243
172
 
244
173
  //# sourceMappingURL=TaskControl.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["TaskDataStatus","TaskManager","DatabaseResponse","TaskResponse","TaskManagerStore","getErrorProperties","AuthenticatedIdentity","TaskExecutionContext","TaskResultStatus","TaskControl","constructor","runner","response","context","run","event","taskId","webinyTaskId","task","getTask","security","setIdentity","id","createdBy","type","displayName","canAccessTenant","error","definition","tasks","getDefinition","definitionId","message","code","data","databaseLogs","taskLog","getTaskLog","taskStatus","ABORTED","aborted","SUCCESS","FAILED","store","log","executionContext","container","resolve","setStore","setRunner","setTimer","timer","setResponse","manager","databaseResponse","result","responseResult","from","runEvents","ex","stack","input","clear","status","ERROR","onError","console","DONE","onDone","params","createdOn","executionName","iteration","iterations","items","getLatestLog","currentIteration","createLog"],"sources":["TaskControl.ts"],"sourcesContent":["import type { ITaskEvent } from \"~/handler/types.js\";\nimport type { Context, ITask, ITaskDataInput, ITaskLog } from \"~/types.js\";\nimport { TaskDataStatus } from \"~/types.js\";\nimport type { ITaskControl, ITaskRunner } from \"./abstractions/index.js\";\nimport { TaskManager } from \"./TaskManager.js\";\nimport type { IResponse, IResponseResult } from \"~/response/abstractions/index.js\";\nimport { DatabaseResponse, TaskResponse } from \"~/response/index.js\";\nimport { TaskManagerStore } from \"./TaskManagerStore.js\";\nimport { getErrorProperties } from \"~/utils/getErrorProperties.js\";\nimport { AuthenticatedIdentity } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TaskExecutionContext } from \"~/features/TaskExecutionContext/index.js\";\nimport {\n TaskDefinition,\n TaskResultStatus\n} from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\ninterface IGetTaskLogParams {\n task: ITask;\n databaseLogs: boolean;\n}\n\nexport class TaskControl implements ITaskControl {\n public readonly runner: ITaskRunner;\n public readonly response: IResponse;\n public readonly context: Context;\n\n public constructor(runner: ITaskRunner, response: IResponse, context: Context) {\n this.runner = runner;\n this.context = context;\n this.response = response;\n }\n\n public async run(event: Pick<ITaskEvent, \"webinyTaskId\">): Promise<IResponseResult> {\n const taskId = event.webinyTaskId;\n /**\n * This is the initial getTask idea.\n * We will need to take care of child tasks:\n * * child tasks can be in multiple levels (child task creates a child task, etc...).\n * * child tasks could be executed in parallel.\n */\n let task: ITask<ITaskDataInput>;\n try {\n task = await this.getTask(taskId);\n this.context.security.setIdentity(\n new AuthenticatedIdentity({\n id: task.createdBy.id,\n type: task.createdBy.type,\n displayName: task.createdBy.displayName ?? \"\",\n context: {\n canAccessTenant: true\n }\n })\n );\n } catch (error) {\n /**\n * TODO Refactor error handling.\n */\n // @ts-expect-error\n return this.response.error({\n ...getErrorProperties(error)\n });\n }\n /**\n * Let's get the task definition.\n */\n const definition = this.context.tasks.getDefinition(task.definitionId);\n if (!definition) {\n return this.response.error({\n error: {\n message: `Task \"${task.id}\" cannot be executed because there is no \"${task.definitionId}\" definition plugin.`,\n code: \"TASK_DEFINITION_ERROR\",\n data: {\n definitionId: task.definitionId\n }\n }\n });\n }\n /**\n * Only enable logs if definition explicitly allows them.\n */\n const databaseLogs = definition.databaseLogs === true;\n\n /**\n * As this as a run of the task, we need to create a new log entry.\n */\n let taskLog: ITaskLog;\n try {\n taskLog = await this.getTaskLog({\n task,\n databaseLogs\n });\n } catch (error) {\n return this.response.error({\n error\n });\n }\n /**\n * Make sure that task does not run if it is aborted.\n * This will effectively end the Step Function execution with a \"success\" status.\n */\n if (task.taskStatus === TaskDataStatus.ABORTED) {\n return this.response.aborted();\n }\n /**\n * Do not run if already a success (done).\n */\n //\n else if (task.taskStatus === TaskDataStatus.SUCCESS) {\n return this.response.error({\n error: {\n message: \"Task is already done, cannot run it again.\"\n }\n });\n }\n /**\n * Do not run if already failed.\n */\n //\n else if (task.taskStatus === TaskDataStatus.FAILED) {\n return this.response.error({\n error: {\n message: \"Task has failed, cannot run it again.\"\n }\n });\n }\n\n const store = new TaskManagerStore({\n context: this.context,\n task,\n log: taskLog,\n databaseLogs\n });\n\n // Populate TaskExecutionContext BEFORE executing task\n const executionContext = this.context.container.resolve(TaskExecutionContext);\n executionContext.setStore(store);\n executionContext.setRunner(this.runner);\n executionContext.setTimer(this.runner.timer);\n executionContext.setResponse(new TaskResponse(this.response));\n\n const manager = new TaskManager(this.context, this.response, store);\n\n const databaseResponse = new DatabaseResponse(this.response, store);\n\n try {\n const result = await manager.run(definition);\n\n const responseResult = await databaseResponse.from(result);\n\n // Get the updated task from store (no database read needed - store maintains local cache)\n await this.runEvents(result, definition, store.getTask());\n\n return responseResult;\n } catch (ex) {\n /**\n * We always want to store the error in the task log.\n */\n return await databaseResponse.from(\n this.response.error({\n error: {\n message: ex.message,\n code: ex.code || \"TASK_ERROR\",\n stack: ex.stack,\n data: {\n ...ex.data,\n input: task.input\n }\n }\n })\n );\n } finally {\n // Clear execution context after task completes\n executionContext.clear();\n }\n }\n\n private async runEvents(\n result: IResponseResult,\n definition: TaskDefinition.Runnable,\n task: ITask\n ): Promise<void> {\n if (result.status === TaskResultStatus.ERROR && definition.onError) {\n try {\n await definition.onError({ task });\n } catch (ex) {\n console.error(`Error executing onError hook for task \"${task.id}\".`);\n console.log(getErrorProperties(ex));\n }\n } else if (result.status === TaskResultStatus.DONE && definition.onDone) {\n try {\n await definition.onDone({ task });\n } catch (ex) {\n console.error(`Error executing onDone hook for task \"${task.id}\".`);\n console.log(getErrorProperties(ex));\n }\n }\n }\n\n private async getTask<T extends TaskDefinition.TaskInput>(id: string): Promise<ITask<T>> {\n try {\n const task = await this.runner.context.tasks.getTask<T>(id);\n if (task) {\n return task;\n }\n } catch (ex) {\n throw this.response.error({\n error: {\n message: ex.message,\n code: ex.code || \"TASK_ERROR\",\n stack: ex.stack,\n data: ex.data\n }\n });\n }\n throw this.response.error({\n error: {\n message: `Task \"${id}\" cannot be executed because it does not exist.`,\n code: \"TASK_NOT_FOUND\"\n }\n });\n }\n\n private async getTaskLog(params: IGetTaskLogParams): Promise<ITaskLog> {\n const { task, databaseLogs } = params;\n /**\n * If logs are disabled, let's return a mocked one.\n */\n if (!databaseLogs) {\n return {\n id: `${task.id}-log`,\n createdOn: task.createdOn,\n createdBy: task.createdBy,\n executionName: task.executionName,\n task: task.id,\n iteration: task.iterations,\n items: []\n };\n }\n let taskLog: ITaskLog | null = null;\n /**\n * First we are trying to get existing latest log.\n */\n try {\n taskLog = await this.context.tasks.getLatestLog(task.id);\n } catch (error) {\n /**\n * If error is not the NotFoundError, we need to throw it.\n */\n if (error.code !== \"NOT_FOUND\") {\n throw this.response.error({\n error\n });\n }\n /**\n * Otherwise just continue and create a new log.\n */\n }\n\n const currentIteration = taskLog?.iteration || 0;\n\n try {\n return await this.context.tasks.createLog(task, {\n executionName: this.response.event.executionName,\n iteration: currentIteration + 1\n });\n } catch (error) {\n throw this.response.error({\n error\n });\n }\n }\n}\n"],"mappings":"AAEA,SAASA,cAAc;AAEvB,SAASC,WAAW;AAEpB,SAASC,gBAAgB,EAAEC,YAAY;AACvC,SAASC,gBAAgB;AACzB,SAASC,kBAAkB;AAC3B,SAASC,qBAAqB,QAAQ,6DAA6D;AACnG,SAASC,oBAAoB;AAC7B,SAEIC,gBAAgB,QACb,wDAAwD;AAO/D,OAAO,MAAMC,WAAW,CAAyB;EAKtCC,WAAWA,CAACC,MAAmB,EAAEC,QAAmB,EAAEC,OAAgB,EAAE;IAC3E,IAAI,CAACF,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACE,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACD,QAAQ,GAAGA,QAAQ;EAC5B;EAEA,MAAaE,GAAGA,CAACC,KAAuC,EAA4B;IAChF,MAAMC,MAAM,GAAGD,KAAK,CAACE,YAAY;IACjC;AACR;AACA;AACA;AACA;AACA;IACQ,IAAIC,IAA2B;IAC/B,IAAI;MACAA,IAAI,GAAG,MAAM,IAAI,CAACC,OAAO,CAACH,MAAM,CAAC;MACjC,IAAI,CAACH,OAAO,CAACO,QAAQ,CAACC,WAAW,CAC7B,IAAIf,qBAAqB,CAAC;QACtBgB,EAAE,EAAEJ,IAAI,CAACK,SAAS,CAACD,EAAE;QACrBE,IAAI,EAAEN,IAAI,CAACK,SAAS,CAACC,IAAI;QACzBC,WAAW,EAAEP,IAAI,CAACK,SAAS,CAACE,WAAW,IAAI,EAAE;QAC7CZ,OAAO,EAAE;UACLa,eAAe,EAAE;QACrB;MACJ,CAAC,CACL,CAAC;IACL,CAAC,CAAC,OAAOC,KAAK,EAAE;MACZ;AACZ;AACA;MACY;MACA,OAAO,IAAI,CAACf,QAAQ,CAACe,KAAK,CAAC;QACvB,GAAGtB,kBAAkB,CAACsB,KAAK;MAC/B,CAAC,CAAC;IACN;IACA;AACR;AACA;IACQ,MAAMC,UAAU,GAAG,IAAI,CAACf,OAAO,CAACgB,KAAK,CAACC,aAAa,CAACZ,IAAI,CAACa,YAAY,CAAC;IACtE,IAAI,CAACH,UAAU,EAAE;MACb,OAAO,IAAI,CAAChB,QAAQ,CAACe,KAAK,CAAC;QACvBA,KAAK,EAAE;UACHK,OAAO,EAAE,SAASd,IAAI,CAACI,EAAE,6CAA6CJ,IAAI,CAACa,YAAY,sBAAsB;UAC7GE,IAAI,EAAE,uBAAuB;UAC7BC,IAAI,EAAE;YACFH,YAAY,EAAEb,IAAI,CAACa;UACvB;QACJ;MACJ,CAAC,CAAC;IACN;IACA;AACR;AACA;IACQ,MAAMI,YAAY,GAAGP,UAAU,CAACO,YAAY,KAAK,IAAI;;IAErD;AACR;AACA;IACQ,IAAIC,OAAiB;IACrB,IAAI;MACAA,OAAO,GAAG,MAAM,IAAI,CAACC,UAAU,CAAC;QAC5BnB,IAAI;QACJiB;MACJ,CAAC,CAAC;IACN,CAAC,CAAC,OAAOR,KAAK,EAAE;MACZ,OAAO,IAAI,CAACf,QAAQ,CAACe,KAAK,CAAC;QACvBA;MACJ,CAAC,CAAC;IACN;IACA;AACR;AACA;AACA;IACQ,IAAIT,IAAI,CAACoB,UAAU,KAAKtC,cAAc,CAACuC,OAAO,EAAE;MAC5C,OAAO,IAAI,CAAC3B,QAAQ,CAAC4B,OAAO,CAAC,CAAC;IAClC;IACA;AACR;AACA;IACQ;IAAA,KACK,IAAItB,IAAI,CAACoB,UAAU,KAAKtC,cAAc,CAACyC,OAAO,EAAE;MACjD,OAAO,IAAI,CAAC7B,QAAQ,CAACe,KAAK,CAAC;QACvBA,KAAK,EAAE;UACHK,OAAO,EAAE;QACb;MACJ,CAAC,CAAC;IACN;IACA;AACR;AACA;IACQ;IAAA,KACK,IAAId,IAAI,CAACoB,UAAU,KAAKtC,cAAc,CAAC0C,MAAM,EAAE;MAChD,OAAO,IAAI,CAAC9B,QAAQ,CAACe,KAAK,CAAC;QACvBA,KAAK,EAAE;UACHK,OAAO,EAAE;QACb;MACJ,CAAC,CAAC;IACN;IAEA,MAAMW,KAAK,GAAG,IAAIvC,gBAAgB,CAAC;MAC/BS,OAAO,EAAE,IAAI,CAACA,OAAO;MACrBK,IAAI;MACJ0B,GAAG,EAAER,OAAO;MACZD;IACJ,CAAC,CAAC;;IAEF;IACA,MAAMU,gBAAgB,GAAG,IAAI,CAAChC,OAAO,CAACiC,SAAS,CAACC,OAAO,CAACxC,oBAAoB,CAAC;IAC7EsC,gBAAgB,CAACG,QAAQ,CAACL,KAAK,CAAC;IAChCE,gBAAgB,CAACI,SAAS,CAAC,IAAI,CAACtC,MAAM,CAAC;IACvCkC,gBAAgB,CAACK,QAAQ,CAAC,IAAI,CAACvC,MAAM,CAACwC,KAAK,CAAC;IAC5CN,gBAAgB,CAACO,WAAW,CAAC,IAAIjD,YAAY,CAAC,IAAI,CAACS,QAAQ,CAAC,CAAC;IAE7D,MAAMyC,OAAO,GAAG,IAAIpD,WAAW,CAAC,IAAI,CAACY,OAAO,EAAE,IAAI,CAACD,QAAQ,EAAE+B,KAAK,CAAC;IAEnE,MAAMW,gBAAgB,GAAG,IAAIpD,gBAAgB,CAAC,IAAI,CAACU,QAAQ,EAAE+B,KAAK,CAAC;IAEnE,IAAI;MACA,MAAMY,MAAM,GAAG,MAAMF,OAAO,CAACvC,GAAG,CAACc,UAAU,CAAC;MAE5C,MAAM4B,cAAc,GAAG,MAAMF,gBAAgB,CAACG,IAAI,CAACF,MAAM,CAAC;;MAE1D;MACA,MAAM,IAAI,CAACG,SAAS,CAACH,MAAM,EAAE3B,UAAU,EAAEe,KAAK,CAACxB,OAAO,CAAC,CAAC,CAAC;MAEzD,OAAOqC,cAAc;IACzB,CAAC,CAAC,OAAOG,EAAE,EAAE;MACT;AACZ;AACA;MACY,OAAO,MAAML,gBAAgB,CAACG,IAAI,CAC9B,IAAI,CAAC7C,QAAQ,CAACe,KAAK,CAAC;QAChBA,KAAK,EAAE;UACHK,OAAO,EAAE2B,EAAE,CAAC3B,OAAO;UACnBC,IAAI,EAAE0B,EAAE,CAAC1B,IAAI,IAAI,YAAY;UAC7B2B,KAAK,EAAED,EAAE,CAACC,KAAK;UACf1B,IAAI,EAAE;YACF,GAAGyB,EAAE,CAACzB,IAAI;YACV2B,KAAK,EAAE3C,IAAI,CAAC2C;UAChB;QACJ;MACJ,CAAC,CACL,CAAC;IACL,CAAC,SAAS;MACN;MACAhB,gBAAgB,CAACiB,KAAK,CAAC,CAAC;IAC5B;EACJ;EAEA,MAAcJ,SAASA,CACnBH,MAAuB,EACvB3B,UAAmC,EACnCV,IAAW,EACE;IACb,IAAIqC,MAAM,CAACQ,MAAM,KAAKvD,gBAAgB,CAACwD,KAAK,IAAIpC,UAAU,CAACqC,OAAO,EAAE;MAChE,IAAI;QACA,MAAMrC,UAAU,CAACqC,OAAO,CAAC;UAAE/C;QAAK,CAAC,CAAC;MACtC,CAAC,CAAC,OAAOyC,EAAE,EAAE;QACTO,OAAO,CAACvC,KAAK,CAAC,0CAA0CT,IAAI,CAACI,EAAE,IAAI,CAAC;QACpE4C,OAAO,CAACtB,GAAG,CAACvC,kBAAkB,CAACsD,EAAE,CAAC,CAAC;MACvC;IACJ,CAAC,MAAM,IAAIJ,MAAM,CAACQ,MAAM,KAAKvD,gBAAgB,CAAC2D,IAAI,IAAIvC,UAAU,CAACwC,MAAM,EAAE;MACrE,IAAI;QACA,MAAMxC,UAAU,CAACwC,MAAM,CAAC;UAAElD;QAAK,CAAC,CAAC;MACrC,CAAC,CAAC,OAAOyC,EAAE,EAAE;QACTO,OAAO,CAACvC,KAAK,CAAC,yCAAyCT,IAAI,CAACI,EAAE,IAAI,CAAC;QACnE4C,OAAO,CAACtB,GAAG,CAACvC,kBAAkB,CAACsD,EAAE,CAAC,CAAC;MACvC;IACJ;EACJ;EAEA,MAAcxC,OAAOA,CAAqCG,EAAU,EAAqB;IACrF,IAAI;MACA,MAAMJ,IAAI,GAAG,MAAM,IAAI,CAACP,MAAM,CAACE,OAAO,CAACgB,KAAK,CAACV,OAAO,CAAIG,EAAE,CAAC;MAC3D,IAAIJ,IAAI,EAAE;QACN,OAAOA,IAAI;MACf;IACJ,CAAC,CAAC,OAAOyC,EAAE,EAAE;MACT,MAAM,IAAI,CAAC/C,QAAQ,CAACe,KAAK,CAAC;QACtBA,KAAK,EAAE;UACHK,OAAO,EAAE2B,EAAE,CAAC3B,OAAO;UACnBC,IAAI,EAAE0B,EAAE,CAAC1B,IAAI,IAAI,YAAY;UAC7B2B,KAAK,EAAED,EAAE,CAACC,KAAK;UACf1B,IAAI,EAAEyB,EAAE,CAACzB;QACb;MACJ,CAAC,CAAC;IACN;IACA,MAAM,IAAI,CAACtB,QAAQ,CAACe,KAAK,CAAC;MACtBA,KAAK,EAAE;QACHK,OAAO,EAAE,SAASV,EAAE,iDAAiD;QACrEW,IAAI,EAAE;MACV;IACJ,CAAC,CAAC;EACN;EAEA,MAAcI,UAAUA,CAACgC,MAAyB,EAAqB;IACnE,MAAM;MAAEnD,IAAI;MAAEiB;IAAa,CAAC,GAAGkC,MAAM;IACrC;AACR;AACA;IACQ,IAAI,CAAClC,YAAY,EAAE;MACf,OAAO;QACHb,EAAE,EAAE,GAAGJ,IAAI,CAACI,EAAE,MAAM;QACpBgD,SAAS,EAAEpD,IAAI,CAACoD,SAAS;QACzB/C,SAAS,EAAEL,IAAI,CAACK,SAAS;QACzBgD,aAAa,EAAErD,IAAI,CAACqD,aAAa;QACjCrD,IAAI,EAAEA,IAAI,CAACI,EAAE;QACbkD,SAAS,EAAEtD,IAAI,CAACuD,UAAU;QAC1BC,KAAK,EAAE;MACX,CAAC;IACL;IACA,IAAItC,OAAwB,GAAG,IAAI;IACnC;AACR;AACA;IACQ,IAAI;MACAA,OAAO,GAAG,MAAM,IAAI,CAACvB,OAAO,CAACgB,KAAK,CAAC8C,YAAY,CAACzD,IAAI,CAACI,EAAE,CAAC;IAC5D,CAAC,CAAC,OAAOK,KAAK,EAAE;MACZ;AACZ;AACA;MACY,IAAIA,KAAK,CAACM,IAAI,KAAK,WAAW,EAAE;QAC5B,MAAM,IAAI,CAACrB,QAAQ,CAACe,KAAK,CAAC;UACtBA;QACJ,CAAC,CAAC;MACN;MACA;AACZ;AACA;IACQ;IAEA,MAAMiD,gBAAgB,GAAGxC,OAAO,EAAEoC,SAAS,IAAI,CAAC;IAEhD,IAAI;MACA,OAAO,MAAM,IAAI,CAAC3D,OAAO,CAACgB,KAAK,CAACgD,SAAS,CAAC3D,IAAI,EAAE;QAC5CqD,aAAa,EAAE,IAAI,CAAC3D,QAAQ,CAACG,KAAK,CAACwD,aAAa;QAChDC,SAAS,EAAEI,gBAAgB,GAAG;MAClC,CAAC,CAAC;IACN,CAAC,CAAC,OAAOjD,KAAK,EAAE;MACZ,MAAM,IAAI,CAACf,QAAQ,CAACe,KAAK,CAAC;QACtBA;MACJ,CAAC,CAAC;IACN;EACJ;AACJ","ignoreList":[]}
1
+ {"version":3,"file":"runner/TaskControl.js","sources":["../../src/runner/TaskControl.ts"],"sourcesContent":["import type { ITaskEvent } from \"~/handler/types.js\";\nimport type { Context, ITask, ITaskDataInput, ITaskLog } from \"~/types.js\";\nimport { TaskDataStatus } from \"~/types.js\";\nimport type { ITaskControl, ITaskRunner } from \"./abstractions/index.js\";\nimport { TaskManager } from \"./TaskManager.js\";\nimport type { IResponse, IResponseResult } from \"~/response/abstractions/index.js\";\nimport { DatabaseResponse, TaskResponse } from \"~/response/index.js\";\nimport { TaskManagerStore } from \"./TaskManagerStore.js\";\nimport { getErrorProperties } from \"~/utils/getErrorProperties.js\";\nimport { AuthenticatedIdentity } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TaskExecutionContext } from \"~/features/TaskExecutionContext/index.js\";\nimport {\n TaskDefinition,\n TaskResultStatus\n} from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\ninterface IGetTaskLogParams {\n task: ITask;\n databaseLogs: boolean;\n}\n\nexport class TaskControl implements ITaskControl {\n public readonly runner: ITaskRunner;\n public readonly response: IResponse;\n public readonly context: Context;\n\n public constructor(runner: ITaskRunner, response: IResponse, context: Context) {\n this.runner = runner;\n this.context = context;\n this.response = response;\n }\n\n public async run(event: Pick<ITaskEvent, \"webinyTaskId\">): Promise<IResponseResult> {\n const taskId = event.webinyTaskId;\n /**\n * This is the initial getTask idea.\n * We will need to take care of child tasks:\n * * child tasks can be in multiple levels (child task creates a child task, etc...).\n * * child tasks could be executed in parallel.\n */\n let task: ITask<ITaskDataInput>;\n try {\n task = await this.getTask(taskId);\n this.context.security.setIdentity(\n new AuthenticatedIdentity({\n id: task.createdBy.id,\n type: task.createdBy.type,\n displayName: task.createdBy.displayName ?? \"\",\n context: {\n canAccessTenant: true\n }\n })\n );\n } catch (error) {\n /**\n * TODO Refactor error handling.\n */\n // @ts-expect-error\n return this.response.error({\n ...getErrorProperties(error)\n });\n }\n /**\n * Let's get the task definition.\n */\n const definition = this.context.tasks.getDefinition(task.definitionId);\n if (!definition) {\n return this.response.error({\n error: {\n message: `Task \"${task.id}\" cannot be executed because there is no \"${task.definitionId}\" definition plugin.`,\n code: \"TASK_DEFINITION_ERROR\",\n data: {\n definitionId: task.definitionId\n }\n }\n });\n }\n /**\n * Only enable logs if definition explicitly allows them.\n */\n const databaseLogs = definition.databaseLogs === true;\n\n /**\n * As this as a run of the task, we need to create a new log entry.\n */\n let taskLog: ITaskLog;\n try {\n taskLog = await this.getTaskLog({\n task,\n databaseLogs\n });\n } catch (error) {\n return this.response.error({\n error\n });\n }\n /**\n * Make sure that task does not run if it is aborted.\n * This will effectively end the Step Function execution with a \"success\" status.\n */\n if (task.taskStatus === TaskDataStatus.ABORTED) {\n return this.response.aborted();\n }\n /**\n * Do not run if already a success (done).\n */\n //\n else if (task.taskStatus === TaskDataStatus.SUCCESS) {\n return this.response.error({\n error: {\n message: \"Task is already done, cannot run it again.\"\n }\n });\n }\n /**\n * Do not run if already failed.\n */\n //\n else if (task.taskStatus === TaskDataStatus.FAILED) {\n return this.response.error({\n error: {\n message: \"Task has failed, cannot run it again.\"\n }\n });\n }\n\n const store = new TaskManagerStore({\n context: this.context,\n task,\n log: taskLog,\n databaseLogs\n });\n\n // Populate TaskExecutionContext BEFORE executing task\n const executionContext = this.context.container.resolve(TaskExecutionContext);\n executionContext.setStore(store);\n executionContext.setRunner(this.runner);\n executionContext.setTimer(this.runner.timer);\n executionContext.setResponse(new TaskResponse(this.response));\n\n const manager = new TaskManager(this.context, this.response, store);\n\n const databaseResponse = new DatabaseResponse(this.response, store);\n\n try {\n const result = await manager.run(definition);\n\n const responseResult = await databaseResponse.from(result);\n\n // Get the updated task from store (no database read needed - store maintains local cache)\n await this.runEvents(result, definition, store.getTask());\n\n return responseResult;\n } catch (ex) {\n /**\n * We always want to store the error in the task log.\n */\n return await databaseResponse.from(\n this.response.error({\n error: {\n message: ex.message,\n code: ex.code || \"TASK_ERROR\",\n stack: ex.stack,\n data: {\n ...ex.data,\n input: task.input\n }\n }\n })\n );\n } finally {\n // Clear execution context after task completes\n executionContext.clear();\n }\n }\n\n private async runEvents(\n result: IResponseResult,\n definition: TaskDefinition.Runnable,\n task: ITask\n ): Promise<void> {\n if (result.status === TaskResultStatus.ERROR && definition.onError) {\n try {\n await definition.onError({ task });\n } catch (ex) {\n console.error(`Error executing onError hook for task \"${task.id}\".`);\n console.log(getErrorProperties(ex));\n }\n } else if (result.status === TaskResultStatus.DONE && definition.onDone) {\n try {\n await definition.onDone({ task });\n } catch (ex) {\n console.error(`Error executing onDone hook for task \"${task.id}\".`);\n console.log(getErrorProperties(ex));\n }\n }\n }\n\n private async getTask<T extends TaskDefinition.TaskInput>(id: string): Promise<ITask<T>> {\n try {\n const task = await this.runner.context.tasks.getTask<T>(id);\n if (task) {\n return task;\n }\n } catch (ex) {\n throw this.response.error({\n error: {\n message: ex.message,\n code: ex.code || \"TASK_ERROR\",\n stack: ex.stack,\n data: ex.data\n }\n });\n }\n throw this.response.error({\n error: {\n message: `Task \"${id}\" cannot be executed because it does not exist.`,\n code: \"TASK_NOT_FOUND\"\n }\n });\n }\n\n private async getTaskLog(params: IGetTaskLogParams): Promise<ITaskLog> {\n const { task, databaseLogs } = params;\n /**\n * If logs are disabled, let's return a mocked one.\n */\n if (!databaseLogs) {\n return {\n id: `${task.id}-log`,\n createdOn: task.createdOn,\n createdBy: task.createdBy,\n executionName: task.executionName,\n task: task.id,\n iteration: task.iterations,\n items: []\n };\n }\n let taskLog: ITaskLog | null = null;\n /**\n * First we are trying to get existing latest log.\n */\n try {\n taskLog = await this.context.tasks.getLatestLog(task.id);\n } catch (error) {\n /**\n * If error is not the NotFoundError, we need to throw it.\n */\n if (error.code !== \"NOT_FOUND\") {\n throw this.response.error({\n error\n });\n }\n /**\n * Otherwise just continue and create a new log.\n */\n }\n\n const currentIteration = taskLog?.iteration || 0;\n\n try {\n return await this.context.tasks.createLog(task, {\n executionName: this.response.event.executionName,\n iteration: currentIteration + 1\n });\n } catch (error) {\n throw this.response.error({\n error\n });\n }\n }\n}\n"],"names":["TaskControl","runner","response","context","event","taskId","task","AuthenticatedIdentity","error","getErrorProperties","definition","databaseLogs","taskLog","TaskDataStatus","store","TaskManagerStore","executionContext","TaskExecutionContext","TaskResponse","manager","TaskManager","databaseResponse","DatabaseResponse","result","responseResult","ex","TaskResultStatus","console","id","params","currentIteration"],"mappings":"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"}
@@ -1,21 +1,20 @@
1
1
  import zod from "zod";
2
2
  import { createZodError } from "@webiny/utils";
3
3
  const validation = zod.object({
4
- webinyTaskId: zod.string(),
5
- webinyTaskDefinitionId: zod.string(),
6
- endpoint: zod.string(),
7
- tenant: zod.string(),
8
- executionName: zod.string(),
9
- stateMachineId: zod.string()
4
+ webinyTaskId: zod.string(),
5
+ webinyTaskDefinitionId: zod.string(),
6
+ endpoint: zod.string(),
7
+ tenant: zod.string(),
8
+ executionName: zod.string(),
9
+ stateMachineId: zod.string()
10
10
  }).required();
11
- export class TaskEventValidation {
12
- validate(event) {
13
- const result = validation.safeParse(event);
14
- if (result.success) {
15
- return result.data;
11
+ class TaskEventValidation {
12
+ validate(event) {
13
+ const result = validation.safeParse(event);
14
+ if (result.success) return result.data;
15
+ throw createZodError(result.error);
16
16
  }
17
- throw createZodError(result.error);
18
- }
19
17
  }
18
+ export { TaskEventValidation };
20
19
 
21
20
  //# sourceMappingURL=TaskEventValidation.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["zod","createZodError","validation","object","webinyTaskId","string","webinyTaskDefinitionId","endpoint","tenant","executionName","stateMachineId","required","TaskEventValidation","validate","event","result","safeParse","success","data","error"],"sources":["TaskEventValidation.ts"],"sourcesContent":["import zod from \"zod\";\nimport { createZodError } from \"@webiny/utils\";\nimport type { ITaskEventValidation, ITaskEventValidationResult } from \"./abstractions/index.js\";\nimport type { ITaskEvent } from \"~/handler/types.js\";\n\nconst validation = zod\n .object({\n webinyTaskId: zod.string(),\n webinyTaskDefinitionId: zod.string(),\n endpoint: zod.string(),\n tenant: zod.string(),\n executionName: zod.string(),\n stateMachineId: zod.string()\n })\n .required();\n\nexport class TaskEventValidation implements ITaskEventValidation {\n public validate(event: Partial<ITaskEvent>): ITaskEventValidationResult {\n const result = validation.safeParse(event);\n if (result.success) {\n return result.data;\n }\n throw createZodError(result.error);\n }\n}\n"],"mappings":"AAAA,OAAOA,GAAG,MAAM,KAAK;AACrB,SAASC,cAAc,QAAQ,eAAe;AAI9C,MAAMC,UAAU,GAAGF,GAAG,CACjBG,MAAM,CAAC;EACJC,YAAY,EAAEJ,GAAG,CAACK,MAAM,CAAC,CAAC;EAC1BC,sBAAsB,EAAEN,GAAG,CAACK,MAAM,CAAC,CAAC;EACpCE,QAAQ,EAAEP,GAAG,CAACK,MAAM,CAAC,CAAC;EACtBG,MAAM,EAAER,GAAG,CAACK,MAAM,CAAC,CAAC;EACpBI,aAAa,EAAET,GAAG,CAACK,MAAM,CAAC,CAAC;EAC3BK,cAAc,EAAEV,GAAG,CAACK,MAAM,CAAC;AAC/B,CAAC,CAAC,CACDM,QAAQ,CAAC,CAAC;AAEf,OAAO,MAAMC,mBAAmB,CAAiC;EACtDC,QAAQA,CAACC,KAA0B,EAA8B;IACpE,MAAMC,MAAM,GAAGb,UAAU,CAACc,SAAS,CAACF,KAAK,CAAC;IAC1C,IAAIC,MAAM,CAACE,OAAO,EAAE;MAChB,OAAOF,MAAM,CAACG,IAAI;IACtB;IACA,MAAMjB,cAAc,CAACc,MAAM,CAACI,KAAK,CAAC;EACtC;AACJ","ignoreList":[]}
1
+ {"version":3,"file":"runner/TaskEventValidation.js","sources":["../../src/runner/TaskEventValidation.ts"],"sourcesContent":["import zod from \"zod\";\nimport { createZodError } from \"@webiny/utils\";\nimport type { ITaskEventValidation, ITaskEventValidationResult } from \"./abstractions/index.js\";\nimport type { ITaskEvent } from \"~/handler/types.js\";\n\nconst validation = zod\n .object({\n webinyTaskId: zod.string(),\n webinyTaskDefinitionId: zod.string(),\n endpoint: zod.string(),\n tenant: zod.string(),\n executionName: zod.string(),\n stateMachineId: zod.string()\n })\n .required();\n\nexport class TaskEventValidation implements ITaskEventValidation {\n public validate(event: Partial<ITaskEvent>): ITaskEventValidationResult {\n const result = validation.safeParse(event);\n if (result.success) {\n return result.data;\n }\n throw createZodError(result.error);\n }\n}\n"],"names":["validation","zod","TaskEventValidation","event","result","createZodError"],"mappings":";;AAKA,MAAMA,aAAaC,IAAAA,MACR,CAAC;IACJ,cAAcA,IAAI,MAAM;IACxB,wBAAwBA,IAAI,MAAM;IAClC,UAAUA,IAAI,MAAM;IACpB,QAAQA,IAAI,MAAM;IAClB,eAAeA,IAAI,MAAM;IACzB,gBAAgBA,IAAI,MAAM;AAC9B,GACC,QAAQ;AAEN,MAAMC;IACF,SAASC,KAA0B,EAA8B;QACpE,MAAMC,SAASJ,WAAW,SAAS,CAACG;QACpC,IAAIC,OAAO,OAAO,EACd,OAAOA,OAAO,IAAI;QAEtB,MAAMC,eAAeD,OAAO,KAAK;IACrC;AACJ"}