eslint-plugin-fsd-paths-check 0.0.17 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,103 +1,11 @@
1
1
  "use strict";
2
2
 
3
- const path = require("path");
4
- const fs = require("fs");
5
- const { allFsdLayers } = require("../constants/constants");
6
-
7
- const calculateRelativePath = (fromFile, toFile) => {
8
- const fromDir = path.dirname(fromFile);
9
- let relative = path.relative(fromDir, toFile);
10
-
11
- if (!relative.startsWith('.') && !relative.startsWith('/')) {
12
- relative = `./${relative}`;
13
- }
14
-
15
- relative = relative.replace(/\\/g, '/');
16
-
17
- return relative;
18
- };
19
-
20
- const getFsdSlice = (filePath) => {
21
- const normalized = filePath.replace(/\\/g, '/');
22
- const segments = normalized.split('/');
23
- const layerIndex = segments.findIndex(segment => allFsdLayers.includes(segment));
24
-
25
- if (layerIndex === -1) return null;
26
- if (layerIndex + 1 >= segments.length) return segments[layerIndex];
27
-
28
- return `${segments[layerIndex]}/${segments[layerIndex + 1]}`;
29
- };
30
-
31
3
  const isOnlyParentDirs = (importPath) => {
32
4
  const normalized = importPath.replace(/\\/g, '/');
33
5
  const segments = normalized.split('/').filter(s => s.length > 0);
34
6
  return segments.every(s => s === '..');
35
7
  };
36
8
 
37
- const resolveTargetDirectory = (importPath, currentFile) => {
38
- const currentDir = path.dirname(currentFile);
39
- const normalized = importPath.replace(/\\/g, '/');
40
- const parentCount = normalized.split('/').filter(s => s === '..').length;
41
-
42
- let targetDir = currentDir;
43
- for (let i = 0; i < parentCount; i++) {
44
- targetDir = path.dirname(targetDir);
45
- }
46
-
47
- return targetDir;
48
- };
49
-
50
- const findReExportInIndex = (indexFilePath, exportedName) => {
51
- try {
52
- if (!fs.existsSync(indexFilePath)) {
53
- return null;
54
- }
55
-
56
- const content = fs.readFileSync(indexFilePath, 'utf-8');
57
-
58
- const exportFromRegex = /export\s*\{\s*[^}]*?\b(\w+)\s*(?:as\s*\w+)?\s*\}\s*from\s*['"]([^'"]+)['"]/g;
59
-
60
- let match;
61
- while ((match = exportFromRegex.exec(content)) !== null) {
62
- const [_, exportName, exportPath] = match;
63
- if (exportName === exportedName) {
64
- return exportPath;
65
- }
66
- }
67
-
68
- const exportAllRegex = /export\s*\*\s*from\s*['"]([^'"]+)['"]/g;
69
- while ((match = exportAllRegex.exec(content)) !== null) {
70
- const [_, exportPath] = match;
71
- }
72
-
73
- return null;
74
- } catch (error) {
75
- console.warn(`Failed to read index.ts: ${error.message}`);
76
- return null;
77
- }
78
- };
79
-
80
- const resolveActualFilePath = (basePath, relativeImport) => {
81
- const resolved = path.resolve(basePath, relativeImport);
82
-
83
- const extensions = ['', '.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx'];
84
-
85
- for (const ext of extensions) {
86
- const fullPath = resolved + ext;
87
- if (fs.existsSync(fullPath)) {
88
- return fullPath;
89
- }
90
- }
91
-
92
- return resolved;
93
- };
94
-
95
- const isSameFsdModule = (file1, file2) => {
96
- const slice1 = getFsdSlice(file1);
97
- const slice2 = getFsdSlice(file2);
98
- return slice1 !== null && slice1 === slice2;
99
- };
100
-
101
9
  module.exports = {
102
10
  meta: {
103
11
  type: `suggestion`,
@@ -106,7 +14,7 @@ module.exports = {
106
14
  recommended: false,
107
15
  url: null,
108
16
  },
109
- fixable: `code`,
17
+ fixable: null,
110
18
  schema: [],
111
19
  messages: {
112
20
  resolvePublicApiImport: `Use direct relative import instead of public API within the same module`,
@@ -117,48 +25,13 @@ module.exports = {
117
25
  return {
118
26
  ImportDeclaration(node) {
119
27
  const importPath = node.source.value;
120
- const currentFile = context.getFilename();
121
-
122
- if (!isOnlyParentDirs(importPath)) {
123
- return;
124
- }
125
-
126
- const targetDir = resolveTargetDirectory(importPath, currentFile);
127
- const indexPath = path.join(targetDir, 'index.ts');
128
28
 
129
- const importedNames = node.specifiers
130
- .filter(spec => spec.type === 'ImportSpecifier')
131
- .map(spec => spec.imported.name);
132
-
133
- if (importedNames.length === 0) {
134
- return;
135
- }
136
-
137
- const reExportPath = findReExportInIndex(indexPath, importedNames[0]);
138
-
139
- if (!reExportPath) {
140
- return;
29
+ if (isOnlyParentDirs(importPath)) {
30
+ context.report({
31
+ node,
32
+ messageId: `resolvePublicApiImport`,
33
+ });
141
34
  }
142
-
143
- const actualFilePath = resolveActualFilePath(targetDir, reExportPath);
144
-
145
- if (!isSameFsdModule(currentFile, actualFilePath)) {
146
- return;
147
- }
148
-
149
- const directRelativePath = calculateRelativePath(currentFile, actualFilePath);
150
-
151
- if (directRelativePath === importPath) {
152
- return;
153
- }
154
-
155
- context.report({
156
- node,
157
- messageId: `resolvePublicApiImport`,
158
- fix(fixer) {
159
- return fixer.replaceText(node.source, `'${directRelativePath}'`);
160
- }
161
- });
162
35
  }
163
36
  };
164
37
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-fsd-paths-check",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "Plugin to check feature sliced design paths correctness",
5
5
  "keywords": [
6
6
  "eslint",