mirror of
				https://github.com/lingble/twenty.git
				synced 2025-11-03 22:27:57 +00:00 
			
		
		
		
	### Description
This PR introduces a custom ESLint rule named
`inject-workspace-repository`. The purpose of this rule is to enforce
naming conventions for files and classes that use the
`@InjectWorkspaceRepository` decorator or include services ending with
`WorkspaceService` in their constructors.
### Rule Overview
The new ESLint rule checks for the following conditions:
1. **File Naming**:
- Only file ending with `.service.ts` or `.workspace-service.ts` are
checked.
- If a file contains a class using the `@InjectWorkspaceRepository`
decorator or a service ending with `WorkspaceService` in the
constructor, the file name must end with `.workspace-service.ts`.
2. **Class Naming**:
- Classes that use the `@InjectWorkspaceRepository` decorator or include
services ending with `WorkspaceService` in their constructors must have
names that end with `WorkspaceService`.
### How It Works
The rule inspects each TypeScript file to ensure that the naming
conventions are adhered to. It specifically looks for:
- Constructor parameters with the `@InjectWorkspaceRepository`
decorator.
- Constructor parameters with a type annotation ending with
`WorkspaceService`.
When such parameters are found, it checks the class name and the file
name to ensure they conform to the expected patterns.
### Example Code
#### Valid Cases
1. **Correct File and Class Name with Decorator**:
    ```typescript
    // Filename: my.workspace-service.ts
    class MyWorkspaceService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    ```
2. **Service Dependency**:
    ```typescript
    // Filename: another.workspace-service.ts
    class AnotherWorkspaceService {
      constructor(private myWorkspaceService: MyWorkspaceService) {}
    }
    ```
#### Invalid Cases
1. **Incorrect Class Name**:
    ```typescript
    // Filename: my.workspace-service.ts
    class MyService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    ```
2. **Incorrect File Name**:
    ```typescript
    // Filename: my.service.ts
    class MyWorkspaceService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    // Error: File name should end with '.workspace-service.ts'.
    ```
3. **Incorrect File and Class Name**:
    ```typescript
    // Filename: my.service.ts
    class MyService {
      constructor(@InjectWorkspaceRepository() private repository) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    // Error: File name should end with '.workspace-service.ts'.
    ```
4. **Incorrect File Type**:
    ```typescript
    // Filename: another.service.ts
    class AnotherService {
      constructor(private myWorkspaceService: MyWorkspaceService) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    // Error: File name should end with '.workspace-service.ts'.
    ```
5. **Incorrect Class Name with Dependency**:
    ```typescript
    // Filename: another.workspace-service.ts
    class AnotherService {
      constructor(private myWorkspaceService: MyWorkspaceService) {}
    }
    // Error: Class name should end with 'WorkspaceService'.
    ```
### First step
This rule is only a warning for now, and then we'll migrate all the code
that need to be migrated and move from `warn` to `error`.
Fix #6309
Co-authored-by: Charles Bochet <charles@twenty.com>
		
	
		
			
				
	
	
		
			78 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { TSESLint } from '@typescript-eslint/utils';
 | 
						|
import { rule, RULE_NAME } from './inject-workspace-repository';
 | 
						|
 | 
						|
const ruleTester = new TSESLint.RuleTester({
 | 
						|
  parser: require.resolve('@typescript-eslint/parser'),
 | 
						|
});
 | 
						|
 | 
						|
ruleTester.run(RULE_NAME, rule, {
 | 
						|
  valid: [
 | 
						|
    {
 | 
						|
      code: `
 | 
						|
        class MyWorkspaceService {
 | 
						|
          constructor(@InjectWorkspaceRepository() private repository) {}
 | 
						|
        }
 | 
						|
      `,
 | 
						|
      filename: 'my.workspace-service.ts',
 | 
						|
    },
 | 
						|
    {
 | 
						|
      code: `
 | 
						|
        class AnotherWorkspaceService {
 | 
						|
          constructor(private myWorkspaceService: MyWorkspaceService) {}
 | 
						|
        }
 | 
						|
      `,
 | 
						|
      filename: 'another.workspace-service.ts',
 | 
						|
    },
 | 
						|
  ],
 | 
						|
  invalid: [
 | 
						|
    {
 | 
						|
      code: `
 | 
						|
        class MyService {
 | 
						|
          constructor(@InjectWorkspaceRepository() private repository) {}
 | 
						|
        }
 | 
						|
      `,
 | 
						|
      filename: 'my.workspace-service.ts',
 | 
						|
      errors: [{ messageId: 'invalidClassName' }],
 | 
						|
    },
 | 
						|
    {
 | 
						|
      code: `
 | 
						|
        class MyWorkspaceService {
 | 
						|
          constructor(@InjectWorkspaceRepository() private repository) {}
 | 
						|
        }
 | 
						|
      `,
 | 
						|
      filename: 'my.service.ts',
 | 
						|
      errors: [{ messageId: 'invalidFileName' }],
 | 
						|
    },
 | 
						|
    {
 | 
						|
      code: `
 | 
						|
        class MyService {
 | 
						|
          constructor(@InjectWorkspaceRepository() private repository) {}
 | 
						|
        }
 | 
						|
      `,
 | 
						|
      filename: 'my.service.ts',
 | 
						|
      errors: [
 | 
						|
        { messageId: 'invalidClassName' },
 | 
						|
        { messageId: 'invalidFileName' },
 | 
						|
      ],
 | 
						|
    },
 | 
						|
    {
 | 
						|
      code: `
 | 
						|
        class AnotherWorkspaceService {
 | 
						|
          constructor(private myWorkspaceService: MyWorkspaceService) {}
 | 
						|
        }
 | 
						|
      `,
 | 
						|
      filename: 'another.service.ts',
 | 
						|
      errors: [{ messageId: 'invalidFileName' }],
 | 
						|
    },
 | 
						|
    {
 | 
						|
      code: `
 | 
						|
        class AnotherService {
 | 
						|
          constructor(private myWorkspaceService: MyWorkspaceService) {}
 | 
						|
        }
 | 
						|
      `,
 | 
						|
      filename: 'another.workspace-service.ts',
 | 
						|
      errors: [{ messageId: 'invalidClassName' }],
 | 
						|
    },
 | 
						|
  ],
 | 
						|
});
 |