[QRQC_2] No explicit any in twenty-server (#12068)

# Introduction

Added a no-explicit-any rule to the twenty-server, not applicable to
tests and integration tests folder

Related to https://github.com/twentyhq/core-team-issues/issues/975
Discussed with Charles

## In case of conflicts
Until this is approved I won't rebased and handle conflict, just need to
drop two latest commits and re run the scripts etc

## Legacy
We decided not to handle the existing lint error occurrences and
programmatically ignored them through a disable next line rule comment

## Open question
We might wanna activate the
[no-explicit-any](https://typescript-eslint.io/rules/no-explicit-any/)
`ignoreRestArgs` for our use case ?
```
    ignoreRestArgs?: boolean;
```

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
This commit is contained in:
Paul Rastoin
2025-05-15 16:26:38 +02:00
committed by GitHub
parent c95c4383b4
commit a8423e8503
213 changed files with 453 additions and 4 deletions

View File

@ -29,9 +29,11 @@ export class GraphqlQueryFilterConditionParser {
}
public parse(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
queryBuilder: SelectQueryBuilder<any>,
objectNameSingular: string,
filter: Partial<ObjectRecordFilter>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): SelectQueryBuilder<any> {
if (!filter || Object.keys(filter).length === 0) {
return queryBuilder;
@ -50,6 +52,7 @@ export class GraphqlQueryFilterConditionParser {
queryBuilder: WhereExpressionBuilder,
objectNameSingular: string,
key: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any,
isFirst = false,
): void {

View File

@ -31,6 +31,7 @@ export class GraphqlQueryFilterFieldParser {
queryBuilder: WhereExpressionBuilder,
objectNameSingular: string,
key: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
filterValue: any,
isFirst = false,
): void {
@ -81,6 +82,7 @@ export class GraphqlQueryFilterFieldParser {
queryBuilder: WhereExpressionBuilder,
fieldMetadata: FieldMetadataInterface,
objectNameSingular: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fieldValue: any,
isFirst = false,
): void {
@ -108,6 +110,7 @@ export class GraphqlQueryFilterFieldParser {
const fullFieldName = `${fieldMetadata.name}${capitalize(subFieldKey)}`;
const [[operator, value]] = Object.entries(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
subFieldFilter as Record<string, any>,
);

View File

@ -65,6 +65,7 @@ export class GraphqlQueryOrderFieldParser {
private parseCompositeFieldForOrder(
fieldMetadata: FieldMetadataInterface,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any,
objectNameSingular: string,
isForwardPagination = true,

View File

@ -8,6 +8,7 @@ import {
export class GraphqlQuerySelectedFieldsAggregateParser {
parse(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
graphqlSelectedFields: Partial<Record<string, any>>,
fieldMetadataMapByName: Record<string, FieldMetadataInterface>,
accumulator: GraphqlQuerySelectedFieldsResult,

View File

@ -17,6 +17,7 @@ export class GraphqlQuerySelectedFieldsRelationParser {
parseRelationField(
fieldMetadata: FieldMetadataInterface,
fieldKey: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fieldValue: any,
accumulator: GraphqlQuerySelectedFieldsResult,
): void {

View File

@ -11,8 +11,11 @@ import { CompositeFieldMetadataType } from 'src/engine/metadata-modules/workspac
import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util';
export type GraphqlQuerySelectedFieldsResult = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
select: Record<string, any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
relations: Record<string, any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
aggregate: Record<string, any>;
};
@ -27,6 +30,7 @@ export class GraphqlQuerySelectedFieldsParser {
}
parse(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
graphqlSelectedFields: Partial<Record<string, any>>,
fieldMetadataMapByName: Record<string, FieldMetadataInterface>,
): GraphqlQuerySelectedFieldsResult {
@ -62,6 +66,7 @@ export class GraphqlQuerySelectedFieldsParser {
}
private parseRecordField(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
graphqlSelectedFields: Partial<Record<string, any>>,
fieldMetadataMapByName: Record<string, FieldMetadataInterface>,
accumulator: GraphqlQuerySelectedFieldsResult,
@ -96,6 +101,7 @@ export class GraphqlQuerySelectedFieldsParser {
}
private parseConnectionField(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
graphqlSelectedFields: Partial<Record<string, any>>,
fieldMetadataMapByName: Record<string, FieldMetadataInterface>,
accumulator: GraphqlQuerySelectedFieldsResult,
@ -112,6 +118,7 @@ export class GraphqlQuerySelectedFieldsParser {
}
private isRootConnection(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
graphqlSelectedFields: Partial<Record<string, any>>,
): boolean {
return Object.keys(graphqlSelectedFields).includes('edges');
@ -119,7 +126,9 @@ export class GraphqlQuerySelectedFieldsParser {
private parseCompositeField(
fieldMetadata: FieldMetadataInterface,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fieldValue: any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Record<string, any> {
const compositeType = compositeTypeDefinitions.get(
fieldMetadata.type as CompositeFieldMetadataType,
@ -151,6 +160,7 @@ export class GraphqlQuerySelectedFieldsParser {
return acc;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{} as Record<string, any>,
);
}

View File

@ -50,9 +50,11 @@ export class GraphqlQueryParser {
}
public applyFilterToBuilder(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
queryBuilder: SelectQueryBuilder<any>,
objectNameSingular: string,
recordFilter: Partial<ObjectRecordFilter>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): SelectQueryBuilder<any> {
return this.filterConditionParser.parse(
queryBuilder,
@ -62,8 +64,10 @@ export class GraphqlQueryParser {
}
public applyDeletedAtToBuilder(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
queryBuilder: SelectQueryBuilder<any>,
recordFilter: Partial<ObjectRecordFilter>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): SelectQueryBuilder<any> {
if (this.checkForDeletedAtFilter(recordFilter)) {
queryBuilder.withDeleted();
@ -99,10 +103,12 @@ export class GraphqlQueryParser {
};
public applyOrderToBuilder(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
queryBuilder: SelectQueryBuilder<any>,
orderBy: ObjectRecordOrderBy,
objectNameSingular: string,
isForwardPagination = true,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): SelectQueryBuilder<any> {
const parsedOrderBys = this.orderFieldParser.parse(
orderBy,
@ -115,6 +121,7 @@ export class GraphqlQueryParser {
public parseSelectedFields(
parentObjectMetadata: ObjectMetadataItemWithFieldMaps,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
graphqlSelectedFields: Partial<Record<string, any>>,
): GraphqlQuerySelectedFieldsResult {
const parentFields = getObjectMetadataMapItemByNameSingular(

View File

@ -46,7 +46,9 @@ export class ObjectRecordsToGraphqlConnectionHelper {
}: {
objectRecords: T[];
parentObjectRecord?: T;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
objectRecordsAggregatedValues?: Record<string, any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
selectedAggregatedFields?: Record<string, any>;
objectName: string;
take: number;
@ -95,6 +97,7 @@ export class ObjectRecordsToGraphqlConnectionHelper {
objectRecordsAggregatedValues,
}: {
selectedAggregatedFields: Record<string, AggregationField[]>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
objectRecordsAggregatedValues: Record<string, any>;
}) => {
if (!isDefined(objectRecordsAggregatedValues)) {
@ -120,6 +123,7 @@ export class ObjectRecordsToGraphqlConnectionHelper {
);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public processRecord<T extends Record<string, any>>({
objectRecord,
objectName,
@ -132,7 +136,9 @@ export class ObjectRecordsToGraphqlConnectionHelper {
}: {
objectRecord: T;
objectName: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
objectRecordsAggregatedValues?: Record<string, any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
selectedAggregatedFields?: Record<string, any>;
take: number;
totalCount: number;
@ -158,6 +164,7 @@ export class ObjectRecordsToGraphqlConnectionHelper {
);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const processedObjectRecord: Record<string, any> = {};
for (const [key, value] of Object.entries(objectRecord)) {
@ -229,7 +236,9 @@ export class ObjectRecordsToGraphqlConnectionHelper {
private processCompositeField(
fieldMetadata: FieldMetadataInterface,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fieldValue: any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Record<string, any> {
const compositeType = compositeTypeDefinitions.get(
fieldMetadata.type as CompositeFieldMetadataType,
@ -262,10 +271,12 @@ export class ObjectRecordsToGraphqlConnectionHelper {
return acc;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{} as Record<string, any>,
);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private formatFieldValue(value: any, fieldType: FieldMetadataType) {
switch (fieldType) {
case FieldMetadataType.RAW_JSON:

View File

@ -14,6 +14,7 @@ export class ProcessAggregateHelper {
queryBuilder,
}: {
selectedAggregatedFields: Record<string, AggregationField>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
queryBuilder: SelectQueryBuilder<any>;
}) => {
queryBuilder.select([]);

View File

@ -47,6 +47,7 @@ export class ProcessNestedRelationsV2Helper {
objectMetadataMaps: ObjectMetadataMaps;
parentObjectMetadataItem: ObjectMetadataItemWithFieldMaps;
parentObjectRecords: T[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
parentObjectRecordsAggregatedValues?: Record<string, any>;
relations: Record<string, FindOptionsRelations<ObjectLiteral>>;
aggregate?: Record<string, AggregationField>;
@ -94,6 +95,7 @@ export class ProcessNestedRelationsV2Helper {
objectMetadataMaps: ObjectMetadataMaps;
parentObjectMetadataItem: ObjectMetadataItemWithFieldMaps;
parentObjectRecords: T[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
parentObjectRecordsAggregatedValues: Record<string, any>;
sourceFieldName: string;
nestedRelations: FindOptionsRelations<ObjectLiteral>;
@ -251,6 +253,7 @@ export class ProcessNestedRelationsV2Helper {
}: {
records: ObjectRecord[];
idField: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}): any[] {
return [...new Set(records.map((item) => item[idField]))];
}
@ -265,20 +268,26 @@ export class ProcessNestedRelationsV2Helper {
aggregate,
sourceFieldName,
}: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
referenceQueryBuilder: SelectQueryBuilder<any>;
column: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ids: any[];
limit: number;
objectMetadataMaps: ObjectMetadataMaps;
targetObjectMetadata: ObjectMetadataItemWithFieldMaps;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
aggregate: Record<string, any>;
sourceFieldName: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}): Promise<{ relationResults: any[]; relationAggregatedFieldsResult: any }> {
if (ids.length === 0) {
return { relationResults: [], relationAggregatedFieldsResult: {} };
}
const aggregateForRelation = aggregate[sourceFieldName];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let relationAggregatedFieldsResult: Record<string, any> = {};
if (aggregateForRelation) {
@ -339,8 +348,11 @@ export class ProcessNestedRelationsV2Helper {
relationType,
}: {
parentRecords: ObjectRecord[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
parentObjectRecordsAggregatedValues: Record<string, any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
relationResults: any[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
relationAggregatedFieldsResult: Record<string, any>;
sourceFieldName: string;
joinField: string;

View File

@ -35,6 +35,7 @@ export class ProcessNestedRelationsHelper {
objectMetadataMaps: ObjectMetadataMaps;
parentObjectMetadataItem: ObjectMetadataItemWithFieldMaps;
parentObjectRecords: T[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
parentObjectRecordsAggregatedValues?: Record<string, any>;
relations: Record<string, FindOptionsRelations<ObjectLiteral>>;
aggregate?: Record<string, AggregationField>;

View File

@ -199,6 +199,7 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
fullPath: string;
column: string;
}[],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Record<string, any> {
const whereConditions = {};

View File

@ -14,6 +14,7 @@ export const computeWhereConditionParts = (
operator: string,
objectNameSingular: string,
key: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any,
): WhereConditionParts => {
const uuid = Math.random().toString(36).slice(2, 7);

View File

@ -10,6 +10,7 @@ import {
} from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception';
export interface CursorData {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
@ -28,6 +29,7 @@ export const encodeCursor = <T extends ObjectRecord = ObjectRecord>(
objectRecord: T,
order: ObjectRecordOrderBy | undefined,
): string => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const orderByValues: Record<string, any> = {};
const orderBy = order?.reduce((acc, orderBy) => ({ ...acc, ...orderBy }), {});
@ -47,7 +49,10 @@ export const encodeCursor = <T extends ObjectRecord = ObjectRecord>(
};
export const getCursor = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
args: FindManyResolverArgs<any, any>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Record<string, any> | undefined => {
if (args.after) return decodeCursor(args.after);
if (args.before) return decodeCursor(args.before);
@ -56,6 +61,7 @@ export const getCursor = (
};
export const getPaginationInfo = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
objectRecords: any[],
limit: number,
isForwardPagination: boolean,