Skip to content

Commit

Permalink
2.7.0 rootSelectorsLimits + performance improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
Igorkowalski94 committed Sep 26, 2024
1 parent baf51f5 commit 90b0b5c
Show file tree
Hide file tree
Showing 38 changed files with 1,296 additions and 262 deletions.
52 changes: 38 additions & 14 deletions fileComposition.schema.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"SelectorType": {
"type": "string",
"default": "",
"enum": [
"class",
"variable",
"variableExpression",
"arrowFunction",
"function",
"type",
"interface",
"enum"
]
},
"Selector": {
"oneOf": [
{
"type": "string",
"default": "",
"enum": [
"class",
"variable",
"variableExpression",
"arrowFunction",
"function",
"type",
"interface",
"enum"
]
},
{ "$ref": "#/definitions/SelectorType" },
{
"type": "object",
"default": { "type": "variableExpression", "limitTo": "" },
Expand Down Expand Up @@ -52,6 +53,28 @@
}
]
},
"RootSelectorsLimits": {
"type": "array",
"default": [],
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"selector": {
"oneOf": [
{ "$ref": "#/definitions/SelectorType" },
{
"type": "array",
"default": [],
"items": { "$ref": "#/definitions/SelectorType" }
}
]
},
"limit": { "type": "number" }
},
"required": ["limit", "selector"]
}
},
"FileRule": {
"type": "object",
"default": {},
Expand Down Expand Up @@ -139,6 +162,7 @@
}
]
},
"rootSelectorsLimits": { "$ref": "#/definitions/RootSelectorsLimits" },
"fileRootRules": {
"oneOf": [
{
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,25 @@
"husky:prepare": "husky install"
},
"dependencies": {
"@typescript-eslint/utils": "^8.6.0",
"@typescript-eslint/utils": "^8.7.0",
"comment-json": "^4.2.5",
"js-yaml": "^4.1.0",
"jsonschema": "^1.4.1",
"micromatch": "^4.0.8"
},
"devDependencies": {
"@eslint/compat": "^1.1.1",
"@eslint/js": "^9.10.0",
"@eslint/js": "^9.11.1",
"@types/eslint__js": "^8.42.3",
"@types/jest": "^29.5.13",
"@types/js-yaml": "^4.0.9",
"@types/micromatch": "^4.0.9",
"@types/node": "^22.5.5",
"eslint": "^9.10.0",
"@types/node": "^22.7.2",
"eslint": "^9.11.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-project-structure": "2.6.1",
"eslint-plugin-project-structure": "2.6.3",
"husky": "^9.1.6",
"jest": "^29.7.0",
"prettier": "^3.3.3",
Expand All @@ -90,7 +90,7 @@
"ts-prune": "^0.10.3",
"tsup": "^8.3.0",
"typescript": "^5.6.2",
"typescript-eslint": "^8.6.0"
"typescript-eslint": "^8.7.0"
},
"resolutions": {
"micromatch": "^4.0.8"
Expand Down
2 changes: 2 additions & 0 deletions src/rules/fileComposition/fileComposition.consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ export const ESLINT_ERRORS = {
prohibitedSelector: `🔥 The use of '{{selectorKey}}' is prohibited in this file. 🔥{{error}}`,
prohibitedSelectorRoot: `🔥 The use of '{{selectorKey}}' is prohibited in the root of the file. 🔥{{error}}`,
prohibitedSelectorExport: `🔥 Exporting '{{selectorKey}}' is prohibited in this file. 🔥{{error}}`,
rootSelectorsLimits:
"🔥 The limit for the given selectors in the root of the file has been exceeded. 🔥\n{{error}}\n\n",
};
27 changes: 22 additions & 5 deletions src/rules/fileComposition/fileComposition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { ESLintUtils } from "@typescript-eslint/utils";

import { ESLINT_ERRORS } from "rules/fileComposition/fileComposition.consts";
import { FileCompositionConfig } from "rules/fileComposition/fileComposition.types";
import { getFileCompositionConfig } from "rules/fileComposition/helpers/getFileCompositionConfig/getFileCompositionConfig";
import { handleClassDeclaration } from "rules/fileComposition/helpers/handleClassDeclaration";
import { handleFunctionDeclaration } from "rules/fileComposition/helpers/handleFunctionDeclaration";
import { handleMethodDefinition } from "rules/fileComposition/helpers/handleMethodDefinition";
import { handlePropertyDefinition } from "rules/fileComposition/helpers/handlePropertyDefinition";
import { handleVariableDeclarator } from "rules/fileComposition/helpers/handleVariableDeclarator";
import { validateFile } from "rules/fileComposition/helpers/validateFile/validateFile";
import { validateRootSelectorsLimits } from "rules/fileComposition/helpers/validateRootSelectorsLimits/validateRootSelectorsLimits";

export const fileComposition = ESLintUtils.RuleCreator(
() =>
Expand All @@ -26,28 +28,39 @@ export const fileComposition = ESLintUtils.RuleCreator(
},
defaultOptions: [],
create(context) {
const { config, fileConfig } = getFileCompositionConfig(context);

return {
Program(node): void {
validateRootSelectorsLimits({
node,
report: context.report,
rootSelectorsLimits: fileConfig?.rootSelectorsLimits,
});
},
VariableDeclarator(node): void {
handleVariableDeclarator({ node, context });
handleVariableDeclarator({ node, context, config, fileConfig });
},
ClassDeclaration(node): void {
handleClassDeclaration({ node, context });
handleClassDeclaration({ node, context, config, fileConfig });
},
MethodDefinition(node): void {
handleMethodDefinition({ node, context });
handleMethodDefinition({ node, context, config, fileConfig });
},
PropertyDefinition(node): void {
handlePropertyDefinition({ node, context });
handlePropertyDefinition({ node, context, config, fileConfig });
},
FunctionDeclaration(node): void {
handleFunctionDeclaration({ node, context });
handleFunctionDeclaration({ node, context, config, fileConfig });
},
TSTypeAliasDeclaration(node): void {
validateFile({
node,
context,
name: node.id.name,
nodeType: "TSTypeAliasDeclaration",
config,
fileConfig,
});
},
TSInterfaceDeclaration(node): void {
Expand All @@ -56,6 +69,8 @@ export const fileComposition = ESLintUtils.RuleCreator(
context,
name: node.id.name,
nodeType: "TSInterfaceDeclaration",
config,
fileConfig,
});
},
TSEnumDeclaration(node): void {
Expand All @@ -64,6 +79,8 @@ export const fileComposition = ESLintUtils.RuleCreator(
context,
name: node.id.name,
nodeType: "TSEnumDeclaration",
config,
fileConfig,
});
},
};
Expand Down
11 changes: 8 additions & 3 deletions src/rules/fileComposition/fileComposition.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,14 @@ export interface FileRuleObject {
rules: FileRule[];
}

interface FilesRules {
export interface RootSelectorLimit {
selector: SelectorType | SelectorType[];
limit: number;
}

export interface FileRules {
filePattern: Pattern;
selectorsLimits?: number;
rootSelectorsLimits?: RootSelectorLimit[];
selectorsOrder?: number;
fileRootRules?: FileRule[] | FileRuleObject;
fileExportRules?: FileRule[] | FileRuleObject;
Expand All @@ -69,7 +74,7 @@ interface FilesRules {

export interface FileCompositionConfig {
regexParameters?: RegexParameters;
filesRules: FilesRules[];
filesRules: FileRules[];
}

export type Context = Readonly<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ import { JSONSchema4 } from "@typescript-eslint/utils/dist/json-schema";
export const FILE_COMPOSITION_SCHEMA: JSONSchema4 = {
$schema: "http://json-schema.org/draft-07/schema#",
definitions: {
SelectorType: {
type: "string",
default: "",
enum: [
"class",
"variable",
"variableExpression",
"arrowFunction",
"function",
"type",
"interface",
"enum",
],
},
Selector: {
oneOf: [
{
type: "string",
default: "",
enum: [
"class",
"variable",
"variableExpression",
"arrowFunction",
"function",
"type",
"interface",
"enum",
],
},
{ $ref: "#/definitions/SelectorType" },
{
type: "object",
default: { type: "variableExpression", limitTo: "" },
Expand Down Expand Up @@ -54,6 +55,28 @@ export const FILE_COMPOSITION_SCHEMA: JSONSchema4 = {
},
],
},
RootSelectorsLimits: {
type: "array",
default: [],
items: {
type: "object",
additionalProperties: false,
properties: {
selector: {
oneOf: [
{ $ref: "#/definitions/SelectorType" },
{
type: "array",
default: [],
items: { $ref: "#/definitions/SelectorType" },
},
],
},
limit: { type: "number" },
},
required: ["limit", "selector"],
},
},
FileRule: {
type: "object",
default: {},
Expand Down Expand Up @@ -141,6 +164,7 @@ export const FILE_COMPOSITION_SCHEMA: JSONSchema4 = {
},
],
},
rootSelectorsLimits: { $ref: "#/definitions/RootSelectorsLimits" },
fileRootRules: {
oneOf: [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import path from "path";

import { isCorrectPattern } from "helpers/isCorrectPattern";
import { readConfigFile } from "helpers/readConfigFile/readConfigFile";
import { validateConfig } from "helpers/validateConfig";

import {
Context,
FileCompositionConfig,
FileRules,
} from "rules/fileComposition/fileComposition.types";
import { FILE_COMPOSITION_SCHEMA } from "rules/fileComposition/helpers/getFileCompositionConfig/getFileCompositionConfig.consts";

interface GetFileCompositionConfigReturn {
config: FileCompositionConfig;
fileConfig?: FileRules;
}

export const getFileCompositionConfig = ({
cwd,
filename,
settings,
options,
}: Context): GetFileCompositionConfigReturn => {
const config = readConfigFile<FileCompositionConfig>({
cwd,
key: "project-structure/file-composition-config-path",
settings,
options: options[0],
});

validateConfig({ config, schema: FILE_COMPOSITION_SCHEMA });

const filenamePath = path.relative(cwd, filename);
const fileConfig = config.filesRules.find(({ filePattern }) =>
isCorrectPattern({ input: filenamePath, pattern: filePattern }),
);

return { config, fileConfig };
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe("handleClassDeclaration", () => {
id: { name: "className" },
} as TSESTree.ClassDeclaration,
context: {} as Context,
config: { filesRules: [] },
});

expect(validateFileMock).toHaveBeenCalled();
Expand All @@ -32,6 +33,7 @@ describe("handleClassDeclaration", () => {
handleClassDeclaration({
node: {} as TSESTree.ClassDeclaration,
context: {} as Context,
config: { filesRules: [] },
});

expect(validateFileMock).not.toHaveBeenCalled();
Expand Down
12 changes: 11 additions & 1 deletion src/rules/fileComposition/helpers/handleClassDeclaration.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { TSESTree } from "@typescript-eslint/utils";

import { Context } from "rules/fileComposition/fileComposition.types";
import {
Context,
FileCompositionConfig,
FileRules,
} from "rules/fileComposition/fileComposition.types";
import { validateFile } from "rules/fileComposition/helpers/validateFile/validateFile";

interface HandleClassDeclarationProps {
node: TSESTree.ClassDeclaration;
context: Context;
config: FileCompositionConfig;
fileConfig?: FileRules;
}

export const handleClassDeclaration = ({
node,
context,
config,
fileConfig,
}: HandleClassDeclarationProps): void => {
if (!node.id?.name) return;

Expand All @@ -19,5 +27,7 @@ export const handleClassDeclaration = ({
context,
name: node.id.name,
nodeType: "ClassDeclaration",
config,
fileConfig,
});
};
Loading

0 comments on commit 90b0b5c

Please sign in to comment.