ci: Configure eslint for benchmark cli (#10480)

This commit is contained in:
Tomi Turtiainen 2024-08-23 13:19:12 +03:00 committed by GitHub
parent dd0c098b86
commit 8403f4aa11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 75 additions and 24 deletions

View file

@ -0,0 +1,30 @@
const sharedOptions = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/node'],
...sharedOptions(__dirname),
parserOptions: {
project: './tsconfig.json',
},
ignorePatterns: ['scenarios/**'],
rules: {
'n8n-local-rules/no-plain-errors': 'off',
complexity: 'error',
},
overrides: [
{
files: ['./src/commands/*.ts'],
rules: {
'import/no-default-export': 'off',
},
},
],
};

View file

@ -5,6 +5,8 @@
"main": "dist/index",
"scripts": {
"build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
"lint": "eslint .",
"lintfix": "eslint . --fix",
"start": "./bin/n8n-benchmark",
"test": "echo \"Error: no test specified\" && exit 1",
"typecheck": "tsc --noEmit",

View file

@ -1,6 +1,6 @@
import { strict as assert } from 'node:assert';
import type { AxiosRequestConfig } from 'axios';
import { N8nApiClient } from './n8nApiClient';
import { AxiosRequestConfig } from 'axios';
export class AuthenticatedN8nApiClient extends N8nApiClient {
constructor(

View file

@ -1,4 +1,5 @@
import axios, { AxiosError, AxiosRequestConfig } from 'axios';
import type { AxiosError, AxiosRequestConfig } from 'axios';
import axios from 'axios';
export class N8nApiClient {
constructor(public readonly apiBaseUrl: string) {}
@ -11,7 +12,7 @@ export class N8nApiClient {
while (Date.now() - START_TIME < TIMEOUT_MS) {
try {
const response = await axios.request({
const response = await axios.request<{ status: 'ok' }>({
url: `${this.apiBaseUrl}/${HEALTH_ENDPOINT}`,
method: 'GET',
});
@ -72,7 +73,7 @@ export class N8nApiClient {
return `${this.apiBaseUrl}/rest${endpoint}`;
}
private delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
private async delay(ms: number): Promise<void> {
return await new Promise((resolve) => setTimeout(resolve, ms));
}
}

View file

@ -1,5 +1,5 @@
import { Workflow } from '@/n8nApiClient/n8nApiClient.types';
import { AuthenticatedN8nApiClient } from './authenticatedN8nApiClient';
import type { AuthenticatedN8nApiClient } from './authenticatedN8nApiClient';
import type { Workflow } from '@/n8nApiClient/n8nApiClient.types';
export class WorkflowApiClient {
constructor(private readonly apiClient: AuthenticatedN8nApiClient) {}

View file

@ -1,7 +1,7 @@
import fs from 'node:fs';
import path from 'node:path';
import { Scenario } from '@/types/scenario';
import { Workflow } from '@/n8nApiClient/n8nApiClient.types';
import * as fs from 'node:fs';
import * as path from 'node:path';
import type { Scenario } from '@/types/scenario';
import type { Workflow } from '@/n8nApiClient/n8nApiClient.types';
/**
* Loads scenario data files from FS
@ -25,11 +25,10 @@ export class ScenarioDataFileLoader {
const fileContent = fs.readFileSync(workflowFilePath, 'utf8');
try {
return JSON.parse(fileContent);
return JSON.parse(fileContent) as Workflow;
} catch (error) {
throw new Error(
`Failed to parse workflow file ${workflowFilePath}: ${error instanceof Error ? error.message : error}`,
);
const e = error as Error;
throw new Error(`Failed to parse workflow file ${workflowFilePath}: ${e.message}`);
}
}
}

View file

@ -48,7 +48,11 @@ export class ScenarioLoader {
private loadAndValidateScenarioManifest(
scenarioManifestPath: string,
): [ScenarioManifest, null] | [null, string[]] {
const scenario = JSON.parse(fs.readFileSync(scenarioManifestPath, 'utf8'));
const [scenario, error] = this.loadScenarioManifest(scenarioManifestPath);
if (!scenario) {
return [null, [error]];
}
const validationErrors: string[] = [];
if (!scenario.name) {
@ -61,6 +65,21 @@ export class ScenarioLoader {
return validationErrors.length === 0 ? [scenario, null] : [null, validationErrors];
}
private loadScenarioManifest(
scenarioManifestPath: string,
): [ScenarioManifest, null] | [null, string] {
try {
const scenario = JSON.parse(
fs.readFileSync(scenarioManifestPath, 'utf8'),
) as ScenarioManifest;
return [scenario, null];
} catch (error) {
const message = error instanceof Error ? error.message : JSON.stringify(error);
return [null, `Failed to parse manifest ${scenarioManifestPath}: ${message}`];
}
}
private formScenarioId(scenarioPath: string): string {
return createHash('sha256').update(scenarioPath).digest('hex');
}

View file

@ -1,5 +1,5 @@
import { $, which } from 'zx';
import { Scenario } from '@/types/scenario';
import type { Scenario } from '@/types/scenario';
/**
* Executes test scenarios using k6
@ -24,7 +24,7 @@ export class K6Executor {
})`${k6ExecutablePath} run --quiet --stage ${stage} ${scenario.scriptPath}`;
for await (const chunk of processPromise.stdout) {
console.log(chunk.toString());
console.log((chunk as Buffer).toString());
}
}

View file

@ -1,5 +1,5 @@
import { AuthenticatedN8nApiClient } from '@/n8nApiClient/authenticatedN8nApiClient';
import { Workflow } from '@/n8nApiClient/n8nApiClient.types';
import type { AuthenticatedN8nApiClient } from '@/n8nApiClient/authenticatedN8nApiClient';
import type { Workflow } from '@/n8nApiClient/n8nApiClient.types';
import { WorkflowApiClient } from '@/n8nApiClient/workflowsApiClient';
/**

View file

@ -1,7 +1,7 @@
import { Scenario } from '@/types/scenario';
import { N8nApiClient } from '@/n8nApiClient/n8nApiClient';
import { ScenarioDataFileLoader } from '@/scenario/scenarioDataLoader';
import { K6Executor } from './k6Executor';
import type { K6Executor } from './k6Executor';
import type { Scenario } from '@/types/scenario';
import type { N8nApiClient } from '@/n8nApiClient/n8nApiClient';
import type { ScenarioDataFileLoader } from '@/scenario/scenarioDataLoader';
import { ScenarioDataImporter } from '@/testExecution/scenarioDataImporter';
import { AuthenticatedN8nApiClient } from '@/n8nApiClient/authenticatedN8nApiClient';