project-structure-lint 1.0.1

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.
Files changed (62) hide show
  1. package/.validate-structurerc.example.json +45 -0
  2. package/CHANGELOG.md +42 -0
  3. package/CONTRIBUTING.md +142 -0
  4. package/LICENSE +21 -0
  5. package/PROJECT_SUMMARY.md +252 -0
  6. package/QUICK_START.md +164 -0
  7. package/README.md +330 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +121 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/config/loader.d.ts +4 -0
  13. package/dist/config/loader.d.ts.map +1 -0
  14. package/dist/config/loader.js +71 -0
  15. package/dist/config/loader.js.map +1 -0
  16. package/dist/core/validator.d.ts +16 -0
  17. package/dist/core/validator.d.ts.map +1 -0
  18. package/dist/core/validator.js +231 -0
  19. package/dist/core/validator.js.map +1 -0
  20. package/dist/index.d.ts +6 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +29 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/presets/index.d.ts +5 -0
  25. package/dist/presets/index.d.ts.map +1 -0
  26. package/dist/presets/index.js +17 -0
  27. package/dist/presets/index.js.map +1 -0
  28. package/dist/presets/react.d.ts +3 -0
  29. package/dist/presets/react.d.ts.map +1 -0
  30. package/dist/presets/react.js +94 -0
  31. package/dist/presets/react.js.map +1 -0
  32. package/dist/reporters/consoleReporter.d.ts +9 -0
  33. package/dist/reporters/consoleReporter.d.ts.map +1 -0
  34. package/dist/reporters/consoleReporter.js +98 -0
  35. package/dist/reporters/consoleReporter.js.map +1 -0
  36. package/dist/types/index.d.ts +59 -0
  37. package/dist/types/index.d.ts.map +1 -0
  38. package/dist/types/index.js +4 -0
  39. package/dist/types/index.js.map +1 -0
  40. package/dist/utils/fileScanner.d.ts +20 -0
  41. package/dist/utils/fileScanner.d.ts.map +1 -0
  42. package/dist/utils/fileScanner.js +166 -0
  43. package/dist/utils/fileScanner.js.map +1 -0
  44. package/dist/utils/naming.d.ts +4 -0
  45. package/dist/utils/naming.d.ts.map +1 -0
  46. package/dist/utils/naming.js +75 -0
  47. package/dist/utils/naming.js.map +1 -0
  48. package/jest.config.js +17 -0
  49. package/package.json +48 -0
  50. package/src/cli.ts +106 -0
  51. package/src/config/loader.ts +79 -0
  52. package/src/core/validator.ts +242 -0
  53. package/src/index.ts +6 -0
  54. package/src/presets/index.ts +16 -0
  55. package/src/presets/react.ts +93 -0
  56. package/src/reporters/consoleReporter.ts +116 -0
  57. package/src/types/index.ts +67 -0
  58. package/src/types/micromatch.d.ts +41 -0
  59. package/src/utils/__tests__/naming.test.ts +107 -0
  60. package/src/utils/fileScanner.ts +162 -0
  61. package/src/utils/naming.ts +99 -0
  62. package/tsconfig.json +20 -0
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ProjectValidator = void 0;
40
+ const path = __importStar(require("path"));
41
+ const micromatch_1 = __importDefault(require("micromatch"));
42
+ const fileScanner_1 = require("../utils/fileScanner");
43
+ const naming_1 = require("../utils/naming");
44
+ class ProjectValidator {
45
+ constructor(config, rootDir = process.cwd()) {
46
+ this.errors = [];
47
+ this.warnings = [];
48
+ this.config = config;
49
+ const ignorePatterns = config.ignore || [];
50
+ this.scanner = new fileScanner_1.FileScanner(rootDir, ignorePatterns);
51
+ }
52
+ async validate() {
53
+ this.errors = [];
54
+ this.warnings = [];
55
+ const files = await this.scanner.scanDirectory();
56
+ const filesScanned = files.filter(f => !f.isDirectory).length;
57
+ const directoriesScanned = files.filter(f => f.isDirectory).length;
58
+ // Validate component co-location
59
+ if (this.config.rules?.componentColocation?.enabled) {
60
+ await this.validateComponentColocation();
61
+ }
62
+ // Validate file naming conventions
63
+ if (this.config.rules?.fileNaming) {
64
+ await this.validateFileNaming(files);
65
+ }
66
+ // Validate folder structure
67
+ if (this.config.rules?.folderStructure) {
68
+ await this.validateFolderStructure(files);
69
+ }
70
+ return {
71
+ valid: this.errors.length === 0,
72
+ errors: this.errors,
73
+ warnings: this.warnings,
74
+ filesScanned,
75
+ directoriesScanned
76
+ };
77
+ }
78
+ async validateComponentColocation() {
79
+ const colocationConfig = this.config.rules?.componentColocation;
80
+ if (!colocationConfig)
81
+ return;
82
+ const componentDirs = this.scanner.getComponentDirectories(colocationConfig.componentDirs);
83
+ for (const dir of componentDirs) {
84
+ const contents = await this.scanner.getDirectoryContents(dir);
85
+ const componentName = path.basename(dir);
86
+ // Find the main component file
87
+ const mainFile = contents.find(f => !f.isDirectory &&
88
+ this.isComponentFile(f.name, componentName));
89
+ if (!mainFile) {
90
+ continue; // Skip if no main component file found
91
+ }
92
+ // Check for required files
93
+ for (const filePattern of colocationConfig.requiredFiles) {
94
+ if (!filePattern.required)
95
+ continue;
96
+ const expectedPattern = this.expandPattern(filePattern.pattern, componentName);
97
+ const matchingFile = contents.find(f => !f.isDirectory && micromatch_1.default.isMatch(f.name, expectedPattern));
98
+ if (!matchingFile) {
99
+ const error = {
100
+ type: 'missing-file',
101
+ severity: this.config.severity || 'error',
102
+ message: `Missing required file: ${filePattern.description || expectedPattern}`,
103
+ directory: dir,
104
+ expected: expectedPattern,
105
+ suggestion: `Create ${expectedPattern} in ${dir}/`
106
+ };
107
+ this.addError(error);
108
+ }
109
+ }
110
+ // Validate naming convention for component
111
+ if (colocationConfig.namingConvention) {
112
+ const isValid = (0, naming_1.validateNamingConvention)(componentName, colocationConfig.namingConvention);
113
+ if (!isValid) {
114
+ const expected = (0, naming_1.getExpectedNaming)(componentName, colocationConfig.namingConvention);
115
+ const error = {
116
+ type: 'naming-violation',
117
+ severity: this.config.severity || 'error',
118
+ message: `Component directory name doesn't follow ${colocationConfig.namingConvention} convention`,
119
+ directory: dir,
120
+ actual: componentName,
121
+ expected,
122
+ suggestion: `Rename directory to ${expected}`
123
+ };
124
+ this.addError(error);
125
+ }
126
+ }
127
+ }
128
+ }
129
+ async validateFileNaming(files) {
130
+ const namingRules = this.config.rules?.fileNaming;
131
+ if (!namingRules)
132
+ return;
133
+ for (const file of files) {
134
+ if (file.isDirectory)
135
+ continue;
136
+ // Check each naming rule pattern
137
+ for (const [pattern, rule] of Object.entries(namingRules)) {
138
+ if (micromatch_1.default.isMatch(file.path, pattern)) {
139
+ const isValid = (0, naming_1.validateNamingConvention)(file.name, rule.convention);
140
+ if (!isValid) {
141
+ const expected = (0, naming_1.getExpectedNaming)(file.name, rule.convention);
142
+ const error = {
143
+ type: 'naming-violation',
144
+ severity: rule.severity || this.config.severity || 'error',
145
+ message: `File name doesn't follow ${rule.convention} convention`,
146
+ file: file.path,
147
+ actual: file.name,
148
+ expected,
149
+ suggestion: `Rename to ${expected}`
150
+ };
151
+ this.addError(error);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ async validateFolderStructure(files) {
158
+ const folderRules = this.config.rules?.folderStructure;
159
+ if (!folderRules)
160
+ return;
161
+ for (const rule of folderRules) {
162
+ // Check if required folder exists
163
+ if (!this.scanner.isDirectory(rule.path)) {
164
+ const error = {
165
+ type: 'structure-violation',
166
+ severity: this.config.severity || 'error',
167
+ message: `Required directory not found: ${rule.name}`,
168
+ directory: rule.path,
169
+ suggestion: `Create directory at ${rule.path}`
170
+ };
171
+ this.addError(error);
172
+ continue;
173
+ }
174
+ // Get files in this directory
175
+ const dirFiles = files.filter(f => f.path.startsWith(rule.path) && !f.isDirectory);
176
+ // Validate file extensions
177
+ if (rule.allowedExtensions) {
178
+ for (const file of dirFiles) {
179
+ if (!rule.allowedExtensions.includes(file.extension)) {
180
+ const error = {
181
+ type: 'forbidden-file',
182
+ severity: 'warning',
183
+ message: `File extension ${file.extension} not allowed in ${rule.name}`,
184
+ file: file.path,
185
+ suggestion: `Allowed extensions: ${rule.allowedExtensions.join(', ')}`
186
+ };
187
+ this.addError(error);
188
+ }
189
+ }
190
+ }
191
+ // Validate naming convention for files in this directory
192
+ if (rule.namingConvention) {
193
+ for (const file of dirFiles) {
194
+ const isValid = (0, naming_1.validateNamingConvention)(file.name, rule.namingConvention);
195
+ if (!isValid) {
196
+ const expected = (0, naming_1.getExpectedNaming)(file.name, rule.namingConvention);
197
+ const error = {
198
+ type: 'naming-violation',
199
+ severity: this.config.severity || 'error',
200
+ message: `File in ${rule.name} doesn't follow ${rule.namingConvention} convention`,
201
+ file: file.path,
202
+ actual: file.name,
203
+ expected,
204
+ suggestion: `Rename to ${expected}`
205
+ };
206
+ this.addError(error);
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+ isComponentFile(filename, componentName) {
213
+ const nameWithoutExt = filename.replace(/\.[^/.]+$/, '');
214
+ return nameWithoutExt === componentName ||
215
+ nameWithoutExt.toLowerCase() === componentName.toLowerCase();
216
+ }
217
+ expandPattern(pattern, componentName) {
218
+ return pattern.replace(/\*/g, componentName);
219
+ }
220
+ addError(error) {
221
+ if (error.severity === 'warning') {
222
+ this.warnings.push(error);
223
+ }
224
+ else {
225
+ this.errors.push(error);
226
+ }
227
+ }
228
+ }
229
+ exports.ProjectValidator = ProjectValidator;
230
+ // Made with
231
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { ProjectValidator } from './core/validator';
2
+ export { loadConfig, validateConfig } from './config/loader';
3
+ export { ConsoleReporter } from './reporters/consoleReporter';
4
+ export { getPreset, listPresets } from './presets';
5
+ export * from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.listPresets = exports.getPreset = exports.ConsoleReporter = exports.validateConfig = exports.loadConfig = exports.ProjectValidator = void 0;
18
+ var validator_1 = require("./core/validator");
19
+ Object.defineProperty(exports, "ProjectValidator", { enumerable: true, get: function () { return validator_1.ProjectValidator; } });
20
+ var loader_1 = require("./config/loader");
21
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return loader_1.loadConfig; } });
22
+ Object.defineProperty(exports, "validateConfig", { enumerable: true, get: function () { return loader_1.validateConfig; } });
23
+ var consoleReporter_1 = require("./reporters/consoleReporter");
24
+ Object.defineProperty(exports, "ConsoleReporter", { enumerable: true, get: function () { return consoleReporter_1.ConsoleReporter; } });
25
+ var presets_1 = require("./presets");
26
+ Object.defineProperty(exports, "getPreset", { enumerable: true, get: function () { return presets_1.getPreset; } });
27
+ Object.defineProperty(exports, "listPresets", { enumerable: true, get: function () { return presets_1.listPresets; } });
28
+ __exportStar(require("./types"), exports);
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,8CAAoD;AAA3C,6GAAA,gBAAgB,OAAA;AACzB,0CAA6D;AAApD,oGAAA,UAAU,OAAA;AAAE,wGAAA,cAAc,OAAA;AACnC,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AACxB,qCAAmD;AAA1C,oGAAA,SAAS,OAAA;AAAE,sGAAA,WAAW,OAAA;AAC/B,0CAAwB"}
@@ -0,0 +1,5 @@
1
+ import { Preset } from '../types';
2
+ export declare const presets: Record<string, Preset>;
3
+ export declare function getPreset(name: string): Preset | undefined;
4
+ export declare function listPresets(): string[];
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAE1C,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1D;AAED,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAEtC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.presets = void 0;
4
+ exports.getPreset = getPreset;
5
+ exports.listPresets = listPresets;
6
+ const react_1 = require("./react");
7
+ exports.presets = {
8
+ react: react_1.reactPreset
9
+ };
10
+ function getPreset(name) {
11
+ return exports.presets[name];
12
+ }
13
+ function listPresets() {
14
+ return Object.keys(exports.presets);
15
+ }
16
+ // Made with
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":";;;AAOA,8BAEC;AAED,kCAEC;AAZD,mCAAsC;AAEzB,QAAA,OAAO,GAA2B;IAC7C,KAAK,EAAE,mBAAW;CACnB,CAAC;AAEF,SAAgB,SAAS,CAAC,IAAY;IACpC,OAAO,eAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,SAAgB,WAAW;IACzB,OAAO,MAAM,CAAC,IAAI,CAAC,eAAO,CAAC,CAAC;AAC9B,CAAC;AAED,aAAa"}
@@ -0,0 +1,3 @@
1
+ import { Preset } from '../types';
2
+ export declare const reactPreset: Preset;
3
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/presets/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,eAAO,MAAM,WAAW,EAAE,MAwFzB,CAAC"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reactPreset = void 0;
4
+ exports.reactPreset = {
5
+ name: 'react',
6
+ description: 'React project with component co-location and testing requirements',
7
+ config: {
8
+ preset: 'react',
9
+ rootDir: 'src',
10
+ rules: {
11
+ componentColocation: {
12
+ enabled: true,
13
+ componentDirs: ['components', 'pages', 'features'],
14
+ requiredFiles: [
15
+ {
16
+ pattern: '*.test.{ts,tsx,js,jsx}',
17
+ required: true,
18
+ description: 'Test file for component'
19
+ },
20
+ {
21
+ pattern: '*.stories.{ts,tsx,js,jsx}',
22
+ required: true,
23
+ description: 'Storybook story file'
24
+ },
25
+ {
26
+ pattern: 'index.{ts,tsx,js,jsx}',
27
+ required: false,
28
+ description: 'Index file for re-exports'
29
+ }
30
+ ],
31
+ namingConvention: 'PascalCase'
32
+ },
33
+ fileNaming: {
34
+ 'components/**/*.{tsx,jsx}': {
35
+ convention: 'PascalCase',
36
+ severity: 'error'
37
+ },
38
+ 'hooks/**/*.{ts,tsx,js,jsx}': {
39
+ convention: 'camelCase',
40
+ severity: 'error'
41
+ },
42
+ 'utils/**/*.{ts,js}': {
43
+ convention: 'camelCase',
44
+ severity: 'error'
45
+ },
46
+ 'types/**/*.{ts,tsx}': {
47
+ convention: 'PascalCase',
48
+ severity: 'error'
49
+ },
50
+ 'constants/**/*.{ts,js}': {
51
+ convention: 'UPPER_CASE',
52
+ severity: 'warning'
53
+ }
54
+ },
55
+ folderStructure: [
56
+ {
57
+ name: 'components',
58
+ path: 'src/components',
59
+ namingConvention: 'PascalCase',
60
+ allowedExtensions: ['.tsx', '.ts', '.jsx', '.js', '.css', '.scss', '.module.css']
61
+ },
62
+ {
63
+ name: 'hooks',
64
+ path: 'src/hooks',
65
+ namingConvention: 'camelCase',
66
+ allowedExtensions: ['.ts', '.tsx', '.js', '.jsx']
67
+ },
68
+ {
69
+ name: 'utils',
70
+ path: 'src/utils',
71
+ namingConvention: 'camelCase',
72
+ allowedExtensions: ['.ts', '.js']
73
+ },
74
+ {
75
+ name: 'types',
76
+ path: 'src/types',
77
+ namingConvention: 'PascalCase',
78
+ allowedExtensions: ['.ts', '.d.ts']
79
+ }
80
+ ]
81
+ },
82
+ ignore: [
83
+ '**/node_modules/**',
84
+ '**/dist/**',
85
+ '**/build/**',
86
+ '**/.next/**',
87
+ '**/coverage/**',
88
+ '**/.git/**'
89
+ ],
90
+ severity: 'error'
91
+ }
92
+ };
93
+ // Made with
94
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/presets/react.ts"],"names":[],"mappings":";;;AAEa,QAAA,WAAW,GAAW;IACjC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,mEAAmE;IAChF,MAAM,EAAE;QACN,MAAM,EAAE,OAAO;QACf,OAAO,EAAE,KAAK;QACd,KAAK,EAAE;YACL,mBAAmB,EAAE;gBACnB,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,CAAC;gBAClD,aAAa,EAAE;oBACb;wBACE,OAAO,EAAE,wBAAwB;wBACjC,QAAQ,EAAE,IAAI;wBACd,WAAW,EAAE,yBAAyB;qBACvC;oBACD;wBACE,OAAO,EAAE,2BAA2B;wBACpC,QAAQ,EAAE,IAAI;wBACd,WAAW,EAAE,sBAAsB;qBACpC;oBACD;wBACE,OAAO,EAAE,uBAAuB;wBAChC,QAAQ,EAAE,KAAK;wBACf,WAAW,EAAE,2BAA2B;qBACzC;iBACF;gBACD,gBAAgB,EAAE,YAAY;aAC/B;YACD,UAAU,EAAE;gBACV,2BAA2B,EAAE;oBAC3B,UAAU,EAAE,YAAY;oBACxB,QAAQ,EAAE,OAAO;iBAClB;gBACD,4BAA4B,EAAE;oBAC5B,UAAU,EAAE,WAAW;oBACvB,QAAQ,EAAE,OAAO;iBAClB;gBACD,oBAAoB,EAAE;oBACpB,UAAU,EAAE,WAAW;oBACvB,QAAQ,EAAE,OAAO;iBAClB;gBACD,qBAAqB,EAAE;oBACrB,UAAU,EAAE,YAAY;oBACxB,QAAQ,EAAE,OAAO;iBAClB;gBACD,wBAAwB,EAAE;oBACxB,UAAU,EAAE,YAAY;oBACxB,QAAQ,EAAE,SAAS;iBACpB;aACF;YACD,eAAe,EAAE;gBACf;oBACE,IAAI,EAAE,YAAY;oBAClB,IAAI,EAAE,gBAAgB;oBACtB,gBAAgB,EAAE,YAAY;oBAC9B,iBAAiB,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;iBAClF;gBACD;oBACE,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,WAAW;oBACjB,gBAAgB,EAAE,WAAW;oBAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;iBAClD;gBACD;oBACE,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,WAAW;oBACjB,gBAAgB,EAAE,WAAW;oBAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;iBAClC;gBACD;oBACE,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,WAAW;oBACjB,gBAAgB,EAAE,YAAY;oBAC9B,iBAAiB,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;iBACpC;aACF;SACF;QACD,MAAM,EAAE;YACN,oBAAoB;YACpB,YAAY;YACZ,aAAa;YACb,aAAa;YACb,gBAAgB;YAChB,YAAY;SACb;QACD,QAAQ,EAAE,OAAO;KAClB;CACF,CAAC;AAEF,aAAa"}
@@ -0,0 +1,9 @@
1
+ import { ValidationResult } from '../types';
2
+ export declare class ConsoleReporter {
3
+ report(result: ValidationResult): void;
4
+ private printError;
5
+ private printWarning;
6
+ reportConfigError(error: string): void;
7
+ reportConfigErrors(errors: string[]): void;
8
+ }
9
+ //# sourceMappingURL=consoleReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consoleReporter.d.ts","sourceRoot":"","sources":["../../src/reporters/consoleReporter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,UAAU,CAAC;AAE7D,qBAAa,eAAe;IAC1B,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IA4CtC,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,YAAY;IA0BpB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMtC,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;CAO3C"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ConsoleReporter = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ class ConsoleReporter {
9
+ report(result) {
10
+ console.log('\n' + chalk_1.default.bold('Project Structure Validation Results'));
11
+ console.log(chalk_1.default.gray('─'.repeat(50)));
12
+ console.log(chalk_1.default.gray(`Files scanned: ${result.filesScanned}`));
13
+ console.log(chalk_1.default.gray(`Directories scanned: ${result.directoriesScanned}`));
14
+ console.log('');
15
+ if (result.errors.length === 0 && result.warnings.length === 0) {
16
+ console.log(chalk_1.default.green('✓ No issues found!'));
17
+ console.log('');
18
+ return;
19
+ }
20
+ // Report errors
21
+ if (result.errors.length > 0) {
22
+ console.log(chalk_1.default.red.bold(`✗ ${result.errors.length} Error${result.errors.length > 1 ? 's' : ''}`));
23
+ console.log('');
24
+ result.errors.forEach((error, index) => {
25
+ this.printError(error, index + 1);
26
+ });
27
+ }
28
+ // Report warnings
29
+ if (result.warnings.length > 0) {
30
+ console.log(chalk_1.default.yellow.bold(`âš  ${result.warnings.length} Warning${result.warnings.length > 1 ? 's' : ''}`));
31
+ console.log('');
32
+ result.warnings.forEach((warning, index) => {
33
+ this.printWarning(warning, index + 1);
34
+ });
35
+ }
36
+ console.log(chalk_1.default.gray('─'.repeat(50)));
37
+ if (result.errors.length > 0) {
38
+ console.log(chalk_1.default.red.bold(`\n✗ Validation failed with ${result.errors.length} error${result.errors.length > 1 ? 's' : ''}`));
39
+ }
40
+ else {
41
+ console.log(chalk_1.default.yellow.bold(`\nâš  Validation passed with ${result.warnings.length} warning${result.warnings.length > 1 ? 's' : ''}`));
42
+ }
43
+ console.log('');
44
+ }
45
+ printError(error, index) {
46
+ console.log(chalk_1.default.red(`${index}. ${error.message}`));
47
+ if (error.file) {
48
+ console.log(chalk_1.default.gray(` File: ${error.file}`));
49
+ }
50
+ if (error.directory) {
51
+ console.log(chalk_1.default.gray(` Directory: ${error.directory}`));
52
+ }
53
+ if (error.actual) {
54
+ console.log(chalk_1.default.gray(` Actual: ${error.actual}`));
55
+ }
56
+ if (error.expected) {
57
+ console.log(chalk_1.default.gray(` Expected: ${error.expected}`));
58
+ }
59
+ if (error.suggestion) {
60
+ console.log(chalk_1.default.cyan(` 💡 ${error.suggestion}`));
61
+ }
62
+ console.log('');
63
+ }
64
+ printWarning(warning, index) {
65
+ console.log(chalk_1.default.yellow(`${index}. ${warning.message}`));
66
+ if (warning.file) {
67
+ console.log(chalk_1.default.gray(` File: ${warning.file}`));
68
+ }
69
+ if (warning.directory) {
70
+ console.log(chalk_1.default.gray(` Directory: ${warning.directory}`));
71
+ }
72
+ if (warning.actual) {
73
+ console.log(chalk_1.default.gray(` Actual: ${warning.actual}`));
74
+ }
75
+ if (warning.expected) {
76
+ console.log(chalk_1.default.gray(` Expected: ${warning.expected}`));
77
+ }
78
+ if (warning.suggestion) {
79
+ console.log(chalk_1.default.cyan(` 💡 ${warning.suggestion}`));
80
+ }
81
+ console.log('');
82
+ }
83
+ reportConfigError(error) {
84
+ console.log(chalk_1.default.red.bold('\n✗ Configuration Error'));
85
+ console.log(chalk_1.default.red(error));
86
+ console.log('');
87
+ }
88
+ reportConfigErrors(errors) {
89
+ console.log(chalk_1.default.red.bold('\n✗ Configuration Errors'));
90
+ errors.forEach(error => {
91
+ console.log(chalk_1.default.red(` • ${error}`));
92
+ });
93
+ console.log('');
94
+ }
95
+ }
96
+ exports.ConsoleReporter = ConsoleReporter;
97
+ // Made with
98
+ //# sourceMappingURL=consoleReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consoleReporter.js","sourceRoot":"","sources":["../../src/reporters/consoleReporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ export type NamingConvention = 'PascalCase' | 'camelCase' | 'kebab-case' | 'snake_case' | 'UPPER_CASE';
2
+ export type Severity = 'error' | 'warning';
3
+ export interface FilePattern {
4
+ pattern: string;
5
+ required?: boolean;
6
+ description?: string;
7
+ }
8
+ export interface FolderRule {
9
+ name: string;
10
+ path: string;
11
+ requiredFiles?: FilePattern[];
12
+ namingConvention?: NamingConvention;
13
+ allowedExtensions?: string[];
14
+ maxDepth?: number;
15
+ }
16
+ export interface ProjectConfig {
17
+ preset?: string;
18
+ rootDir?: string;
19
+ rules?: {
20
+ folderStructure?: FolderRule[];
21
+ componentColocation?: {
22
+ enabled: boolean;
23
+ componentDirs: string[];
24
+ requiredFiles: FilePattern[];
25
+ namingConvention?: NamingConvention;
26
+ };
27
+ fileNaming?: {
28
+ [pattern: string]: {
29
+ convention: NamingConvention;
30
+ severity?: Severity;
31
+ };
32
+ };
33
+ };
34
+ ignore?: string[];
35
+ severity?: Severity;
36
+ }
37
+ export interface ValidationError {
38
+ type: 'missing-file' | 'naming-violation' | 'structure-violation' | 'forbidden-file';
39
+ severity: Severity;
40
+ message: string;
41
+ file?: string;
42
+ directory?: string;
43
+ expected?: string;
44
+ actual?: string;
45
+ suggestion?: string;
46
+ }
47
+ export interface ValidationResult {
48
+ valid: boolean;
49
+ errors: ValidationError[];
50
+ warnings: ValidationError[];
51
+ filesScanned: number;
52
+ directoriesScanned: number;
53
+ }
54
+ export interface Preset {
55
+ name: string;
56
+ description: string;
57
+ config: ProjectConfig;
58
+ }
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAEvG,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,WAAW,EAAE,CAAC;IAC9B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,eAAe,CAAC,EAAE,UAAU,EAAE,CAAC;QAC/B,mBAAmB,CAAC,EAAE;YACpB,OAAO,EAAE,OAAO,CAAC;YACjB,aAAa,EAAE,MAAM,EAAE,CAAC;YACxB,aAAa,EAAE,WAAW,EAAE,CAAC;YAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;SACrC,CAAC;QACF,UAAU,CAAC,EAAE;YACX,CAAC,OAAO,EAAE,MAAM,GAAG;gBACjB,UAAU,EAAE,gBAAgB,CAAC;gBAC7B,QAAQ,CAAC,EAAE,QAAQ,CAAC;aACrB,CAAC;SACH,CAAC;KACH,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,cAAc,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;IACrF,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // Made with
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;AAkEA,aAAa"}
@@ -0,0 +1,20 @@
1
+ export interface ScannedFile {
2
+ path: string;
3
+ name: string;
4
+ directory: string;
5
+ extension: string;
6
+ isDirectory: boolean;
7
+ }
8
+ export declare class FileScanner {
9
+ private rootDir;
10
+ private ignorePatterns;
11
+ constructor(rootDir: string, ignorePatterns?: string[]);
12
+ scanDirectory(dir?: string): Promise<ScannedFile[]>;
13
+ findFiles(pattern: string, baseDir?: string): Promise<string[]>;
14
+ getDirectoryContents(dir: string): Promise<ScannedFile[]>;
15
+ getComponentDirectories(componentDirs: string[]): string[];
16
+ private shouldIgnore;
17
+ fileExists(filePath: string): boolean;
18
+ isDirectory(filePath: string): boolean;
19
+ }
20
+ //# sourceMappingURL=fileScanner.d.ts.map