diff --git a/packages/respect-core/src/modules/__tests__/flow-runner/call-api-and-analyze-results.test.ts b/packages/respect-core/src/modules/__tests__/flow-runner/call-api-and-analyze-results.test.ts index 67b75b0b98..9e051c292b 100644 --- a/packages/respect-core/src/modules/__tests__/flow-runner/call-api-and-analyze-results.test.ts +++ b/packages/respect-core/src/modules/__tests__/flow-runner/call-api-and-analyze-results.test.ts @@ -344,7 +344,7 @@ describe('callAPIAndAnalyzeResults', () => { it('should call API and return checks result', async () => { const serverUrl = 'https://catfact.ninja/'; - const workflowName = 'get-breeds-workflow'; + const workflowId = 'get-breeds-workflow'; const step = ctx.workflows[0].steps[0]; const mockResponse = { @@ -359,7 +359,7 @@ describe('callAPIAndAnalyzeResults', () => { const result = await callAPIAndAnalyzeResults({ ctx, - workflowName, + workflowId, step, requestData: { serverUrl: { url: serverUrl }, diff --git a/packages/respect-core/src/modules/__tests__/flow-runner/run-step.test.ts b/packages/respect-core/src/modules/__tests__/flow-runner/run-step.test.ts index fca2de7ef1..29744cbecb 100644 --- a/packages/respect-core/src/modules/__tests__/flow-runner/run-step.test.ts +++ b/packages/respect-core/src/modules/__tests__/flow-runner/run-step.test.ts @@ -611,7 +611,6 @@ const basicCTX = { arazzo: '1.0.1', $outputs: {}, } as unknown as TestContext; -const testDocumentFilePath = 'test.yml'; describe('runStep', () => { afterEach(() => { @@ -626,9 +625,7 @@ describe('runStep', () => { successCriteria: [{ condition: '$statusCode == 200' }], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore callAPIAndAnalyzeResults.mockImplementationOnce(async ({ step }: { step: Step }) => { @@ -653,31 +650,25 @@ describe('runStep', () => { await runStep({ step, ctx: basicCTX, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toMatchSnapshot(); }); - it('should run step and return failed result when workflowName is missing', async () => { + it('should run step and return failed result when workflowId is missing', async () => { const step = { stepId: 'get-bird', 'x-operation': { url: 'http://localhost:3000/bird', method: 'get' }, successCriteria: [{ condition: '$statusCode == 200' }], checks: [], } as unknown as Step; - const workflowName = undefined; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = undefined; await runStep({ step, ctx: basicCTX, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(step.checks).toEqual([ @@ -700,9 +691,7 @@ describe('runStep', () => { successCriteria: [{ condition: '$statusCode == 200' }], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore callAPIAndAnalyzeResults.mockImplementationOnce(async ({ step }: { step: Step }) => { @@ -713,9 +702,7 @@ describe('runStep', () => { await runStep({ step, ctx: basicCTX, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); // @ts-ignore @@ -758,9 +745,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore callAPIAndAnalyzeResults.mockImplementationOnce(async ({ step }: { step: Step }) => { @@ -843,9 +828,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -871,9 +854,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore callAPIAndAnalyzeResults.mockImplementationOnce(async ({ step }: { step: Step }) => { @@ -968,9 +949,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -1003,9 +982,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; (callAPIAndAnalyzeResults as jest.Mock).mockImplementationOnce( async ({ step }: { step: Step }) => { @@ -1091,9 +1068,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -1128,9 +1103,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; (callAPIAndAnalyzeResults as jest.Mock).mockImplementationOnce( async ({ step }: { step: Step }) => { @@ -1212,9 +1185,7 @@ describe('runStep', () => { runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }) ).rejects.toThrowError( 'Cannot use both workflowId: success-action-workflow and stepId: success-action-step in goto action' @@ -1250,9 +1221,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore (callAPIAndAnalyzeResults as jest.Mock).mockImplementationOnce( @@ -1335,9 +1304,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -1363,9 +1330,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore (callAPIAndAnalyzeResults as jest.Mock).mockImplementationOnce( @@ -1462,9 +1427,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -1499,9 +1462,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; (callAPIAndAnalyzeResults as jest.Mock).mockImplementation(async ({ step }: { step: Step }) => { step.checks = [ @@ -1581,9 +1542,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -1619,9 +1578,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore (callAPIAndAnalyzeResults as jest.Mock).mockImplementation(async ({ step }: { step: Step }) => { @@ -1700,9 +1657,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }) ).rejects.toThrow( 'Cannot use both workflowId: failure-action-workflow and stepId: failure-action-step in retry action' @@ -1737,9 +1692,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; (callAPIAndAnalyzeResults as jest.Mock).mockImplementation(async ({ step }: { step: Step }) => { step.checks = [ @@ -1832,9 +1785,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -1869,9 +1820,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore (callAPIAndAnalyzeResults as jest.Mock).mockImplementationOnce( @@ -1997,9 +1946,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -2034,9 +1981,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; // @ts-ignore (callAPIAndAnalyzeResults as jest.Mock).mockImplementation(async ({ step }: { step: Step }) => { @@ -2118,9 +2063,7 @@ describe('runStep', () => { await runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(displayChecks).toHaveBeenCalled(); @@ -2147,9 +2090,7 @@ describe('runStep', () => { ], checks: [], } as unknown as Step; - const workflowName = 'get-bird-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'get-bird-workflow'; const context = { ...basicCTX, @@ -2183,9 +2124,7 @@ describe('runStep', () => { runStep({ step: stepOne, ctx: context, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }) ).rejects.toThrow(`Parameter "in" is required for ${stepOne.stepId} step`); }); @@ -2199,9 +2138,7 @@ describe('runStep', () => { }, checks: [], } as unknown as Step; - const workflowName = 'test-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'test-workflow'; const localCTX = { $request: undefined, $response: undefined, @@ -2629,9 +2566,7 @@ describe('runStep', () => { await runStep({ step, ctx: localCTX, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(runWorkflow).toHaveBeenCalled(); @@ -3066,9 +3001,7 @@ describe('runStep', () => { await runStep({ step, ctx: localCTX, - workflowName: 'test-workflow', - parentStepId, - parentWorkflowId, + workflowId: 'test-workflow', }); // @ts-ignore @@ -3542,9 +3475,7 @@ describe('runStep', () => { await runStep({ step, ctx: localCTX, - workflowName: 'test-workflow', - parentStepId, - parentWorkflowId, + workflowId: 'test-workflow', }); expect(resolveWorkflowContext).toHaveBeenCalledWith( @@ -3600,9 +3531,7 @@ describe('runStep', () => { }, checks: [], } as unknown as Step; - const workflowName = 'test-workflow'; - const parentWorkflowId = undefined; - const parentStepId = undefined; + const workflowId = 'test-workflow'; const localCTX = { apiClient, $request: undefined, @@ -4034,9 +3963,7 @@ describe('runStep', () => { await runStep({ step, ctx: localCTX, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, }); expect(runWorkflow).not.toHaveBeenCalled(); diff --git a/packages/respect-core/src/modules/flow-runner/call-api-and-analyze-results.ts b/packages/respect-core/src/modules/flow-runner/call-api-and-analyze-results.ts index 43636aede9..cb1ddd76a1 100644 --- a/packages/respect-core/src/modules/flow-runner/call-api-and-analyze-results.ts +++ b/packages/respect-core/src/modules/flow-runner/call-api-and-analyze-results.ts @@ -6,36 +6,16 @@ import { evaluateRuntimeExpressionPayload } from '../runtime-expressions'; import type { RequestData } from './prepare-request'; import type { TestContext, Step } from '../../types'; -import type { OperationDetails } from '../description-parser'; -import type { ParameterWithIn } from '../config-parser'; - -// TODO: rename -export type ResultObject = { - ctx: TestContext; - workflowName: string; - step: Step; - requestData: { - serverUrl?: { - url: string; - // TODO: support variables - }; - path: string; - method: string; - parameters: ParameterWithIn[]; - requestBody: any; - openapiOperation?: OperationDetails & Record; - }; -}; // TODO: split into two functions export async function callAPIAndAnalyzeResults({ ctx, - workflowName, + workflowId, step, requestData, }: { ctx: TestContext; - workflowName: string; + workflowId: string; step: Step; requestData: RequestData; }) { @@ -61,38 +41,13 @@ export async function callAPIAndAnalyzeResults({ return checksResult; } - const request = ctx.$workflows[workflowName].steps[step.stepId].request; - - // store step level outputs - if (step.outputs) { - const runtimeExpressionContext = createRuntimeExpressionCtx({ - ctx: { - ...ctx, - ...{ - $request: request, - $response: step.response, - $inputs: ctx.$workflows[workflowName].inputs, - }, - }, - workflowId: workflowName, - step, - }); - - if (step.outputs) { - for (const outputKey of Object.keys(step.outputs)) { - step.outputs[outputKey] = evaluateRuntimeExpressionPayload({ - payload: step.outputs[outputKey], - context: runtimeExpressionContext, - }); - } - } - } + const request = ctx.$workflows[workflowId].steps[step.stepId].request; step.verboseLog = ctx.apiClient.getVerboseResponseLogs(); if (step.successCriteria) { const successCriteriaChecks = checkCriteria({ - workflowId: workflowName, + workflowId, step, criteria: step.successCriteria, ctx: { @@ -100,7 +55,7 @@ export async function callAPIAndAnalyzeResults({ ...{ $request: request, $response: step.response, - $inputs: ctx.$workflows[workflowName].inputs, + $inputs: ctx.$workflows[workflowId].inputs, }, }, }); @@ -113,7 +68,7 @@ export async function callAPIAndAnalyzeResults({ stepCallCtx: { $request: request, $response: step.response, - $inputs: ctx.$workflows[workflowName].inputs, + $inputs: ctx.$workflows[workflowId].inputs, }, descriptionOperation: requestData.openapiOperation, ctx, @@ -124,6 +79,29 @@ export async function callAPIAndAnalyzeResults({ step.checks.push(...schemaChecks); } + // store step level outputs + if (step.outputs) { + const runtimeExpressionContext = createRuntimeExpressionCtx({ + ctx: { + ...ctx, + $request: request, + $response: step.response, + $inputs: ctx.$workflows[workflowId].inputs, + }, + workflowId, + step, + }); + + if (step.outputs) { + for (const outputKey of Object.keys(step.outputs)) { + step.outputs[outputKey] = evaluateRuntimeExpressionPayload({ + payload: step.outputs[outputKey], + context: runtimeExpressionContext, + }); + } + } + } + // save local $steps context ctx.$steps[step.stepId] = { outputs: ctx.$steps[step.stepId].outputs @@ -131,7 +109,7 @@ export async function callAPIAndAnalyzeResults({ : step.outputs, }; // save $workflows context - ctx.$workflows[workflowName].steps[step.stepId] = { + ctx.$workflows[workflowId].steps[step.stepId] = { outputs: ctx.$steps[step.stepId].outputs, request, response: step.response, diff --git a/packages/respect-core/src/modules/flow-runner/run-step.ts b/packages/respect-core/src/modules/flow-runner/run-step.ts index d424d9bffa..d8bc60c12f 100644 --- a/packages/respect-core/src/modules/flow-runner/run-step.ts +++ b/packages/respect-core/src/modules/flow-runner/run-step.ts @@ -31,20 +31,16 @@ const logger = DefaultLogger.getInstance(); export async function runStep({ step, ctx, - workflowName, - parentStepId, - parentWorkflowId, + workflowId, retriesLeft, }: { step: Step; ctx: TestContext; - workflowName: string | undefined; - parentStepId?: string; - parentWorkflowId?: string; + workflowId: string | undefined; retriesLeft?: number; }): Promise<{ shouldEnd: boolean } | void> { - const workflow = ctx.workflows.find((w) => w.workflowId === workflowName); - const { stepId, onFailure, onSuccess, workflowId, parameters } = step; + const workflow = ctx.workflows.find((w) => w.workflowId === workflowId); + const { stepId, onFailure, onSuccess, workflowId: targetWorkflowRef, parameters } = step; const failureActionsToRun = (onFailure || workflow?.failureActions || []).map( (action) => resolveReusableComponentItem(action, ctx) as OnFailureObject @@ -57,15 +53,15 @@ export async function runStep({ (parameter) => resolveReusableComponentItem(parameter, ctx) as ResolvedParameter ); - if (workflowId) { - const resolvedWorkflow = - ctx.workflows.find((w) => w.workflowId === workflowId) || - getValueFromContext(workflowId, ctx); + if (targetWorkflowRef) { + const targetWorkflow = + ctx.workflows.find((w) => w.workflowId === targetWorkflowRef) || + getValueFromContext(targetWorkflowRef, ctx); - if (!resolvedWorkflow) { + if (!targetWorkflow) { const failedCall: Check = { name: CHECKS.UNEXPECTED_ERROR, - message: `Workflow ${red(workflowId)} not found.`, + message: `Workflow ${red(targetWorkflowRef)} not found.`, pass: false, severity: ctx.severity['UNEXPECTED_ERROR'], }; @@ -73,7 +69,7 @@ export async function runStep({ return; } - const workflowCtx = await resolveWorkflowContext(workflowId, resolvedWorkflow, ctx); + const workflowCtx = await resolveWorkflowContext(targetWorkflowRef, targetWorkflow, ctx); if (resolvedParameters && resolvedParameters.length) { // When the step in context specifies a workflowId, then all parameters without `in` maps to workflow inputs. @@ -85,14 +81,14 @@ export async function runStep({ return acc; }, {} as Record); - workflowCtx.$workflows[resolvedWorkflow.workflowId].inputs = workflowInputParameters; + workflowCtx.$workflows[targetWorkflow.workflowId].inputs = workflowInputParameters; } const stepWorkflowResult = await runWorkflow({ - workflowInput: resolvedWorkflow, + workflowInput: targetWorkflow, ctx: workflowCtx, - parentWorkflowId: workflowId || parentWorkflowId, - parentStepId: parentStepId || stepId, + parentWorkflowId: targetWorkflowRef, + parentStepId: stepId, }); // FIXME @@ -160,15 +156,15 @@ export async function runStep({ let requestData: RequestData | undefined; try { - if (!workflowName) { + if (!workflowId) { throw new Error('Workflow name is required to run a step'); } - requestData = await prepareRequest(ctx, step, workflowName); + requestData = await prepareRequest(ctx, step, workflowId); const checksResult = await callAPIAndAnalyzeResults({ ctx, - workflowName, + workflowId, step, requestData, }); @@ -246,7 +242,7 @@ export async function runStep({ } const matchesCriteria = checkCriteria({ - workflowId: workflowName, + workflowId: workflowId, step, criteria, ctx, @@ -279,27 +275,25 @@ export async function runStep({ await runWorkflow({ workflowInput: targetWorkflow, ctx: targetCtx, - parentWorkflowId: workflowName, + parentWorkflowId: workflowId, fromStepId: targetStep, }); } else if (targetStep) { const stepToRun = workflow?.steps.find((s) => s.stepId === targetStep) as Step; if (!stepToRun) { - throw new Error(`Step ${targetStep} not found in workflow ${workflowName}`); + throw new Error(`Step ${targetStep} not found in workflow ${workflowId}`); } await runStep({ step: stepToRun, ctx: targetCtx, - workflowName: workflowName as string, + workflowId, }); } return { stepResult: await runStep({ step, ctx, - workflowName, - parentStepId: stepId, - parentWorkflowId: workflowName, + workflowId, retriesLeft: retriesLeft - 1, }), retriesLeft, @@ -313,7 +307,7 @@ export async function runStep({ await runWorkflow({ workflowInput: targetWorkflow || workflow, ctx: targetCtx, - parentWorkflowId: workflowName, + parentWorkflowId: workflowId, fromStepId: targetStep, }); return { shouldEnd: true }; diff --git a/packages/respect-core/src/modules/flow-runner/runner.ts b/packages/respect-core/src/modules/flow-runner/runner.ts index d19021abb9..0c50cb4795 100644 --- a/packages/respect-core/src/modules/flow-runner/runner.ts +++ b/packages/respect-core/src/modules/flow-runner/runner.ts @@ -146,14 +146,14 @@ export async function runWorkflow({ throw new Error(`\n ${blue('Workflow')} ${workflowInput} ${blue('not found')} \n`); } - const workflowName = workflow?.workflowId || parentWorkflowId; + const workflowId = workflow.workflowId; if (parentWorkflowId && parentStepId) { printStepWorkflowSeparator(parentStepId, parentWorkflowId); } else if (parentWorkflowId) { printDependentWorkflowSeparator(parentWorkflowId); } else { - printWorkflowSeparator(fileBaseName, workflowName); + printWorkflowSeparator(fileBaseName, workflowId); } const fromStepIndex = fromStepId @@ -169,9 +169,7 @@ export async function runWorkflow({ const stepResults = await runStep({ step, ctx, - workflowName, - parentWorkflowId, - parentStepId, + workflowId, }); // When `end` action is used, we should not continue with the next steps if (stepResults?.shouldEnd) { @@ -190,12 +188,12 @@ export async function runWorkflow({ } // workflow level outputs - if (workflow.outputs && workflowName) { + if (workflow.outputs && workflowId) { if (!ctx.$outputs) { ctx.$outputs = {}; } - if (!ctx.$outputs[workflowName]) { - ctx.$outputs[workflowName] = {}; + if (!ctx.$outputs[workflowId]) { + ctx.$outputs[workflowId] = {}; } const runtimeExpressionContext = createRuntimeExpressionCtx({ @@ -203,10 +201,10 @@ export async function runWorkflow({ ...ctx, $inputs: { ...(ctx.$inputs || {}), - ...(ctx.$workflows[workflowName]?.inputs || {}), + ...(ctx.$workflows[workflowId]?.inputs || {}), }, }, - workflowId: workflowName, + workflowId, }); for (const outputKey of Object.keys(workflow.outputs)) { @@ -217,12 +215,10 @@ export async function runWorkflow({ context: runtimeExpressionContext, }); } - ctx.$outputs[workflowName].outputs = workflow.outputs; - ctx.$workflows[workflowName].outputs = workflow.outputs; + ctx.$outputs[workflowId].outputs = workflow.outputs; + ctx.$workflows[workflowId].outputs = workflow.outputs; } catch (error: any) { - throw new Error( - `Failed to resolve outputs in workflow "${workflowName}": ${error.message}` - ); + throw new Error(`Failed to resolve outputs in workflow "${workflowId}": ${error.message}`); } } } diff --git a/packages/respect-core/src/types.ts b/packages/respect-core/src/types.ts index 517121399c..ca46c89198 100644 --- a/packages/respect-core/src/types.ts +++ b/packages/respect-core/src/types.ts @@ -209,21 +209,16 @@ export type TestContext = RuntimeExpressionContext & { }; apiClient: ApiFetcher; }; + export type TestDescription = Partial< Pick< TestContext & WorkflowInnerContext & StepInnerContext, 'workflows' | 'arazzo' | 'info' | 'sourceDescriptions' | '$outputs' | 'components' > >; -export type CheckStepInfo = { - stepId: string; - workflowId?: string; - operationId?: string; - operationPath?: string; -}; + export type Check = { severity: RuleSeverity; - stepInfo?: CheckStepInfo; pass: boolean; name: string; message?: string;