diff --git a/packages/cli/src/PublicApi/v1/handlers/executions/executions.service.ts b/packages/cli/src/PublicApi/v1/handlers/executions/executions.service.ts index 0986a59227..2f5bb96ab3 100644 --- a/packages/cli/src/PublicApi/v1/handlers/executions/executions.service.ts +++ b/packages/cli/src/PublicApi/v1/handlers/executions/executions.service.ts @@ -1,7 +1,8 @@ import { parse } from 'flatted'; -import { In, Not, Raw, ObjectLiteral, LessThan, IsNull } from 'typeorm'; +import { In, Not, Raw, LessThan, IsNull, FindOperator } from 'typeorm'; import { Db, IExecutionFlattedDb, IExecutionResponseApi } from '../../../..'; +import { ExecutionEntity } from '../../../../databases/entities/ExecutionEntity'; import { ExecutionStatus } from '../../../types'; function prepareExecutionData( @@ -18,8 +19,12 @@ function prepareExecutionData( }; } -function getStatusCondition(status: ExecutionStatus): ObjectLiteral { - const condition: ObjectLiteral = {}; +function getStatusCondition(status: ExecutionStatus) { + const condition: { + finished?: boolean; + waitTill?: FindOperator; + stoppedAt?: FindOperator; + } = {}; if (status === 'success') { condition.finished = true; @@ -51,7 +56,7 @@ function getExecutionSelectableProperties(includeData?: boolean): Array { - const where = { - ...(data.lastId && { id: LessThan(data.lastId) }), - ...(data.status && { ...getStatusCondition(data.status) }), - ...(data.workflowIds && { workflowId: In(data.workflowIds.map(String)) }), - ...(data.excludedExecutionsIds && { id: Not(In(data.excludedExecutionsIds)) }), - }; + type WhereClause = Record< + string, + string | boolean | FindOperator> + >; - if (data.lastId && data.excludedExecutionsIds) { + let where: WhereClause = {}; + + if (params.lastId && params.excludedExecutionsIds?.length) { where.id = Raw((id) => `${id} < :lastId AND ${id} NOT IN (:...excludedExecutionsIds)`, { - lastId: data.lastId, - excludedExecutionsIds: data.excludedExecutionsIds, + lastId: params.lastId, + excludedExecutionsIds: params.excludedExecutionsIds, }); + } else if (params.lastId) { + where.id = LessThan(params.lastId); + } else if (params.excludedExecutionsIds?.length) { + where.id = Not(In(params.excludedExecutionsIds)); + } + + if (params.status) { + where = { ...where, ...getStatusCondition(params.status) }; + } + + if (params.workflowIds) { + where = { ...where, workflowId: In(params.workflowIds) }; } const executions = await Db.collections.Execution.find({ - select: getExecutionSelectableProperties(data.includeData), + select: getExecutionSelectableProperties(params.includeData), where, order: { id: 'DESC' }, - take: data.limit, + take: params.limit, }); - return executions.map((execution) => prepareExecutionData(execution)) as IExecutionResponseApi[]; + return executions.map(prepareExecutionData) as IExecutionResponseApi[]; } export async function getExecutionsCount(data: { diff --git a/packages/cli/test/integration/publicApi/executions.test.ts b/packages/cli/test/integration/publicApi/executions.test.ts index a4aab6ff31..bd86f0f61f 100644 --- a/packages/cli/test/integration/publicApi/executions.test.ts +++ b/packages/cli/test/integration/publicApi/executions.test.ts @@ -292,9 +292,9 @@ test.skip('GET /executions should paginate two executions', async () => { const workflow = await testDb.createWorkflow({}, owner); - const fistSuccessfullExecution = await testDb.createSuccessfulExecution(workflow); + const firstSuccessfulExecution = await testDb.createSuccessfulExecution(workflow); - const secondSuccessfullExecution = await testDb.createSuccessfulExecution(workflow); + const secondSuccessfulExecution = await testDb.createSuccessfulExecution(workflow); await testDb.createErrorExecution(workflow); @@ -317,7 +317,7 @@ test.skip('GET /executions should paginate two executions', async () => { expect(secondExecutionResponse.body.data.length).toBe(1); expect(secondExecutionResponse.body.nextCursor).toBeNull(); - const successfullExecutions = [fistSuccessfullExecution, secondSuccessfullExecution]; + const successfulExecutions = [firstSuccessfulExecution, secondSuccessfulExecution]; const executions = [...firstExecutionResponse.body.data, ...secondExecutionResponse.body.data]; for (let i = 0; i < executions.length; i++) { @@ -335,12 +335,12 @@ test.skip('GET /executions should paginate two executions', async () => { expect(id).toBeDefined(); expect(finished).toBe(true); - expect(mode).toEqual(successfullExecutions[i].mode); + expect(mode).toEqual(successfulExecutions[i].mode); expect(retrySuccessId).toBeNull(); expect(retryOf).toBeNull(); expect(startedAt).not.toBeNull(); expect(stoppedAt).not.toBeNull(); - expect(workflowId).toBe(successfullExecutions[i].workflowId); + expect(workflowId).toBe(successfulExecutions[i].workflowId); expect(waitTill).toBeNull(); } });