@webiny/background-tasks 6.6.0-alpha.3 → 6.6.0-alpha.4

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 (43) hide show
  1. package/api/BackgroundTasksFeature.js +6 -6
  2. package/api/BackgroundTasksFeature.js.map +1 -1
  3. package/api/crud/crud.tasks.js.map +1 -1
  4. package/api/crud/definition.tasks.js +2 -2
  5. package/api/crud/definition.tasks.js.map +1 -1
  6. package/api/decorators/SelfCleaningTaskHandlerDecorator.d.ts +33 -0
  7. package/api/decorators/{SelfCleaningTaskDecorator.js → SelfCleaningTaskHandlerDecorator.js} +15 -39
  8. package/api/decorators/SelfCleaningTaskHandlerDecorator.js.map +1 -0
  9. package/api/decorators/TaskDefinitionDefaultsDecorator.d.ts +27 -0
  10. package/api/decorators/{RunnableTaskDecorator.js → TaskDefinitionDefaultsDecorator.js} +11 -32
  11. package/api/decorators/TaskDefinitionDefaultsDecorator.js.map +1 -0
  12. package/api/domain/errors.d.ts +0 -10
  13. package/api/domain/errors.js +1 -11
  14. package/api/domain/errors.js.map +1 -1
  15. package/api/features/{GetTaskDefinition/GetTaskDefinitionUseCase.d.ts → GetRunnableTaskDefinition/GetRunnableTaskDefinitionUseCase.d.ts} +5 -7
  16. package/api/features/GetRunnableTaskDefinition/GetRunnableTaskDefinitionUseCase.js +51 -0
  17. package/api/features/GetRunnableTaskDefinition/GetRunnableTaskDefinitionUseCase.js.map +1 -0
  18. package/api/features/{GetTaskDefinition → GetRunnableTaskDefinition}/abstractions.d.ts +7 -8
  19. package/api/features/GetRunnableTaskDefinition/abstractions.js +5 -0
  20. package/api/features/GetRunnableTaskDefinition/abstractions.js.map +1 -0
  21. package/api/features/{GetTaskDefinition → GetRunnableTaskDefinition}/feature.d.ts +1 -1
  22. package/api/features/GetRunnableTaskDefinition/feature.js +11 -0
  23. package/api/features/GetRunnableTaskDefinition/feature.js.map +1 -0
  24. package/api/features/GetRunnableTaskDefinition/index.d.ts +2 -0
  25. package/api/features/GetRunnableTaskDefinition/index.js +2 -0
  26. package/api/runner/TaskControl.d.ts +2 -2
  27. package/api/runner/TaskControl.js +1 -1
  28. package/api/runner/TaskControl.js.map +1 -1
  29. package/api/runner/TaskRunner.js +2 -2
  30. package/api/runner/TaskRunner.js.map +1 -1
  31. package/package.json +19 -19
  32. package/api/decorators/RunnableTaskDecorator.d.ts +0 -33
  33. package/api/decorators/RunnableTaskDecorator.js.map +0 -1
  34. package/api/decorators/SelfCleaningTaskDecorator.d.ts +0 -33
  35. package/api/decorators/SelfCleaningTaskDecorator.js.map +0 -1
  36. package/api/features/GetTaskDefinition/GetTaskDefinitionUseCase.js +0 -88
  37. package/api/features/GetTaskDefinition/GetTaskDefinitionUseCase.js.map +0 -1
  38. package/api/features/GetTaskDefinition/abstractions.js +0 -5
  39. package/api/features/GetTaskDefinition/abstractions.js.map +0 -1
  40. package/api/features/GetTaskDefinition/feature.js +0 -11
  41. package/api/features/GetTaskDefinition/feature.js.map +0 -1
  42. package/api/features/GetTaskDefinition/index.d.ts +0 -2
  43. package/api/features/GetTaskDefinition/index.js +0 -2
@@ -0,0 +1,51 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import { GetRunnableTaskDefinitionUseCase } from "./abstractions.js";
3
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
4
+ import { TaskHandlerResolver } from "../TaskHandlerResolver/index.js";
5
+ import { TaskDefinitionNotFoundError } from "../../domain/errors.js";
6
+ class GetRunnableTaskDefinitionUseCaseImpl {
7
+ constructor(definitions, handlerResolver){
8
+ this.definitions = definitions;
9
+ this.handlerResolver = handlerResolver;
10
+ }
11
+ execute(id) {
12
+ for (const definition of this.definitions){
13
+ if (definition.id !== id) continue;
14
+ const handlerClass = definition.handler;
15
+ const handler = this.handlerResolver.resolve(handlerClass);
16
+ const runnable = {
17
+ id: definition.id,
18
+ title: definition.title,
19
+ description: definition.description,
20
+ isPrivate: definition.isPrivate,
21
+ databaseLogs: definition.databaseLogs,
22
+ maxIterations: definition.maxIterations,
23
+ selfCleanup: definition.selfCleanup,
24
+ run: handler.run.bind(handler),
25
+ onBeforeTrigger: handler.onBeforeTrigger?.bind(handler),
26
+ onDone: handler.onDone?.bind(handler),
27
+ onError: handler.onError?.bind(handler),
28
+ onAbort: handler.onAbort?.bind(handler),
29
+ onMaxIterations: handler.onMaxIterations?.bind(handler),
30
+ createInputValidation: handler.createInputValidation?.bind(handler)
31
+ };
32
+ return Result.ok(runnable);
33
+ }
34
+ return Result.fail(new TaskDefinitionNotFoundError(id));
35
+ }
36
+ }
37
+ const GetRunnableTaskDefinitionUseCase_GetRunnableTaskDefinitionUseCase = GetRunnableTaskDefinitionUseCase.createImplementation({
38
+ implementation: GetRunnableTaskDefinitionUseCaseImpl,
39
+ dependencies: [
40
+ [
41
+ TaskDefinition,
42
+ {
43
+ multiple: true
44
+ }
45
+ ],
46
+ TaskHandlerResolver
47
+ ]
48
+ });
49
+ export { GetRunnableTaskDefinitionUseCaseImpl, GetRunnableTaskDefinitionUseCase_GetRunnableTaskDefinitionUseCase as GetRunnableTaskDefinitionUseCase };
50
+
51
+ //# sourceMappingURL=GetRunnableTaskDefinitionUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/GetRunnableTaskDefinition/GetRunnableTaskDefinitionUseCase.js","sources":["../../../../src/api/features/GetRunnableTaskDefinition/GetRunnableTaskDefinitionUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport type { Constructor } from \"@webiny/di\";\nimport { GetRunnableTaskDefinitionUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { TaskHandlerResolver } from \"~/api/features/TaskHandlerResolver/index.js\";\nimport { TaskDefinitionNotFoundError } from \"~/api/domain/errors.js\";\n\nexport class GetRunnableTaskDefinitionUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private definitions: TaskDefinition.Interface[],\n private handlerResolver: TaskHandlerResolver.Interface\n ) {}\n\n public execute<\n I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput,\n O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput\n >(id: string): Result<TaskDefinition.Runnable<I, O>, UseCaseAbstraction.Error> {\n for (const definition of this.definitions) {\n if (definition.id !== id) {\n continue;\n }\n\n // Every definition is free to build, so reaching this point cost nothing. The handler is\n // the expensive half and it is built only now, for the one task that was asked for.\n //\n // The registered definition is stored under the abstraction's default generics, so its\n // handler cannot be proven assignable to the caller's narrower <I, O>.\n const handlerClass = definition.handler as Constructor<TaskDefinition.Handler<I, O>>;\n const handler = this.handlerResolver.resolve(handlerClass);\n\n // Present the two halves as the single object the runner and\n // `context.tasks.getDefinition()` expect. Metadata from the definition, behaviour from\n // the handler, bound so `this` inside a hook is still the instance that owns the\n // injected dependencies.\n const runnable: TaskDefinition.Runnable<I, O> = {\n id: definition.id,\n title: definition.title,\n description: definition.description,\n isPrivate: definition.isPrivate as boolean,\n databaseLogs: definition.databaseLogs as boolean,\n maxIterations: definition.maxIterations as number,\n selfCleanup: definition.selfCleanup,\n\n run: handler.run.bind(handler),\n onBeforeTrigger: handler.onBeforeTrigger?.bind(handler),\n onDone: handler.onDone?.bind(handler),\n onError: handler.onError?.bind(handler),\n onAbort: handler.onAbort?.bind(handler),\n onMaxIterations: handler.onMaxIterations?.bind(handler),\n createInputValidation: handler.createInputValidation?.bind(handler)\n };\n\n return Result.ok(runnable);\n }\n\n return Result.fail(new TaskDefinitionNotFoundError(id));\n }\n}\n\nexport const GetRunnableTaskDefinitionUseCase = UseCaseAbstraction.createImplementation({\n implementation: GetRunnableTaskDefinitionUseCaseImpl,\n dependencies: [[TaskDefinition, { multiple: true }], TaskHandlerResolver]\n});\n"],"names":["GetRunnableTaskDefinitionUseCaseImpl","definitions","handlerResolver","id","definition","handlerClass","handler","runnable","Result","TaskDefinitionNotFoundError","GetRunnableTaskDefinitionUseCase","UseCaseAbstraction","TaskDefinition","TaskHandlerResolver"],"mappings":";;;;;AAOO,MAAMA;IACT,YACYC,WAAuC,EACvCC,eAA8C,CACxD;aAFUD,WAAW,GAAXA;aACAC,eAAe,GAAfA;IACT;IAEI,QAGLC,EAAU,EAAmE;QAC3E,KAAK,MAAMC,cAAc,IAAI,CAAC,WAAW,CAAE;YACvC,IAAIA,WAAW,EAAE,KAAKD,IAClB;YAQJ,MAAME,eAAeD,WAAW,OAAO;YACvC,MAAME,UAAU,IAAI,CAAC,eAAe,CAAC,OAAO,CAACD;YAM7C,MAAME,WAA0C;gBAC5C,IAAIH,WAAW,EAAE;gBACjB,OAAOA,WAAW,KAAK;gBACvB,aAAaA,WAAW,WAAW;gBACnC,WAAWA,WAAW,SAAS;gBAC/B,cAAcA,WAAW,YAAY;gBACrC,eAAeA,WAAW,aAAa;gBACvC,aAAaA,WAAW,WAAW;gBAEnC,KAAKE,QAAQ,GAAG,CAAC,IAAI,CAACA;gBACtB,iBAAiBA,QAAQ,eAAe,EAAE,KAAKA;gBAC/C,QAAQA,QAAQ,MAAM,EAAE,KAAKA;gBAC7B,SAASA,QAAQ,OAAO,EAAE,KAAKA;gBAC/B,SAASA,QAAQ,OAAO,EAAE,KAAKA;gBAC/B,iBAAiBA,QAAQ,eAAe,EAAE,KAAKA;gBAC/C,uBAAuBA,QAAQ,qBAAqB,EAAE,KAAKA;YAC/D;YAEA,OAAOE,OAAO,EAAE,CAACD;QACrB;QAEA,OAAOC,OAAO,IAAI,CAAC,IAAIC,4BAA4BN;IACvD;AACJ;AAEO,MAAMO,oEAAmCC,iCAAAA,oBAAuC,CAAC;IACpF,gBAAgBX;IAChB,cAAc;QAAC;YAACY;YAAgB;gBAAE,UAAU;YAAK;SAAE;QAAEC;KAAoB;AAC7E"}
@@ -1,17 +1,16 @@
1
1
  import type { Result } from "@webiny/feature/api";
