Skip to content

Commit

Permalink
2.1.18
Browse files Browse the repository at this point in the history
  • Loading branch information
Igorkowalski94 committed Aug 18, 2024
1 parent 51d306a commit a68d91a
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 132 deletions.
19 changes: 8 additions & 11 deletions documentation/migration-to-2.1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ A minor configuration fix will be required for version <= 1.4.7.

### General changes:

- The entire documentation has been rewritten for ESLint's new config system. Examples with the old ESLint configuration can be found in the [**playground**](https://github.com/Igorkowalski94/eslint-plugin-project-structure-playground) for eslint-plugin-project-structure rules.
- A shorter notation option for [structure](https://github.com/Igorkowalski94/eslint-plugin-project-structure/blob/main/documentation/project-structure-folder-structure.md#structure).
- New build-in {SNAKE_CASE} regexParameter.
- Improvements for {PascalCase} and {camelCase} regexParameters.
- The entire documentation has been rewritten for ESLint's new config system. Examples with the old ESLint configuration can be found in the [playground](https://github.com/Igorkowalski94/eslint-plugin-project-structure-playground) for eslint-plugin-project-structure rules.
- New option for creating a configuration file in an .mjs file with TypeScript support.
- Enforcing the existence of a file/folder when a specific file/folder exists. For example, if `src/Component.tsx` exists, then `src/Component.test.tsx` and `src/stories/Component.stories.tsx` must also exist.
- [Enforcing the existence](https://github.com/Igorkowalski94/eslint-plugin-project-structure/blob/main/documentation/project-structure-folder-structure.md#enforce-existence) of a files/folders when a specific file/folder exists. For example, if `src/Component.tsx` exists, then `src/Component.test.tsx` and `src/stories/Component.stories.tsx` must also exist.
- You can now use comments in folderStructure.json and independentModules.json files.
- Improved error messages for folder-structure.
- Easier configuration of folder-structure. The "extension" key has been removed, now the file extension will be part of the "name". You don't need to add /^$/ to your regex, they will be added automatically and other improvements.
Expand Down Expand Up @@ -122,17 +125,13 @@ The following improvements are automatically added to the regex:
From: ${{key}}

```jsonc
{
"name": "/^${{parentName}}$/",
}
{ "name": "/^${{parentName}}$/" }
```

To: {key}

```jsonc
{
"name": "{parentName}",
}
{ "name": "{parentName}" }
```

### Changes for build-in PascalCase
Expand Down Expand Up @@ -169,9 +168,7 @@ Add **`SNAKE_CASE`** validation to your regex.<br>
The added regex is **`((([A-Z]|\d)+_)*([A-Z]|\d)+)`**.

```jsonc
{
"name": "{SNAKE_CASE}",
}
{ "name": "{SNAKE_CASE}" }
```

### New rules:
Expand Down
80 changes: 45 additions & 35 deletions documentation/project-structure-folder-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Enforce rules on folder structure to keep your project consistent, orderly and w
✅ File/Folder name regex validation with features like wildcard `*` and treating `.` as a character, along with other conveniences.<br>
✅ Build in case validation.<br>
✅ Inheriting the folder's name. The file/folder inherits the name of the folder in which it is located. Option of adding your own prefixes/suffixes or changing the case.<br>
✅ Enforcing the existence of a file/folder when a specific file/folder exists. For example, if `./src/Component.tsx` exists, then `./src/Component.test.tsx` and `./src/stories/Component.stories.tsx` must also exist.<br>
✅ Enforcing the existence of a files/folders when a specific file/folder exists. For example, if `./src/Component.tsx` exists, then `./src/Component.test.tsx` and `./src/stories/Component.stories.tsx` must also exist.<br>
✅ Reusable rules for folder structures.<br>
✅ An option to create a separate configuration file with TypeScript support.<br>
✅ Forcing a nested/flat structure for a given folder.<br>
Expand Down Expand Up @@ -164,20 +164,18 @@ Create a **`folderStructure.mjs`** in the root of your project.<br>
import { createFolderStructure } from "eslint-plugin-project-structure";

export const folderStructureConfig = createFolderStructure({
structure: {
children: [
// Allow any files in the root of your project, like package.json, eslint.config.mjs, etc. You can add rules for them separately.
// You can also add exceptions like this: "(?!folderStructure)*"
{ name: "*" },
{
name: "src",
children: [
{ name: "index.tsx" },
{ name: "components", children: [{ name: "{PascalCase}.tsx" }] },
],
},
],
},
structure: [
// Allow any files in the root of your project, like package.json, eslint.config.mjs, etc. You can add rules for them separately.
// You can also add exceptions like this: "(?!folderStructure)*"
{ name: "*" },
{
name: "src",
children: [
{ name: "index.tsx" },
{ name: "components", children: [{ name: "{PascalCase}.tsx" }] },
],
},
],
});
```

Expand Down Expand Up @@ -239,17 +237,15 @@ import { createFolderStructure } from "eslint-plugin-project-structure";

export const folderStructureConfig = createFolderStructure({
ignorePatterns: ["src/legacy/**"],
structure: {
children: [
// Allow any files in the root of your project, like package.json, eslint.config.mjs, etc. You can add rules for them separately.
// You can also add exceptions like this: "(?!folderStructure)*"
{ name: "*" },
{
name: "src",
children: [{ ruleId: "hooks_folder" }, { ruleId: "components_folder" }],
},
],
},
structure: [
// Allow any files in the root of your project, like package.json, eslint.config.mjs, etc. You can add rules for them separately.
// You can also add exceptions like this: "(?!folderStructure)*"
{ name: "*" },
{
name: "src",
children: [{ ruleId: "hooks_folder" }, { ruleId: "components_folder" }],
},
],
rules: {
hooks_folder: {
name: "hooks",
Expand Down Expand Up @@ -441,7 +437,13 @@ In `enforceExistence`, two references are available for use:
```jsonc
{
"structure": {
// If root directory exists.
"enforceExistence": [
"src", // ./src must exist.
"src/components", // ./src/components must exist.
],
"children": [
{ "name": "*" },
{
"name": "src",
"children": [
Expand All @@ -459,20 +461,12 @@ In `enforceExistence`, two references are available for use:
},
],
},
{
"name": "*",
// If any file exists in the root directory of the project.
"enforceExistence": [
"src", // ./src must exist.
"src/components", // ./src/components must exist.
],
},
],
},
}
```

### **`structure`**: `<Rule>` <a id="structure"></a>
### **`structure`**: `<Rule> | <Rule>[]` <a id="structure"></a>

The structure of your project and its rules.

Expand All @@ -490,9 +484,25 @@ The structure of your project and its rules.
└── 📄 ...
```

```jsonc
{
"structure": [
{ "name": "libs", "children": [] },
{ "name": "src", "children": [] },
{ "name": "yourCoolFolderName", "children": [] },
// Allow any files in the root of your project, like package.json, eslint.config.mjs, etc. You can add rules for them separately.
// You can also add exceptions like this: "(?!folderStructure)*"
{ "name": "*" },
],
}
```

or

```jsonc
{
"structure": {
"enforceExistence": ["src"],
"children": [
{ "name": "libs", "children": [] },
{ "name": "src", "children": [] },
Expand Down
12 changes: 11 additions & 1 deletion folderStructure.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,17 @@
}
},
"structure": {
"$ref": "#/definitions/Rule"
"oneOf": [
{
"$ref": "#/definitions/Rule"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/Rule"
}
}
]
},
"rules": {
"type": "object",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"author": "Igor Kowalski (Igorkowalski94)",
"name": "eslint-plugin-project-structure",
"version": "2.1.17",
"version": "2.1.18",
"license": "MIT",
"description": "Eslint plugin with rules that will help you achieve a project structure that is scalable, consistent, and well thought out. Whether you're working alone or with a small or large team, save time by automating the reviews of key principles for a healthy project!",
"keywords": [
Expand Down
69 changes: 0 additions & 69 deletions src/rules/folderStructure/folderStructure.consts.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,6 @@
import { JSONSchema4 } from "@typescript-eslint/utils/dist/json-schema";

export const REFERENCES = {
parentName: "{parentName}",
ParentName: "{ParentName}",
name: "{name}",
Name: "{Name}",
};

export const FOLDER_STRUCTURE_SCHEMA: JSONSchema4 = {
$schema: "http://json-schema.org/draft-07/schema#",
definitions: {
Rule: {
type: "object",
default: { name: "" },
properties: {
ruleId: {
type: "string",
default: "",
},
name: {
type: "string",
default: "",
},
children: {
type: "array",
default: [],
items: {
$ref: "#/definitions/Rule",
},
},
enforceExistence: {
type: "array",
default: [],
items: {
type: "string",
},
},
},
additionalProperties: false,
},
RegexParameters: {
type: "object",
default: {},
additionalProperties: {
type: "string",
},
},
},
type: "object",
properties: {
ignorePatterns: {
type: "array",
default: [],
items: {
type: "string",
},
},
structure: {
$ref: "#/definitions/Rule",
},
rules: {
type: "object",
default: {},
additionalProperties: {
$ref: "#/definitions/Rule",
},
},
regexParameters: {
$ref: "#/definitions/RegexParameters",
},
},
required: ["structure"],
additionalProperties: false,
};
2 changes: 1 addition & 1 deletion src/rules/folderStructure/folderStructure.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type RegexParameters = Record<string, string>;

export interface FolderStructureConfig<T extends string = string> {
ignorePatterns?: string[];
structure: Rule<T>;
structure: Rule<T> | Rule<T>[];
rules?: Record<T, Rule<T>>;
regexParameters?: RegexParameters;
}
Expand Down
2 changes: 1 addition & 1 deletion src/rules/folderStructure/helpers/createFolderStructure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
export const createFolderStructure = <
R extends Record<string, Rule<keyof R & string>>,
>(config: {
structure: Rule<keyof R & string>;
structure: Rule<keyof R & string> | Rule<keyof R & string>[];
rules?: R;
ignorePatterns?: string[];
regexParameters?: RegexParameters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ import path, { sep } from "path";
interface GetPathsProps {
cwd: string;
filename: string;
rootFolderName: string;
}

interface GetPathsReturn {
pathname: string;
filenameWithoutCwd: string;
}

export const getPaths = ({ cwd, filename }: GetPathsProps): GetPathsReturn => {
export const getPaths = ({
cwd,
filename,
rootFolderName,
}: GetPathsProps): GetPathsReturn => {
const filenameWithoutCwd = path.relative(cwd, filename).replaceAll(sep, "/");

const pathname = path
.join("structure", filenameWithoutCwd)
.join(rootFolderName, filenameWithoutCwd)
.replaceAll(sep, "/");

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
FolderStructureConfig,
Rule,
} from "rules/folderStructure/folderStructure.types";
import { getRootRule } from "rules/folderStructure/helpers/validateFolderStructure/helpers/getRootRule";

describe("getRootRule", () => {
it.each<{ structure: FolderStructureConfig["structure"]; expected: Rule }>([
{
structure: [{ children: [] }, { name: "index.ts" }],
expected: { children: [{ children: [] }, { name: "index.ts" }] },
},
{
structure: { enforceExistence: [], children: [] },
expected: { enforceExistence: [], children: [] },
},
])("Should return correct value for %o", ({ structure, expected }) => {
expect(getRootRule(structure)).toEqual(expected);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
FolderStructureConfig,
Rule,
} from "rules/folderStructure/folderStructure.types";

export const getRootRule = (
structure: FolderStructureConfig["structure"],
): Rule => {
if (Array.isArray(structure))
return {
children: structure,
};

return structure;
};
Loading

0 comments on commit a68d91a

Please sign in to comment.