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>
		
	
		
			
				
	
	
		
			98 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import {
 | 
						|
  RULE_NAME as injectWorkspaceRepositoryName,
 | 
						|
  rule as injectWorkspaceRepository,
 | 
						|
} from './rules/inject-workspace-repository';
 | 
						|
import {
 | 
						|
  rule as componentPropsNaming,
 | 
						|
  RULE_NAME as componentPropsNamingName,
 | 
						|
} from './rules/component-props-naming';
 | 
						|
import {
 | 
						|
  rule as effectComponents,
 | 
						|
  RULE_NAME as effectComponentsName,
 | 
						|
} from './rules/effect-components';
 | 
						|
import {
 | 
						|
  rule as explicitBooleanPredicatesInIf,
 | 
						|
  RULE_NAME as explicitBooleanPredicatesInIfName,
 | 
						|
} from './rules/explicit-boolean-predicates-in-if';
 | 
						|
import {
 | 
						|
  rule as matchingStateVariable,
 | 
						|
  RULE_NAME as matchingStateVariableName,
 | 
						|
} from './rules/matching-state-variable';
 | 
						|
import {
 | 
						|
  rule as maxConstsPerFile,
 | 
						|
  RULE_NAME as maxConstsPerFileName,
 | 
						|
} from './rules/max-consts-per-file';
 | 
						|
import {
 | 
						|
  rule as noHardcodedColors,
 | 
						|
  RULE_NAME as noHardcodedColorsName,
 | 
						|
} from './rules/no-hardcoded-colors';
 | 
						|
import {
 | 
						|
  rule as noNavigatePreferLink,
 | 
						|
  RULE_NAME as noNavigatePreferLinkName,
 | 
						|
} from './rules/no-navigate-prefer-link';
 | 
						|
import {
 | 
						|
  rule as noStateUseref,
 | 
						|
  RULE_NAME as noStateUserefName,
 | 
						|
} from './rules/no-state-useref';
 | 
						|
import {
 | 
						|
  rule as sortCssPropertiesAlphabetically,
 | 
						|
  RULE_NAME as sortCssPropertiesAlphabeticallyName,
 | 
						|
} from './rules/sort-css-properties-alphabetically';
 | 
						|
import {
 | 
						|
  rule as styledComponentsPrefixedWithStyled,
 | 
						|
  RULE_NAME as styledComponentsPrefixedWithStyledName,
 | 
						|
} from './rules/styled-components-prefixed-with-styled';
 | 
						|
import {
 | 
						|
  rule as useGetLoadableAndGetValueToGetAtoms,
 | 
						|
  RULE_NAME as useGetLoadableAndGetValueToGetAtomsName,
 | 
						|
} from './rules/use-getLoadable-and-getValue-to-get-atoms';
 | 
						|
import {
 | 
						|
  rule as useRecoilCallbackHasDependencyArray,
 | 
						|
  RULE_NAME as useRecoilCallbackHasDependencyArrayName,
 | 
						|
} from './rules/useRecoilCallback-has-dependency-array';
 | 
						|
 | 
						|
/**
 | 
						|
 * Import your custom workspace rules at the top of this file.
 | 
						|
 *
 | 
						|
 * For example:
 | 
						|
 *
 | 
						|
 * import { RULE_NAME as myCustomRuleName, rule as myCustomRule } from './rules/my-custom-rule';
 | 
						|
 *
 | 
						|
 * In order to quickly get started with writing rules you can use the
 | 
						|
 * following generator command and provide your desired rule name:
 | 
						|
 *
 | 
						|
 * ```sh
 | 
						|
 * npx nx g @nx/eslint:workspace-rule {{ NEW_RULE_NAME }}
 | 
						|
 * ```
 | 
						|
 */
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  /**
 | 
						|
   * Apply the imported custom rules here.
 | 
						|
   *
 | 
						|
   * For example (using the example import above):
 | 
						|
   *
 | 
						|
   * rules: {
 | 
						|
   *  [myCustomRuleName]: myCustomRule
 | 
						|
   * }
 | 
						|
   */
 | 
						|
  rules: {
 | 
						|
    [componentPropsNamingName]: componentPropsNaming,
 | 
						|
    [effectComponentsName]: effectComponents,
 | 
						|
    [matchingStateVariableName]: matchingStateVariable,
 | 
						|
    [noHardcodedColorsName]: noHardcodedColors,
 | 
						|
    [noStateUserefName]: noStateUseref,
 | 
						|
    [sortCssPropertiesAlphabeticallyName]: sortCssPropertiesAlphabetically,
 | 
						|
    [styledComponentsPrefixedWithStyledName]:
 | 
						|
      styledComponentsPrefixedWithStyled,
 | 
						|
    [explicitBooleanPredicatesInIfName]: explicitBooleanPredicatesInIf,
 | 
						|
    [useGetLoadableAndGetValueToGetAtomsName]:
 | 
						|
      useGetLoadableAndGetValueToGetAtoms,
 | 
						|
    [maxConstsPerFileName]: maxConstsPerFile,
 | 
						|
    [useRecoilCallbackHasDependencyArrayName]:
 | 
						|
      useRecoilCallbackHasDependencyArray,
 | 
						|
    [noNavigatePreferLinkName]: noNavigatePreferLink,
 | 
						|
    [injectWorkspaceRepositoryName]: injectWorkspaceRepository,
 | 
						|
  },
 | 
						|
};
 |