2
2
  import type { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
3
- import type { TaskDefinitionNotFoundError, TaskDefinitionNotRunnableError } from "../../../api/domain/errors.js";
4
- export interface IGetTaskDefinitionUseCase {
3
+ import type { TaskDefinitionNotFoundError } from "../../../api/domain/errors.js";
4
+ export interface IGetRunnableTaskDefinitionUseCase {
5
5
  execute<I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput, O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput>(id: string): Result<TaskDefinition.Runnable<I, O>, UseCaseError>;
6
6
  }
7
- export interface IGetTaskDefinitionUseCaseErrors {
7
+ export interface IGetRunnableTaskDefinitionUseCaseErrors {
8
8
  notFound: TaskDefinitionNotFoundError;
9
- notRunnable: TaskDefinitionNotRunnableError;
10
9
  }
11
- type UseCaseError = IGetTaskDefinitionUseCaseErrors[keyof IGetTaskDefinitionUseCaseErrors];
12
- export declare const GetTaskDefinitionUseCase: import("@webiny/di").Abstraction<IGetTaskDefinitionUseCase>;
13
- export declare namespace GetTaskDefinitionUseCase {
14
- type Interface = IGetTaskDefinitionUseCase;
10
+ type UseCaseError = IGetRunnableTaskDefinitionUseCaseErrors[keyof IGetRunnableTaskDefinitionUseCaseErrors];
11
+ export declare const GetRunnableTaskDefinitionUseCase: import("@webiny/di").Abstraction<IGetRunnableTaskDefinitionUseCase>;
12
+ export declare namespace GetRunnableTaskDefinitionUseCase {
13
+ type Interface = IGetRunnableTaskDefinitionUseCase;
15
14
  type Error = UseCaseError;
16
15
  type Return<I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput, O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput> = Result<TaskDefinition.Runnable<I, O>, UseCaseError>;
17
16
  }
@@ -0,0 +1,5 @@
1
+ import { createAbstraction } from "@webiny/feature/api";
2
+ const GetRunnableTaskDefinitionUseCase = createAbstraction("Tasks/GetRunnableTaskDefinitionUseCase");
3
+ export { GetRunnableTaskDefinitionUseCase };
4
+
5
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/GetRunnableTaskDefinition/abstractions.js","sources":["../../../../src/api/features/GetRunnableTaskDefinition/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { Result } from \"@webiny/feature/api\";\nimport type { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport type { TaskDefinitionNotFoundError } from \"~/api/domain/errors.js\";\n\nexport interface IGetRunnableTaskDefinitionUseCase {\n execute<\n I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput,\n O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput\n >(\n id: string\n ): Result<TaskDefinition.Runnable<I, O>, UseCaseError>;\n}\n\nexport interface IGetRunnableTaskDefinitionUseCaseErrors {\n notFound: TaskDefinitionNotFoundError;\n}\n\ntype UseCaseError =\n IGetRunnableTaskDefinitionUseCaseErrors[keyof IGetRunnableTaskDefinitionUseCaseErrors];\n\nexport const GetRunnableTaskDefinitionUseCase =\n createAbstraction<IGetRunnableTaskDefinitionUseCase>(\"Tasks/GetRunnableTaskDefinitionUseCase\");\n\nexport namespace GetRunnableTaskDefinitionUseCase {\n export type Interface = IGetRunnableTaskDefinitionUseCase;\n\n export type Error = UseCaseError;\n export type Return<\n I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput,\n O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput\n > = Result<TaskDefinition.Runnable<I, O>, UseCaseError>;\n}\n"],"names":["GetRunnableTaskDefinitionUseCase","createAbstraction"],"mappings":";AAqBO,MAAMA,mCACTC,kBAAqD"}
@@ -1,4 +1,4 @@
1
- export declare const GetTaskDefinitionFeature: {
1
+ export declare const GetRunnableTaskDefinitionFeature: {
2
2
  name: string;
3
3
  register(container: import("@webiny/di").Container): void;
4
4
  };
@@ -0,0 +1,11 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { GetRunnableTaskDefinitionUseCase } from "./GetRunnableTaskDefinitionUseCase.js";
3
+ const GetRunnableTaskDefinitionFeature = createFeature({
4
+ name: "GetRunnableTaskDefinition",
5
+ register (container) {
6
+ container.register(GetRunnableTaskDefinitionUseCase);
7
+ }
8
+ });
9
+ export { GetRunnableTaskDefinitionFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/GetRunnableTaskDefinition/feature.js","sources":["../../../../src/api/features/GetRunnableTaskDefinition/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { GetRunnableTaskDefinitionUseCase } from \"./GetRunnableTaskDefinitionUseCase.js\";\n\nexport const GetRunnableTaskDefinitionFeature = createFeature({\n name: \"GetRunnableTaskDefinition\",\n register(container) {\n container.register(GetRunnableTaskDefinitionUseCase);\n }\n});\n"],"names":["GetRunnableTaskDefinitionFeature","createFeature","container","GetRunnableTaskDefinitionUseCase"],"mappings":";;AAGO,MAAMA,mCAAmCC,cAAc;IAC1D,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,2 @@
1
+ export { GetRunnableTaskDefinitionUseCase } from "./abstractions.js";
2
+ export { GetRunnableTaskDefinitionFeature } from "./feature.js";
@@ -0,0 +1,2 @@
1
+ export { GetRunnableTaskDefinitionUseCase } from "./abstractions.js";
2
+ export { GetRunnableTaskDefinitionFeature } from "./feature.js";
@@ -5,7 +5,7 @@ import type { IResponse, IResponseResult } from "../../api/response/abstractions
5
5
  import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
6
6
  import { TaskExecutionContext } from "../../api/features/TaskExecutionContext/index.js";
7
7
  import { TasksCrud } from "../../api/TasksCrud.js";
8
- import { GetTaskDefinitionUseCase } from "../../api/features/GetTaskDefinition/abstractions.js";
8
+ import { GetRunnableTaskDefinitionUseCase } from "../../api/features/GetRunnableTaskDefinition/abstractions.js";
9
9
  import { Logger } from "@webiny/api-core/features/logger/index.js";
10
10
  import { TaskController } from "@webiny/api-core/features/task/TaskController/abstractions.js";
11
11
  /**
@@ -23,7 +23,7 @@ export interface ITaskControlDependencies {
23
23
  taskExecutionContext: TaskExecutionContext.Interface;
24
24
  tasksCrud: TasksCrud.Interface;
25
25
  taskController: TaskController.Interface;
26
- getTaskDefinition: GetTaskDefinitionUseCase.Interface;
26
+ getRunnableTaskDefinition: GetRunnableTaskDefinitionUseCase.Interface;
27
27
  }
28
28
  export declare class TaskControl implements ITaskControl {
29
29
  readonly runner: ITaskRunner;
@@ -30,7 +30,7 @@ class TaskControl {
30
30
  ...getErrorProperties(error)
31
31
  });
32
32
  }
33
- const definitionResult = this.deps.getTaskDefinition.execute(task.definitionId);
33
+ const definitionResult = this.deps.getRunnableTaskDefinition.execute(task.definitionId);
34
34
  if (definitionResult.isFail()) return this.response.error({
35
35
  error: {
36
36
  message: `Task "${task.id}" cannot be executed because there is no "${task.definitionId}" definition plugin.`,
@@ -1 +1 @@
1
- {"version":3,"file":"api/runner/TaskControl.js","sources":["../../../src/api/runner/TaskControl.ts"],"sourcesContent":["import type { ITaskEvent } from \"~/api/handler/types.js\";\nimport type { Context, ITask, ITaskDataInput, ITaskLog } from \"~/api/types.js\";\nimport { TaskDataStatus } from \"~/api/types.js\";\nimport type { ITaskControl, ITaskRunner } from \"./abstractions/index.js\";\nimport { TaskManager } from \"./TaskManager.js\";\nimport type { IResponse, IResponseResult } from \"~/api/response/abstractions/index.js\";\nimport { DatabaseResponse, TaskResponse } from \"~/api/response/index.js\";\nimport { TaskManagerStore } from \"./TaskManagerStore.js\";\nimport { getErrorProperties } from \"~/api/utils/getErrorProperties.js\";\nimport {\n AuthenticatedIdentity,\n IdentityContext\n} from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TaskExecutionContext } from \"~/api/features/TaskExecutionContext/index.js\";\nimport {\n TaskDefinition,\n TaskResultStatus\n} from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { TasksCrud } from \"~/api/TasksCrud.js\";\nimport { GetTaskDefinitionUseCase } from \"~/api/features/GetTaskDefinition/abstractions.js\";\nimport { Logger } from \"@webiny/api-core/features/logger/index.js\";\nimport { TaskController } from \"@webiny/api-core/features/task/TaskController/abstractions.js\";\n\ninterface IGetTaskLogParams {\n task: ITask;\n databaseLogs: boolean;\n}\n\n/**\n * What TaskControl needs from the container, declared in one place.\n *\n * TaskControl is built by hand (TaskRunner does it), so it cannot take these through DI the way a\n * registered class would. Naming them here is the next best thing: the class states what it uses,\n * TaskRunner resolves them once where it assembles the object, and a test can pass fakes. Reaching\n * into `context.container` from inside a method instead would leave the class with dependencies\n * nothing can see or substitute.\n */\nexport interface ITaskControlDependencies {\n logger: Logger.Interface;\n identityContext: IdentityContext.Interface;\n taskExecutionContext: TaskExecutionContext.Interface;\n tasksCrud: TasksCrud.Interface;\n taskController: TaskController.Interface;\n getTaskDefinition: GetTaskDefinitionUseCase.Interface;\n}\n\nexport class TaskControl implements ITaskControl {\n public readonly runner: ITaskRunner;\n public readonly response: IResponse;\n public readonly context: Context;\n private readonly deps: ITaskControlDependencies;\n\n public constructor(\n runner: ITaskRunner,\n response: IResponse,\n context: Context,\n deps: ITaskControlDependencies\n ) {\n this.runner = runner;\n this.context = context;\n this.response = response;\n this.deps = deps;\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.deps.identityContext.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 definitionResult = this.deps.getTaskDefinition.execute(task.definitionId);\n if (definitionResult.isFail()) {\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 const definition = definitionResult.value;\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 tasksCrud: this.deps.tasksCrud,\n task,\n log: taskLog,\n databaseLogs\n });\n\n // Populate TaskExecutionContext BEFORE executing task\n const executionContext = this.deps.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 taskController: this.deps.taskController,\n identityContext: this.deps.identityContext\n });\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, definition });\n } catch (ex) {\n this.deps.logger.error(\n { error: getErrorProperties(ex), taskId: task.id, hook: \"onError\" },\n \"Error executing task lifecycle hook.\"\n );\n }\n } else if (result.status === TaskResultStatus.DONE && definition.onDone) {\n try {\n await definition.onDone({ task, definition });\n } catch (ex) {\n this.deps.logger.error(\n { error: getErrorProperties(ex), taskId: task.id, hook: \"onDone\" },\n \"Error executing task lifecycle hook.\"\n );\n }\n }\n }\n\n private async getTask<T extends TaskDefinition.TaskInput>(id: string): Promise<ITask<T>> {\n try {\n const task = await this.deps.tasksCrud.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.deps.tasksCrud.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.deps.tasksCrud.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","deps","event","taskId","task","AuthenticatedIdentity","error","getErrorProperties","definitionResult","definition","databaseLogs","taskLog","TaskDataStatus","store","TaskManagerStore","executionContext","TaskResponse","manager","TaskManager","databaseResponse","DatabaseResponse","result","responseResult","ex","TaskResultStatus","id","params","currentIteration"],"mappings":"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"}
1
+ {"version":3,"file":"api/runner/TaskControl.js","sources":["../../../src/api/runner/TaskControl.ts"],"sourcesContent":["import type { ITaskEvent } from \"~/api/handler/types.js\";\nimport type { Context, ITask, ITaskDataInput, ITaskLog } from \"~/api/types.js\";\nimport { TaskDataStatus } from \"~/api/types.js\";\nimport type { ITaskControl, ITaskRunner } from \"./abstractions/index.js\";\nimport { TaskManager } from \"./TaskManager.js\";\nimport type { IResponse, IResponseResult } from \"~/api/response/abstractions/index.js\";\nimport { DatabaseResponse, TaskResponse } from \"~/api/response/index.js\";\nimport { TaskManagerStore } from \"./TaskManagerStore.js\";\nimport { getErrorProperties } from \"~/api/utils/getErrorProperties.js\";\nimport {\n AuthenticatedIdentity,\n IdentityContext\n} from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TaskExecutionContext } from \"~/api/features/TaskExecutionContext/index.js\";\nimport {\n TaskDefinition,\n TaskResultStatus\n} from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { TasksCrud } from \"~/api/TasksCrud.js\";\nimport { GetRunnableTaskDefinitionUseCase } from \"~/api/features/GetRunnableTaskDefinition/abstractions.js\";\nimport { Logger } from \"@webiny/api-core/features/logger/index.js\";\nimport { TaskController } from \"@webiny/api-core/features/task/TaskController/abstractions.js\";\n\ninterface IGetTaskLogParams {\n task: ITask;\n databaseLogs: boolean;\n}\n\n/**\n * What TaskControl needs from the container, declared in one place.\n *\n * TaskControl is built by hand (TaskRunner does it), so it cannot take these through DI the way a\n * registered class would. Naming them here is the next best thing: the class states what it uses,\n * TaskRunner resolves them once where it assembles the object, and a test can pass fakes. Reaching\n * into `context.container` from inside a method instead would leave the class with dependencies\n * nothing can see or substitute.\n */\nexport interface ITaskControlDependencies {\n logger: Logger.Interface;\n identityContext: IdentityContext.Interface;\n taskExecutionContext: TaskExecutionContext.Interface;\n tasksCrud: TasksCrud.Interface;\n taskController: TaskController.Interface;\n getRunnableTaskDefinition: GetRunnableTaskDefinitionUseCase.Interface;\n}\n\nexport class TaskControl implements ITaskControl {\n public readonly runner: ITaskRunner;\n public readonly response: IResponse;\n public readonly context: Context;\n private readonly deps: ITaskControlDependencies;\n\n public constructor(\n runner: ITaskRunner,\n response: IResponse,\n context: Context,\n deps: ITaskControlDependencies\n ) {\n this.runner = runner;\n this.context = context;\n this.response = response;\n this.deps = deps;\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.deps.identityContext.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 definitionResult = this.deps.getRunnableTaskDefinition.execute(task.definitionId);\n if (definitionResult.isFail()) {\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 const definition = definitionResult.value;\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 tasksCrud: this.deps.tasksCrud,\n task,\n log: taskLog,\n databaseLogs\n });\n\n // Populate TaskExecutionContext BEFORE executing task\n const executionContext = this.deps.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 taskController: this.deps.taskController,\n identityContext: this.deps.identityContext\n });\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, definition });\n } catch (ex) {\n this.deps.logger.error(\n { error: getErrorProperties(ex), taskId: task.id, hook: \"onError\" },\n \"Error executing task lifecycle hook.\"\n );\n }\n } else if (result.status === TaskResultStatus.DONE && definition.onDone) {\n try {\n await definition.onDone({ task, definition });\n } catch (ex) {\n this.deps.logger.error(\n { error: getErrorProperties(ex), taskId: task.id, hook: \"onDone\" },\n \"Error executing task lifecycle hook.\"\n );\n }\n }\n }\n\n private async getTask<T extends TaskDefinition.TaskInput>(id: string): Promise<ITask<T>> {\n try {\n const task = await this.deps.tasksCrud.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.deps.tasksCrud.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.deps.tasksCrud.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","deps","event","taskId","task","AuthenticatedIdentity","error","getErrorProperties","definitionResult","definition","databaseLogs","taskLog","TaskDataStatus","store","TaskManagerStore","executionContext","TaskResponse","manager","TaskManager","databaseResponse","DatabaseResponse","result","responseResult","ex","TaskResultStatus","id","params","currentIteration"],"mappings":"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"}
@@ -6,7 +6,7 @@ import { TaskController } from "@webiny/api-core/features/task/TaskController/ab
6
6
  import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
7
7
  import { TaskExecutionContext } from "../features/TaskExecutionContext/index.js";
8
8
  import { TasksCrud } from "../TasksCrud.js";
9
- import { GetTaskDefinitionUseCase } from "../features/GetTaskDefinition/abstractions.js";
9
+ import { GetRunnableTaskDefinitionUseCase } from "../features/GetRunnableTaskDefinition/abstractions.js";
10
10
  const transformMinutesIntoMilliseconds = (minutes)=>60000 * minutes;
11
11
  const DEFAULT_TASKS_TIMEOUT_CLOSE_MINUTES = 3;
12
12
  class TaskRunner {
@@ -43,7 +43,7 @@ class TaskRunner {
43
43
  taskExecutionContext: container.resolve(TaskExecutionContext),
44
44
  tasksCrud: container.resolve(TasksCrud),
45
45
  taskController: container.resolve(TaskController),
46
- getTaskDefinition: container.resolve(GetTaskDefinitionUseCase)
46
+ getRunnableTaskDefinition: container.resolve(GetRunnableTaskDefinitionUseCase)
47
47
  };
48
48
  const logger = deps.logger;
49
49
  const control = new TaskControl(this, response, this.context, deps);
@@ -1 +1 @@
1
- {"version":3,"file":"api/runner/TaskRunner.js","sources":["../../../src/api/runner/TaskRunner.ts"],"sourcesContent":["import type { ITaskEvent, ITaskRawEvent } from \"~/api/handler/types.js\";\nimport type { ITaskEventValidation, ITaskRunner } from \"./abstractions/index.js\";\nimport type { Context } from \"~/api/types.js\";\nimport { Response, ResponseErrorResult } from \"~/api/response/index.js\";\nimport { TaskControl } from \"./TaskControl.js\";\nimport type { IResponseResult } from \"~/api/response/abstractions/index.js\";\nimport { getErrorProperties } from \"~/api/utils/getErrorProperties.js\";\nimport type { Timer } from \"~/api/abstractions/Timer.js\";\nimport { Logger } from \"@webiny/api-core/features/logger/index.js\";\nimport { TaskController } from \"@webiny/api-core/features/task/TaskController/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TaskExecutionContext } from \"~/api/features/TaskExecutionContext/index.js\";\nimport { TasksCrud } from \"~/api/TasksCrud.js\";\nimport { GetTaskDefinitionUseCase } from \"~/api/features/GetTaskDefinition/abstractions.js\";\nimport type { ITaskControlDependencies } from \"./TaskControl.js\";\n\nconst transformMinutesIntoMilliseconds = (minutes: number) => {\n return minutes * 60000;\n};\n\nconst DEFAULT_TASKS_TIMEOUT_CLOSE_MINUTES = 3;\n\nexport class TaskRunner<C extends Context = Context> implements ITaskRunner<C> {\n /**\n * When DI is introduced, these will get injected.\n *\n * container.bind<Request>(\"Request\").toConstantValue(request);\n * @inject(\"Request\") public readonly request: Request;\n *\n * Follow the same example for the rest of the properties.\n */\n public readonly context: C;\n public readonly timer: Timer.Interface;\n private readonly validation: ITaskEventValidation;\n\n /**\n * We take all required variables separately because they will get injected via DI - so less refactoring is required in the future.\n */\n public constructor(context: C, timer: Timer.Interface, validation: ITaskEventValidation) {\n this.context = context;\n this.timer = timer;\n this.validation = validation;\n }\n\n public isCloseToTimeout(seconds?: number) {\n const milliseconds = seconds ? seconds * 1000 : this.getIsCloseToTimeoutMilliseconds();\n return this.timer.getRemainingMilliseconds() < milliseconds;\n }\n\n public async run(rawEvent: ITaskRawEvent): Promise<IResponseResult> {\n const response = new Response({\n ...rawEvent\n });\n\n let event: ITaskEvent;\n try {\n event = this.validation.validate(rawEvent);\n } catch (ex) {\n return response.error({\n error: getErrorProperties(ex)\n });\n }\n response.setEvent(event);\n /**\n * If we received a delay when initiating the task, we need to send the continue response immediately.\n */\n if (rawEvent.delay && rawEvent.delay > 0) {\n return response.continue({\n input: {},\n wait: rawEvent.delay\n });\n }\n\n // Resolved here, where the control's collaborators are assembled. TaskControl is built\n // by hand rather than by DI, so this is the one place that knows how to satisfy it; doing\n // it inside TaskControl's methods instead would leave the class with dependencies nothing\n // reading its signature can see, and nothing in a test can substitute.\n const container = this.context.container;\n const deps: ITaskControlDependencies = {\n logger: container.resolve(Logger),\n identityContext: container.resolve(IdentityContext),\n taskExecutionContext: container.resolve(TaskExecutionContext),\n tasksCrud: container.resolve(TasksCrud),\n taskController: container.resolve(TaskController),\n getTaskDefinition: container.resolve(GetTaskDefinitionUseCase)\n };\n const logger = deps.logger;\n const control = new TaskControl(this, response, this.context, deps);\n\n try {\n const result = await control.run(event);\n if (result instanceof ResponseErrorResult === false) {\n return result;\n }\n logger.error({ taskId: event.webinyTaskId, result }, \"Task returned an error result.\");\n return result;\n } catch (ex) {\n logger.error(\n { error: getErrorProperties(ex), taskId: event.webinyTaskId },\n \"Failed to execute task.\"\n );\n return response.error({\n error: getErrorProperties(ex)\n });\n }\n }\n\n private getIsCloseToTimeoutMilliseconds() {\n const value = parseInt(process.env[\"WEBINY_TASKS_TIMEOUT_CLOSE_MINUTES\"] || \"\");\n const result = value > 0 ? value : DEFAULT_TASKS_TIMEOUT_CLOSE_MINUTES;\n return transformMinutesIntoMilliseconds(result);\n }\n}\n"],"names":["transformMinutesIntoMilliseconds","minutes","DEFAULT_TASKS_TIMEOUT_CLOSE_MINUTES","TaskRunner","context","timer","validation","seconds","milliseconds","rawEvent","response","Response","event","ex","getErrorProperties","container","deps","Logger","IdentityContext","TaskExecutionContext","TasksCrud","TaskController","GetTaskDefinitionUseCase","logger","control","TaskControl","result","ResponseErrorResult","value","parseInt","process"],"mappings":";;;;;;;;;AAgBA,MAAMA,mCAAmC,CAACC,UAC/BA,AAAU,QAAVA;AAGX,MAAMC,sCAAsC;AAErC,MAAMC;IAgBT,YAAmBC,OAAU,EAAEC,KAAsB,EAAEC,UAAgC,CAAE;QACrF,IAAI,CAAC,OAAO,GAAGF;QACf,IAAI,CAAC,KAAK,GAAGC;QACb,IAAI,CAAC,UAAU,GAAGC;IACtB;IAEO,iBAAiBC,OAAgB,EAAE;QACtC,MAAMC,eAAeD,UAAUA,AAAU,OAAVA,UAAiB,IAAI,CAAC,+BAA+B;QACpF,OAAO,IAAI,CAAC,KAAK,CAAC,wBAAwB,KAAKC;IACnD;IAEA,MAAa,IAAIC,QAAuB,EAA4B;QAChE,MAAMC,WAAW,IAAIC,SAAS;YAC1B,GAAGF,QAAQ;QACf;QAEA,IAAIG;QACJ,IAAI;YACAA,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAACH;QACrC,EAAE,OAAOI,IAAI;YACT,OAAOH,SAAS,KAAK,CAAC;gBAClB,OAAOI,mBAAmBD;YAC9B;QACJ;QACAH,SAAS,QAAQ,CAACE;QAIlB,IAAIH,SAAS,KAAK,IAAIA,SAAS,KAAK,GAAG,GACnC,OAAOC,SAAS,QAAQ,CAAC;YACrB,OAAO,CAAC;YACR,MAAMD,SAAS,KAAK;QACxB;QAOJ,MAAMM,YAAY,IAAI,CAAC,OAAO,CAAC,SAAS;QACxC,MAAMC,OAAiC;YACnC,QAAQD,UAAU,OAAO,CAACE;YAC1B,iBAAiBF,UAAU,OAAO,CAACG;YACnC,sBAAsBH,UAAU,OAAO,CAACI;YACxC,WAAWJ,UAAU,OAAO,CAACK;YAC7B,gBAAgBL,UAAU,OAAO,CAACM;YAClC,mBAAmBN,UAAU,OAAO,CAACO;QACzC;QACA,MAAMC,SAASP,KAAK,MAAM;QAC1B,MAAMQ,UAAU,IAAIC,YAAY,IAAI,EAAEf,UAAU,IAAI,CAAC,OAAO,EAAEM;QAE9D,IAAI;YACA,MAAMU,SAAS,MAAMF,QAAQ,GAAG,CAACZ;YACjC,IAAIc,kBAAkBC,wBAAwB,OAC1C,OAAOD;YAEXH,OAAO,KAAK,CAAC;gBAAE,QAAQX,MAAM,YAAY;gBAAEc;YAAO,GAAG;YACrD,OAAOA;QACX,EAAE,OAAOb,IAAI;YACTU,OAAO,KAAK,CACR;gBAAE,OAAOT,mBAAmBD;gBAAK,QAAQD,MAAM,YAAY;YAAC,GAC5D;YAEJ,OAAOF,SAAS,KAAK,CAAC;gBAClB,OAAOI,mBAAmBD;YAC9B;QACJ;IACJ;IAEQ,kCAAkC;QACtC,MAAMe,QAAQC,SAASC,QAAQ,GAAG,CAAC,qCAAqC,IAAI;QAC5E,MAAMJ,SAASE,QAAQ,IAAIA,QAAQ1B;QACnC,OAAOF,iCAAiC0B;IAC5C;AACJ"}
1
+ {"version":3,"file":"api/runner/TaskRunner.js","sources":["../../../src/api/runner/TaskRunner.ts"],"sourcesContent":["import type { ITaskEvent, ITaskRawEvent } from \"~/api/handler/types.js\";\nimport type { ITaskEventValidation, ITaskRunner } from \"./abstractions/index.js\";\nimport type { Context } from \"~/api/types.js\";\nimport { Response, ResponseErrorResult } from \"~/api/response/index.js\";\nimport { TaskControl } from \"./TaskControl.js\";\nimport type { IResponseResult } from \"~/api/response/abstractions/index.js\";\nimport { getErrorProperties } from \"~/api/utils/getErrorProperties.js\";\nimport type { Timer } from \"~/api/abstractions/Timer.js\";\nimport { Logger } from \"@webiny/api-core/features/logger/index.js\";\nimport { TaskController } from \"@webiny/api-core/features/task/TaskController/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TaskExecutionContext } from \"~/api/features/TaskExecutionContext/index.js\";\nimport { TasksCrud } from \"~/api/TasksCrud.js\";\nimport { GetRunnableTaskDefinitionUseCase } from \"~/api/features/GetRunnableTaskDefinition/abstractions.js\";\nimport type { ITaskControlDependencies } from \"./TaskControl.js\";\n\nconst transformMinutesIntoMilliseconds = (minutes: number) => {\n return minutes * 60000;\n};\n\nconst DEFAULT_TASKS_TIMEOUT_CLOSE_MINUTES = 3;\n\nexport class TaskRunner<C extends Context = Context> implements ITaskRunner<C> {\n /**\n * When DI is introduced, these will get injected.\n *\n * container.bind<Request>(\"Request\").toConstantValue(request);\n * @inject(\"Request\") public readonly request: Request;\n *\n * Follow the same example for the rest of the properties.\n */\n public readonly context: C;\n public readonly timer: Timer.Interface;\n private readonly validation: ITaskEventValidation;\n\n /**\n * We take all required variables separately because they will get injected via DI - so less refactoring is required in the future.\n */\n public constructor(context: C, timer: Timer.Interface, validation: ITaskEventValidation) {\n this.context = context;\n this.timer = timer;\n this.validation = validation;\n }\n\n public isCloseToTimeout(seconds?: number) {\n const milliseconds = seconds ? seconds * 1000 : this.getIsCloseToTimeoutMilliseconds();\n return this.timer.getRemainingMilliseconds() < milliseconds;\n }\n\n public async run(rawEvent: ITaskRawEvent): Promise<IResponseResult> {\n const response = new Response({\n ...rawEvent\n });\n\n let event: ITaskEvent;\n try {\n event = this.validation.validate(rawEvent);\n } catch (ex) {\n return response.error({\n error: getErrorProperties(ex)\n });\n }\n response.setEvent(event);\n /**\n * If we received a delay when initiating the task, we need to send the continue response immediately.\n */\n if (rawEvent.delay && rawEvent.delay > 0) {\n return response.continue({\n input: {},\n wait: rawEvent.delay\n });\n }\n\n // Resolved here, where the control's collaborators are assembled. TaskControl is built\n // by hand rather than by DI, so this is the one place that knows how to satisfy it; doing\n // it inside TaskControl's methods instead would leave the class with dependencies nothing\n // reading its signature can see, and nothing in a test can substitute.\n const container = this.context.container;\n const deps: ITaskControlDependencies = {\n logger: container.resolve(Logger),\n identityContext: container.resolve(IdentityContext),\n taskExecutionContext: container.resolve(TaskExecutionContext),\n tasksCrud: container.resolve(TasksCrud),\n taskController: container.resolve(TaskController),\n getRunnableTaskDefinition: container.resolve(GetRunnableTaskDefinitionUseCase)\n };\n const logger = deps.logger;\n const control = new TaskControl(this, response, this.context, deps);\n\n try {\n const result = await control.run(event);\n if (result instanceof ResponseErrorResult === false) {\n return result;\n }\n logger.error({ taskId: event.webinyTaskId, result }, \"Task returned an error result.\");\n return result;\n } catch (ex) {\n logger.error(\n { error: getErrorProperties(ex), taskId: event.webinyTaskId },\n \"Failed to execute task.\"\n );\n return response.error({\n error: getErrorProperties(ex)\n });\n }\n }\n\n private getIsCloseToTimeoutMilliseconds() {\n const value = parseInt(process.env[\"WEBINY_TASKS_TIMEOUT_CLOSE_MINUTES\"] || \"\");\n const result = value > 0 ? value : DEFAULT_TASKS_TIMEOUT_CLOSE_MINUTES;\n return transformMinutesIntoMilliseconds(result);\n }\n}\n"],"names":["transformMinutesIntoMilliseconds","minutes","DEFAULT_TASKS_TIMEOUT_CLOSE_MINUTES","TaskRunner","context","timer","validation","seconds","milliseconds","rawEvent","response","Response","event","ex","getErrorProperties","container","deps","Logger","IdentityContext","TaskExecutionContext","TasksCrud","TaskController","GetRunnableTaskDefinitionUseCase","logger","control","TaskControl","result","ResponseErrorResult","value","parseInt","process"],"mappings":";;;;;;;;;AAgBA,MAAMA,mCAAmC,CAACC,UAC/BA,AAAU,QAAVA;AAGX,MAAMC,sCAAsC;AAErC,MAAMC;IAgBT,YAAmBC,OAAU,EAAEC,KAAsB,EAAEC,UAAgC,CAAE;QACrF,IAAI,CAAC,OAAO,GAAGF;QACf,IAAI,CAAC,KAAK,GAAGC;QACb,IAAI,CAAC,UAAU,GAAGC;IACtB;IAEO,iBAAiBC,OAAgB,EAAE;QACtC,MAAMC,eAAeD,UAAUA,AAAU,OAAVA,UAAiB,IAAI,CAAC,+BAA+B;QACpF,OAAO,IAAI,CAAC,KAAK,CAAC,wBAAwB,KAAKC;IACnD;IAEA,MAAa,IAAIC,QAAuB,EAA4B;QAChE,MAAMC,WAAW,IAAIC,SAAS;YAC1B,GAAGF,QAAQ;QACf;QAEA,IAAIG;QACJ,IAAI;YACAA,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAACH;QACrC,EAAE,OAAOI,IAAI;YACT,OAAOH,SAAS,KAAK,CAAC;gBAClB,OAAOI,mBAAmBD;YAC9B;QACJ;QACAH,SAAS,QAAQ,CAACE;QAIlB,IAAIH,SAAS,KAAK,IAAIA,SAAS,KAAK,GAAG,GACnC,OAAOC,SAAS,QAAQ,CAAC;YACrB,OAAO,CAAC;YACR,MAAMD,SAAS,KAAK;QACxB;QAOJ,MAAMM,YAAY,IAAI,CAAC,OAAO,CAAC,SAAS;QACxC,MAAMC,OAAiC;YACnC,QAAQD,UAAU,OAAO,CAACE;YAC1B,iBAAiBF,UAAU,OAAO,CAACG;YACnC,sBAAsBH,UAAU,OAAO,CAACI;YACxC,WAAWJ,UAAU,OAAO,CAACK;YAC7B,gBAAgBL,UAAU,OAAO,CAACM;YAClC,2BAA2BN,UAAU,OAAO,CAACO;QACjD;QACA,MAAMC,SAASP,KAAK,MAAM;QAC1B,MAAMQ,UAAU,IAAIC,YAAY,IAAI,EAAEf,UAAU,IAAI,CAAC,OAAO,EAAEM;QAE9D,IAAI;YACA,MAAMU,SAAS,MAAMF,QAAQ,GAAG,CAACZ;YACjC,IAAIc,kBAAkBC,wBAAwB,OAC1C,OAAOD;YAEXH,OAAO,KAAK,CAAC;gBAAE,QAAQX,MAAM,YAAY;gBAAEc;YAAO,GAAG;YACrD,OAAOA;QACX,EAAE,OAAOb,IAAI;YACTU,OAAO,KAAK,CACR;gBAAE,OAAOT,mBAAmBD;gBAAK,QAAQD,MAAM,YAAY;YAAC,GAC5D;YAEJ,OAAOF,SAAS,KAAK,CAAC;gBAClB,OAAOI,mBAAmBD;YAC9B;QACJ;IACJ;IAEQ,kCAAkC;QACtC,MAAMe,QAAQC,SAASC,QAAQ,GAAG,CAAC,qCAAqC,IAAI;QAC5E,MAAMJ,SAASE,QAAQ,IAAIA,QAAQ1B;QACnC,OAAOF,iCAAiC0B;IAC5C;AACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/background-tasks",
3
- "version": "6.6.0-alpha.3",
3
+ "version": "6.6.0-alpha.4",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -21,20 +21,20 @@
21
21
  "dependencies": {
22
22
  "@graphql-tools/merge": "9.2.3",
23
23
  "@graphql-tools/schema": "10.1.0",
24
- "@webiny/admin-ui": "6.6.0-alpha.3",
25
- "@webiny/api": "6.6.0-alpha.3",
26
- "@webiny/api-core": "6.6.0-alpha.3",
27
- "@webiny/api-graphql": "6.6.0-alpha.3",
28
- "@webiny/api-headless-cms": "6.6.0-alpha.3",
29
- "@webiny/app": "6.6.0-alpha.3",
30
- "@webiny/app-admin": "6.6.0-alpha.3",
31
- "@webiny/error": "6.6.0-alpha.3",
32
- "@webiny/feature": "6.6.0-alpha.3",
33
- "@webiny/handler": "6.6.0-alpha.3",
34
- "@webiny/icons": "6.6.0-alpha.3",
35
- "@webiny/plugins": "6.6.0-alpha.3",
36
- "@webiny/sdk": "6.6.0-alpha.3",
37
- "@webiny/utils": "6.6.0-alpha.3",
24
+ "@webiny/admin-ui": "6.6.0-alpha.4",
25
+ "@webiny/api": "6.6.0-alpha.4",
26
+ "@webiny/api-core": "6.6.0-alpha.4",
27
+ "@webiny/api-graphql": "6.6.0-alpha.4",
28
+ "@webiny/api-headless-cms": "6.6.0-alpha.4",
29
+ "@webiny/app": "6.6.0-alpha.4",
30
+ "@webiny/app-admin": "6.6.0-alpha.4",
31
+ "@webiny/error": "6.6.0-alpha.4",
32
+ "@webiny/feature": "6.6.0-alpha.4",
33
+ "@webiny/handler": "6.6.0-alpha.4",
34
+ "@webiny/icons": "6.6.0-alpha.4",
35
+ "@webiny/plugins": "6.6.0-alpha.4",
36
+ "@webiny/sdk": "6.6.0-alpha.4",
37
+ "@webiny/utils": "6.6.0-alpha.4",
38
38
  "deep-equal": "2.2.3",
39
39
  "graphql": "16.14.2",
40
40
  "lodash": "4.18.1",
@@ -47,11 +47,11 @@
47
47
  "zod": "4.4.3"
48
48
  },
49
49
  "devDependencies": {
50
- "@webiny/api-core-testing": "6.6.0-alpha.3",
51
- "@webiny/build-tools": "6.6.0-alpha.3",
50
+ "@webiny/api-core-testing": "6.6.0-alpha.4",
51
+ "@webiny/build-tools": "6.6.0-alpha.4",
52
52
  "@webiny/di": "1.1.0",
53
- "@webiny/event-handler-core": "6.6.0-alpha.3",
54
- "@webiny/wcp": "6.6.0-alpha.3",
53
+ "@webiny/event-handler-core": "6.6.0-alpha.4",
54
+ "@webiny/wcp": "6.6.0-alpha.4",
55
55
  "rimraf": "6.1.3",
56
56
  "type-fest": "5.8.0",
57
57
  "typescript": "7.0.2",
@@ -1,33 +0,0 @@
1
- import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
2
- import type { ITaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
3
- /**
4
- * RunnableTaskDecorator adds runtime behavior to TaskDefinition:
5
- * - Applies default values (maxIterations, isPrivate, databaseLogs, fields)
6
- * - Validates task ID (must be camelCase)
7
- * - Provides field management methods
8
- */
9
- declare class RunnableTaskDecoratorImpl implements TaskDefinition.Interface {
10
- private decoratee;
11
- constructor(decoratee: TaskDefinition.Interface);
12
- get id(): string;
13
- get title(): string;
14
- get description(): string | undefined;
15
- get isPrivate(): boolean;
16
- get databaseLogs(): boolean;
17
- get maxIterations(): number;
18
- get selfCleanup(): import("@webiny/api-core/features/task/TaskDefinition/abstractions").ISelfCleanup | undefined;
19
- get createInputValidation(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskCreateInputValidationParams) => import("@webiny/api/types").GenericRecord<PropertyKey, import("zod").ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>> | import("zod").ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>) | undefined;
20
- get handler(): import("@webiny/di").Constructor<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskHandler<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>> | undefined;
21
- get run(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskRunParams<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>) => Promise<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskResult<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>) | undefined;
22
- get onBeforeTrigger(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskBeforeTriggerParams<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput>) => Promise<void>) | undefined;
23
- get onDone(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskLifecycleHook<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>) => Promise<void>) | undefined;
24
- get onError(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskLifecycleHook<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>) => Promise<void>) | undefined;
25
- get onAbort(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskLifecycleHook<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>) => Promise<void>) | undefined;
26
- get onMaxIterations(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskLifecycleHook<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>) => Promise<void>) | undefined;
27
- private validate;
28
- getTask(): ITaskDefinition;
29
- }
30
- export declare const RunnableTaskDecorator: typeof RunnableTaskDecoratorImpl & {
31
- __abstraction: import("@webiny/di").Abstraction<ITaskDefinition<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
32
- };
33
- export {};
@@ -1 +0,0 @@
1
- {"version":3,"file":"api/decorators/RunnableTaskDecorator.js","sources":["../../../src/api/decorators/RunnableTaskDecorator.ts"],"sourcesContent":["import camelCase from \"lodash/camelCase.js\";\nimport WebinyError from \"@webiny/error\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport type { ITaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\nconst DEFAULT_MAX_ITERATIONS = 50;\n\n/**\n * RunnableTaskDecorator adds runtime behavior to TaskDefinition:\n * - Applies default values (maxIterations, isPrivate, databaseLogs, fields)\n * - Validates task ID (must be camelCase)\n * - Provides field management methods\n */\nclass RunnableTaskDecoratorImpl implements TaskDefinition.Interface {\n constructor(private decoratee: TaskDefinition.Interface) {\n this.validate();\n }\n\n // Delegate simple properties\n get id() {\n return this.decoratee.id;\n }\n\n get title() {\n return this.decoratee.title;\n }\n\n get description() {\n return this.decoratee.description;\n }\n\n // Apply default values\n get isPrivate() {\n return this.decoratee.isPrivate || false;\n }\n\n get databaseLogs() {\n return this.decoratee.databaseLogs || false;\n }\n\n get maxIterations() {\n return this.decoratee.maxIterations || DEFAULT_MAX_ITERATIONS;\n }\n\n get selfCleanup() {\n return this.decoratee.selfCleanup;\n }\n\n get createInputValidation() {\n return this.decoratee.createInputValidation;\n }\n\n // A definition that delegates to a `handler` class has no `run` of its own — the handler\n // supplies it, and GetTaskDefinitionUseCase merges the two halves after this decorator runs.\n get handler() {\n return this.decoratee.handler;\n }\n\n // Delegate lifecycle methods (bind to preserve context)\n get run() {\n return this.decoratee.run?.bind(this.decoratee);\n }\n\n get onBeforeTrigger() {\n return this.decoratee.onBeforeTrigger?.bind(this.decoratee);\n }\n\n get onDone() {\n return this.decoratee.onDone?.bind(this.decoratee);\n }\n\n get onError() {\n return this.decoratee.onError?.bind(this.decoratee);\n }\n\n get onAbort() {\n return this.decoratee.onAbort?.bind(this.decoratee);\n }\n\n get onMaxIterations() {\n return this.decoratee.onMaxIterations?.bind(this.decoratee);\n }\n\n // Validation logic\n private validate(): void {\n if (camelCase(this.decoratee.id) !== this.decoratee.id) {\n throw new WebinyError(\n `Task ID \"${this.decoratee.id}\" is invalid. It must be in camelCase format, for example: \"myCustomTask\".`\n );\n }\n }\n\n // Method to get the underlying task (for compatibility with existing code)\n public getTask(): ITaskDefinition {\n return this;\n }\n}\n\nexport const RunnableTaskDecorator = TaskDefinition.createDecorator({\n decorator: RunnableTaskDecoratorImpl,\n dependencies: []\n});\n"],"names":["DEFAULT_MAX_ITERATIONS","RunnableTaskDecoratorImpl","decoratee","camelCase","WebinyError","RunnableTaskDecorator","TaskDefinition"],"mappings":";;;AAKA,MAAMA,yBAAyB;AAQ/B,MAAMC;IACF,YAAoBC,SAAmC,CAAE;aAArCA,SAAS,GAATA;QAChB,IAAI,CAAC,QAAQ;IACjB;IAGA,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE;IAC5B;IAEA,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK;IAC/B;IAEA,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW;IACrC;IAGA,IAAI,YAAY;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI;IACvC;IAEA,IAAI,eAAe;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI;IAC1C;IAEA,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,IAAIF;IAC3C;IAEA,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW;IACrC;IAEA,IAAI,wBAAwB;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,qBAAqB;IAC/C;IAIA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO;IACjC;IAGA,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,SAAS;IAClD;IAEA,IAAI,kBAAkB;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,SAAS;IAC9D;IAEA,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,SAAS;IACrD;IAEA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC,SAAS;IACtD;IAEA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC,SAAS;IACtD;IAEA,IAAI,kBAAkB;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,SAAS;IAC9D;IAGQ,WAAiB;QACrB,IAAIG,UAAU,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,EAClD,MAAM,IAAIC,MACN,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,0EAA0E,CAAC;IAGrH;IAGO,UAA2B;QAC9B,OAAO,IAAI;IACf;AACJ;AAEO,MAAMC,wBAAwBC,eAAe,eAAe,CAAC;IAChE,WAAWL;IACX,cAAc,EAAE;AACpB"}
@@ -1,33 +0,0 @@
1
- import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
2
- import { Logger } from "@webiny/api-core/features/logger/index.js";
3
- import { CleanupTaskSubtreeUseCase } from "../../api/features/CleanupTaskSubtree/index.js";
4
- type LifecycleHook = TaskDefinition.Interface["onDone"];
5
- type HookParams = Parameters<NonNullable<LifecycleHook>>[0];
6
- export declare class SelfCleaningTaskDecoratorImpl implements TaskDefinition.Interface {
7
- private readonly cleanupTaskSubtree;
8
- private readonly logger;
9
- private decoratee;
10
- private readonly events;
11
- constructor(cleanupTaskSubtree: CleanupTaskSubtreeUseCase.Interface, logger: Logger.Interface, decoratee: TaskDefinition.Interface);
12
- get handler(): import("@webiny/di").Constructor<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskHandler<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>> | undefined;
13
- get id(): string;
14
- get title(): string;
15
- get description(): string | undefined;
16
- get isPrivate(): boolean | undefined;
17
- get maxIterations(): number | undefined;
18
- get selfCleanup(): import("@webiny/api-core/features/task/TaskDefinition/abstractions").ISelfCleanup | undefined;
19
- get createInputValidation(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskCreateInputValidationParams) => import("@webiny/api/types").GenericRecord<PropertyKey, import("zod").ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>> | import("zod").ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>) | undefined;
20
- get run(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskRunParams<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>) => Promise<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskResult<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>) | undefined;
21
- get onBeforeTrigger(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskBeforeTriggerParams<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput>) => Promise<void>) | undefined;
22
- get onMaxIterations(): ((params: import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskLifecycleHook<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>) => Promise<void>) | undefined;
23
- get databaseLogs(): boolean | undefined;
24
- get onDone(): (params: HookParams) => Promise<void>;
25
- get onError(): (params: HookParams) => Promise<void>;
26
- get onAbort(): (params: HookParams) => Promise<void>;
27
- private runCleanup;
28
- private safeCall;
29
- }
30
- export declare const SelfCleaningTaskDecorator: typeof SelfCleaningTaskDecoratorImpl & {
31
- __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskDefinition<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
32
- };
33
- export {};
@@ -1 +0,0 @@
1
- {"version":3,"file":"api/decorators/SelfCleaningTaskDecorator.js","sources":["../../../src/api/decorators/SelfCleaningTaskDecorator.ts"],"sourcesContent":["import { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { Logger } from \"@webiny/api-core/features/logger/index.js\";\nimport type { ISelfCleanupEvent } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { normalizeSelfCleanup } from \"~/api/utils/normalizeSelfCleanup.js\";\nimport { CleanupTaskSubtreeUseCase } from \"~/api/features/CleanupTaskSubtree/index.js\";\nimport { getErrorProperties } from \"~/api/utils/getErrorProperties.js\";\n\ntype LifecycleHook = TaskDefinition.Interface[\"onDone\"];\ntype HookParams = Parameters<NonNullable<LifecycleHook>>[0];\n\nexport class SelfCleaningTaskDecoratorImpl implements TaskDefinition.Interface {\n private readonly events: ReadonlySet<ISelfCleanupEvent>;\n\n public constructor(\n private readonly cleanupTaskSubtree: CleanupTaskSubtreeUseCase.Interface,\n private readonly logger: Logger.Interface,\n private decoratee: TaskDefinition.Interface\n ) {\n this.events = normalizeSelfCleanup(decoratee.selfCleanup);\n }\n\n // A definition that delegates to a `handler` class has no `run` of its own.\n get handler() {\n return this.decoratee.handler;\n }\n\n // Pass-through properties.\n get id() {\n return this.decoratee.id;\n }\n get title() {\n return this.decoratee.title;\n }\n get description() {\n return this.decoratee.description;\n }\n get isPrivate() {\n return this.decoratee.isPrivate;\n }\n get maxIterations() {\n return this.decoratee.maxIterations;\n }\n get selfCleanup() {\n return this.decoratee.selfCleanup;\n }\n get createInputValidation() {\n return this.decoratee.createInputValidation;\n }\n get run() {\n return this.decoratee.run?.bind(this.decoratee);\n }\n get onBeforeTrigger() {\n return this.decoratee.onBeforeTrigger?.bind(this.decoratee);\n }\n get onMaxIterations() {\n return this.decoratee.onMaxIterations?.bind(this.decoratee);\n }\n\n // databaseLogs override — any non-empty event set forces false.\n get databaseLogs() {\n if (this.events.size > 0) {\n return false;\n }\n return this.decoratee.databaseLogs;\n }\n\n // Always-defined lifecycle hooks. Each runs the user's hook first, then\n // triggers cleanup if the matching event is in the set.\n get onDone() {\n return async (params: HookParams) => {\n await this.safeCall(this.decoratee.onDone, params, \"onDone\");\n if (this.events.has(\"onSuccess\")) {\n await this.runCleanup(params);\n }\n };\n }\n\n get onError() {\n return async (params: HookParams) => {\n await this.safeCall(this.decoratee.onError, params, \"onError\");\n if (this.events.has(\"onError\")) {\n await this.runCleanup(params);\n }\n };\n }\n\n get onAbort() {\n return async (params: HookParams) => {\n await this.safeCall(this.decoratee.onAbort, params, \"onAbort\");\n if (this.events.has(\"onAbort\")) {\n await this.runCleanup(params);\n }\n };\n }\n\n private async runCleanup(params: HookParams): Promise<void> {\n await this.cleanupTaskSubtree.execute(params.task.id);\n }\n\n private async safeCall(\n hook: LifecycleHook | undefined,\n params: HookParams,\n name: string\n ): Promise<void> {\n if (!hook) {\n return;\n }\n try {\n await hook.call(this.decoratee, params);\n } catch (ex) {\n this.logger.error(\n { error: getErrorProperties(ex), taskId: params.task.id, hook: name },\n \"Error executing task lifecycle hook.\"\n );\n }\n }\n}\n\nexport const SelfCleaningTaskDecorator = TaskDefinition.createDecorator({\n decorator: SelfCleaningTaskDecoratorImpl,\n dependencies: [CleanupTaskSubtreeUseCase, Logger]\n});\n"],"names":["SelfCleaningTaskDecoratorImpl","cleanupTaskSubtree","logger","decoratee","normalizeSelfCleanup","params","hook","name","ex","getErrorProperties","SelfCleaningTaskDecorator","TaskDefinition","CleanupTaskSubtreeUseCase","Logger"],"mappings":";;;;;AAUO,MAAMA;IAGT,YACqBC,kBAAuD,EACvDC,MAAwB,EACjCC,SAAmC,CAC7C;aAHmBF,kBAAkB,GAAlBA;aACAC,MAAM,GAANA;aACTC,SAAS,GAATA;QAER,IAAI,CAAC,MAAM,GAAGC,qBAAqBD,UAAU,WAAW;IAC5D;IAGA,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO;IACjC;IAGA,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE;IAC5B;IACA,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK;IAC/B;IACA,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW;IACrC;IACA,IAAI,YAAY;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS;IACnC;IACA,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa;IACvC;IACA,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW;IACrC;IACA,IAAI,wBAAwB;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,qBAAqB;IAC/C;IACA,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,SAAS;IAClD;IACA,IAAI,kBAAkB;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,SAAS;IAC9D;IACA,IAAI,kBAAkB;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,SAAS;IAC9D;IAGA,IAAI,eAAe;QACf,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,GACnB,OAAO;QAEX,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY;IACtC;IAIA,IAAI,SAAS;QACT,OAAO,OAAOE;YACV,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAEA,QAAQ;YACnD,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAChB,MAAM,IAAI,CAAC,UAAU,CAACA;QAE9B;IACJ;IAEA,IAAI,UAAU;QACV,OAAO,OAAOA;YACV,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAEA,QAAQ;YACpD,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAChB,MAAM,IAAI,CAAC,UAAU,CAACA;QAE9B;IACJ;IAEA,IAAI,UAAU;QACV,OAAO,OAAOA;YACV,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAEA,QAAQ;YACpD,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAChB,MAAM,IAAI,CAAC,UAAU,CAACA;QAE9B;IACJ;IAEA,MAAc,WAAWA,MAAkB,EAAiB;QACxD,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAACA,OAAO,IAAI,CAAC,EAAE;IACxD;IAEA,MAAc,SACVC,IAA+B,EAC/BD,MAAkB,EAClBE,IAAY,EACC;QACb,IAAI,CAACD,MACD;QAEJ,IAAI;YACA,MAAMA,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,EAAED;QACpC,EAAE,OAAOG,IAAI;YACT,IAAI,CAAC,MAAM,CAAC,KAAK,CACb;gBAAE,OAAOC,mBAAmBD;gBAAK,QAAQH,OAAO,IAAI,CAAC,EAAE;gBAAE,MAAME;YAAK,GACpE;QAER;IACJ;AACJ;AAEO,MAAMG,4BAA4BC,eAAe,eAAe,CAAC;IACpE,WAAWX;IACX,cAAc;QAACY;QAA2BC;KAAO;AACrD"}
@@ -1,88 +0,0 @@
1
- import { Result } from "@webiny/feature/api";
2
- import { GetTaskDefinitionUseCase } from "./abstractions.js";
3
- import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
4
- import { TaskHandlerResolver } from "../TaskHandlerResolver/index.js";
5
- import { Logger } from "@webiny/api-core/features/logger/index.js";
6
- import { TaskDefinitionNotFoundError, TaskDefinitionNotRunnableError } from "../../domain/errors.js";
7
- class GetTaskDefinitionUseCaseImpl {
8
- constructor(definitions, handlerResolver, logger){
9
- this.definitions = definitions;
10
- this.handlerResolver = handlerResolver;
11
- this.logger = logger;
12
- }
13
- execute(id) {
14
- for (const definition of this.definitions)if (definition.id === id) {
15
- if (definition.handler) {
16
- const handlerClass = definition.handler;
17
- const handler = this.handlerResolver.resolve(handlerClass);
18
- const runnable = toRunnable(definition, handler, this.logger);
19
- return Result.ok(runnable);
20
- }
21
- if ("function" == typeof definition.run) {
22
- const runnable = definition;
23
- return Result.ok(runnable);
24
- }
25
- return Result.fail(new TaskDefinitionNotRunnableError(id));
26
- }
27
- return Result.fail(new TaskDefinitionNotFoundError(id));
28
- }
29
- }
30
- const SWALLOWED_HOOKS = new Set([
31
- "onDone",
32
- "onError",
33
- "onAbort"
34
- ]);
35
- const toRunnable = (definition, handler, logger)=>{
36
- const chain = (name)=>{
37
- const own = handler[name]?.bind(handler);
38
- const decorated = definition[name]?.bind(definition);
39
- if (!own && !decorated) return;
40
- return async (params)=>{
41
- let failure;
42
- if (own) try {
43
- await own(params);
44
- } catch (error) {
45
- if (SWALLOWED_HOOKS.has(name)) logger.error({
46
- error,
47
- taskId: definition.id,
48
- hook: name
49
- }, "Error executing task lifecycle hook.");
50
- else failure = error;
51
- }
52
- await decorated?.(params);
53
- if (failure) throw failure;
54
- };
55
- };
56
- return {
57
- id: definition.id,
58
- title: definition.title,
59
- description: definition.description,
60
- isPrivate: definition.isPrivate,
61
- databaseLogs: definition.databaseLogs,
62
- maxIterations: definition.maxIterations,
63
- selfCleanup: definition.selfCleanup,
64
- run: handler.run.bind(handler),
65
- onBeforeTrigger: chain("onBeforeTrigger"),
66
- onDone: chain("onDone"),
67
- onError: chain("onError"),
68
- onAbort: chain("onAbort"),
69
- onMaxIterations: chain("onMaxIterations"),
70
- createInputValidation: handler.createInputValidation?.bind(handler)
71
- };
72
- };
73
- const GetTaskDefinitionUseCase_GetTaskDefinitionUseCase = GetTaskDefinitionUseCase.createImplementation({
74
- implementation: GetTaskDefinitionUseCaseImpl,
75
- dependencies: [
76
- [
77
- TaskDefinition,
78
- {
79
- multiple: true
80
- }
81
- ],
82
- TaskHandlerResolver,
83
- Logger
84
- ]
85
- });
86
- export { GetTaskDefinitionUseCaseImpl, GetTaskDefinitionUseCase_GetTaskDefinitionUseCase as GetTaskDefinitionUseCase };
87
-
88
- //# sourceMappingURL=GetTaskDefinitionUseCase.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"api/features/GetTaskDefinition/GetTaskDefinitionUseCase.js","sources":["../../../../src/api/features/GetTaskDefinition/GetTaskDefinitionUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport type { Constructor } from \"@webiny/di\";\nimport { GetTaskDefinitionUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { TaskHandlerResolver } from \"~/api/features/TaskHandlerResolver/index.js\";\nimport { Logger } from \"@webiny/api-core/features/logger/index.js\";\nimport {\n TaskDefinitionNotFoundError,\n TaskDefinitionNotRunnableError\n} from \"~/api/domain/errors.js\";\n\nexport class GetTaskDefinitionUseCaseImpl implements UseCaseAbstraction.Interface {\n public constructor(\n private definitions: TaskDefinition.Interface[],\n private handlerResolver: TaskHandlerResolver.Interface,\n private logger: Logger.Interface\n ) {}\n\n public execute<\n I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput,\n O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput\n >(id: string): Result<TaskDefinition.Runnable<I, O>, UseCaseAbstraction.Error> {\n for (const definition of this.definitions) {\n if (definition.id !== id) {\n continue;\n }\n\n // New shape: the definition names a handler class, built only now that we know this is\n // the task being asked for. Its dependencies are never touched for the other 23.\n if (definition.handler) {\n // The registered definition is stored under the abstraction's default generics, so\n // its handler cannot be proven assignable to the caller's narrower <I, O>. Same\n // reason the legacy branch below casts.\n const handlerClass = definition.handler as Constructor<\n TaskDefinition.Handler<I, O>\n >;\n const handler = this.handlerResolver.resolve(handlerClass);\n const runnable = toRunnable<I, O>(definition, handler, this.logger);\n\n return Result.ok(runnable);\n }\n\n // Old shape: the definition carries `run()` and the hooks itself, so it IS the handler.\n if (typeof definition.run === \"function\") {\n const runnable = definition as TaskDefinition.Runnable<I, O>;\n\n return Result.ok(runnable);\n }\n\n return Result.fail(new TaskDefinitionNotRunnableError(id));\n }\n\n return Result.fail(new TaskDefinitionNotFoundError(id));\n }\n}\n\ntype HookName = \"onBeforeTrigger\" | \"onDone\" | \"onError\" | \"onAbort\" | \"onMaxIterations\";\n\n/** Hooks a single-object definition already swallows, via SelfCleaningTaskDecorator's safeCall. */\nconst SWALLOWED_HOOKS: ReadonlySet<HookName> = new Set([\"onDone\", \"onError\", \"onAbort\"]);\n\n/**\n * Present the two halves as the single object the runner and `context.tasks.getDefinition()` expect.\n * Metadata reads come from the definition, behaviour from the handler.\n *\n * Hooks come from BOTH, in that order, because they mean different things. The handler's hook is the\n * task author's, and the definition's is whatever a decorator added: `SelfCleaningTaskDecorator`\n * supplies an `onDone` that deletes the finished task. Taking only the handler's would silently drop\n * every definition-level decorator, and taking only the definition's would drop the task's own.\n *\n * A throwing handler hook must not stop the decorator's half from running, so the decorator's half\n * runs either way. What happens to the error afterwards follows what a single-object definition\n * already does, which differs per hook:\n *\n * - `onDone`, `onError`, `onAbort` are swallowed and logged, because `SelfCleaningTaskDecorator`\n * routes them through its own `safeCall` and does exactly that;\n * - `onBeforeTrigger` and `onMaxIterations` are rethrown, because the decorator passes those\n * straight through and their callers rely on the throw. A throwing `onBeforeTrigger` aborts the\n * trigger, and a throwing `onMaxIterations` is what makes `TaskManager` answer with \"Failed to\n * execute onMaxIterations handler.\" Swallowing either would silently change behaviour for a task\n * that moved to a handler.\n *\n * TRANSITIONAL. The chaining exists only because a definition can still carry hooks. It should not:\n * a hook needs dependencies, and dependencies on a definition are what make looking one up by id\n * expensive, which is the thing this whole split is removing. The final PR moves hooks onto handlers\n * only, at which point this function takes them from the handler and the definition contributes\n * metadata alone. `SelfCleaningTaskDecorator` splits to follow: its `databaseLogs` override stays a\n * definition decorator, and its cleanup hooks become a `TaskHandler` decorator reading\n * `params.definition.selfCleanup`.\n */\nconst toRunnable = <I extends TaskDefinition.TaskInput, O extends TaskDefinition.TaskOutput>(\n definition: TaskDefinition.Interface,\n handler: TaskDefinition.Handler<I, O>,\n logger: Logger.Interface\n): TaskDefinition.Runnable<I, O> => {\n const chain = (name: HookName) => {\n const own = handler[name]?.bind(handler);\n const decorated = definition[name]?.bind(definition);\n\n if (!own && !decorated) {\n return undefined;\n }\n\n return async (params: any) => {\n let failure: unknown;\n\n if (own) {\n try {\n await own(params);\n } catch (error) {\n if (SWALLOWED_HOOKS.has(name)) {\n logger.error(\n { error, taskId: definition.id, hook: name },\n \"Error executing task lifecycle hook.\"\n );\n } else {\n failure = error;\n }\n }\n }\n\n await decorated?.(params);\n\n if (failure) {\n throw failure;\n }\n };\n };\n\n return {\n id: definition.id,\n title: definition.title,\n description: definition.description,\n isPrivate: definition.isPrivate as boolean,\n databaseLogs: definition.databaseLogs as boolean,\n maxIterations: definition.maxIterations as number,\n selfCleanup: definition.selfCleanup,\n\n run: handler.run.bind(handler),\n onBeforeTrigger: chain(\"onBeforeTrigger\"),\n onDone: chain(\"onDone\"),\n onError: chain(\"onError\"),\n onAbort: chain(\"onAbort\"),\n onMaxIterations: chain(\"onMaxIterations\"),\n createInputValidation: handler.createInputValidation?.bind(handler)\n };\n};\n\nexport const GetTaskDefinitionUseCase = UseCaseAbstraction.createImplementation({\n implementation: GetTaskDefinitionUseCaseImpl,\n dependencies: [[TaskDefinition, { multiple: true }], TaskHandlerResolver, Logger]\n});\n"],"names":["GetTaskDefinitionUseCaseImpl","definitions","handlerResolver","logger","id","definition","handlerClass","handler","runnable","toRunnable","Result","TaskDefinitionNotRunnableError","TaskDefinitionNotFoundError","SWALLOWED_HOOKS","Set","chain","name","own","decorated","params","failure","error","GetTaskDefinitionUseCase","UseCaseAbstraction","TaskDefinition","TaskHandlerResolver","Logger"],"mappings":";;;;;;AAWO,MAAMA;IACT,YACYC,WAAuC,EACvCC,eAA8C,EAC9CC,MAAwB,CAClC;aAHUF,WAAW,GAAXA;aACAC,eAAe,GAAfA;aACAC,MAAM,GAANA;IACT;IAEI,QAGLC,EAAU,EAAmE;QAC3E,KAAK,MAAMC,cAAc,IAAI,CAAC,WAAW,CACrC,IAAIA,WAAW,EAAE,KAAKD;YAMtB,IAAIC,WAAW,OAAO,EAAE;gBAIpB,MAAMC,eAAeD,WAAW,OAAO;gBAGvC,MAAME,UAAU,IAAI,CAAC,eAAe,CAAC,OAAO,CAACD;gBAC7C,MAAME,WAAWC,WAAiBJ,YAAYE,SAAS,IAAI,CAAC,MAAM;gBAElE,OAAOG,OAAO,EAAE,CAACF;YACrB;YAGA,IAAI,AAA0B,cAA1B,OAAOH,WAAW,GAAG,EAAiB;gBACtC,MAAMG,WAAWH;gBAEjB,OAAOK,OAAO,EAAE,CAACF;YACrB;YAEA,OAAOE,OAAO,IAAI,CAAC,IAAIC,+BAA+BP;;QAG1D,OAAOM,OAAO,IAAI,CAAC,IAAIE,4BAA4BR;IACvD;AACJ;AAKA,MAAMS,kBAAyC,IAAIC,IAAI;IAAC;IAAU;IAAW;CAAU;AA+BvF,MAAML,aAAa,CACfJ,YACAE,SACAJ;IAEA,MAAMY,QAAQ,CAACC;QACX,MAAMC,MAAMV,OAAO,CAACS,KAAK,EAAE,KAAKT;QAChC,MAAMW,YAAYb,UAAU,CAACW,KAAK,EAAE,KAAKX;QAEzC,IAAI,CAACY,OAAO,CAACC,WACT;QAGJ,OAAO,OAAOC;YACV,IAAIC;YAEJ,IAAIH,KACA,IAAI;gBACA,MAAMA,IAAIE;YACd,EAAE,OAAOE,OAAO;gBACZ,IAAIR,gBAAgB,GAAG,CAACG,OACpBb,OAAO,KAAK,CACR;oBAAEkB;oBAAO,QAAQhB,WAAW,EAAE;oBAAE,MAAMW;gBAAK,GAC3C;qBAGJI,UAAUC;YAElB;YAGJ,MAAMH,YAAYC;YAElB,IAAIC,SACA,MAAMA;QAEd;IACJ;IAEA,OAAO;QACH,IAAIf,WAAW,EAAE;QACjB,OAAOA,WAAW,KAAK;QACvB,aAAaA,WAAW,WAAW;QACnC,WAAWA,WAAW,SAAS;QAC/B,cAAcA,WAAW,YAAY;QACrC,eAAeA,WAAW,aAAa;QACvC,aAAaA,WAAW,WAAW;QAEnC,KAAKE,QAAQ,GAAG,CAAC,IAAI,CAACA;QACtB,iBAAiBQ,MAAM;QACvB,QAAQA,MAAM;QACd,SAASA,MAAM;QACf,SAASA,MAAM;QACf,iBAAiBA,MAAM;QACvB,uBAAuBR,QAAQ,qBAAqB,EAAE,KAAKA;IAC/D;AACJ;AAEO,MAAMe,oDAA2BC,yBAAAA,oBAAuC,CAAC;IAC5E,gBAAgBvB;IAChB,cAAc;QAAC;YAACwB;YAAgB;gBAAE,UAAU;YAAK;SAAE;QAAEC;QAAqBC;KAAO;AACrF"}
@@ -1,5 +0,0 @@
1
- import { createAbstraction } from "@webiny/feature/api";
2
- const GetTaskDefinitionUseCase = createAbstraction("Tasks/GetTaskDefinitionUseCase");
3
- export { GetTaskDefinitionUseCase };
4
-
5
- //# sourceMappingURL=abstractions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"api/features/GetTaskDefinition/abstractions.js","sources":["../../../../src/api/features/GetTaskDefinition/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { Result } from \"@webiny/feature/api\";\nimport type { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport type {\n TaskDefinitionNotFoundError,\n TaskDefinitionNotRunnableError\n} from \"~/api/domain/errors.js\";\n\nexport interface IGetTaskDefinitionUseCase {\n execute<\n I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput,\n O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput\n >(\n id: string\n ): Result<TaskDefinition.Runnable<I, O>, UseCaseError>;\n}\n\nexport interface IGetTaskDefinitionUseCaseErrors {\n notFound: TaskDefinitionNotFoundError;\n notRunnable: TaskDefinitionNotRunnableError;\n}\n\ntype UseCaseError = IGetTaskDefinitionUseCaseErrors[keyof IGetTaskDefinitionUseCaseErrors];\n\nexport const GetTaskDefinitionUseCase = createAbstraction<IGetTaskDefinitionUseCase>(\n \"Tasks/GetTaskDefinitionUseCase\"\n);\n\nexport namespace GetTaskDefinitionUseCase {\n export type Interface = IGetTaskDefinitionUseCase;\n\n export type Error = UseCaseError;\n export type Return<\n I extends TaskDefinition.TaskInput = TaskDefinition.TaskInput,\n O extends TaskDefinition.TaskOutput = TaskDefinition.TaskOutput\n > = Result<TaskDefinition.Runnable<I, O>, UseCaseError>;\n}\n"],"names":["GetTaskDefinitionUseCase","createAbstraction"],"mappings":";AAwBO,MAAMA,2BAA2BC,kBACpC"}