@xanahlight/component-forge 1.4.0 → 1.5.0
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.
- package/dist/commands/check/index.d.ts +15 -0
- package/dist/commands/check/index.js +73 -4
- package/dist/commands/check/index.js.map +1 -1
- package/dist/index.js +54 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/commands/check/check.test.d.ts +0 -1
- package/dist/commands/check/check.test.js +0 -151
- package/dist/commands/check/check.test.js.map +0 -1
- package/dist/commands/explain/explain.test.d.ts +0 -1
- package/dist/commands/explain/explain.test.js +0 -57
- package/dist/commands/explain/explain.test.js.map +0 -1
- package/dist/commands/generate.d.ts +0 -6
- package/dist/commands/generate.js +0 -91
- package/dist/commands/generate.js.map +0 -1
- package/dist/commands/init.d.ts +0 -10
- package/dist/commands/init.js +0 -54
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/migrate/migrate.test.d.ts +0 -1
- package/dist/commands/migrate/migrate.test.js +0 -176
- package/dist/commands/migrate/migrate.test.js.map +0 -1
- package/dist/commands/validate/validate.test.d.ts +0 -1
- package/dist/commands/validate/validate.test.js +0 -163
- package/dist/commands/validate/validate.test.js.map +0 -1
- package/dist/commands/validate.d.ts +0 -1
- package/dist/commands/validate.js +0 -119
- package/dist/commands/validate.js.map +0 -1
- package/dist/templates/files.test.d.ts +0 -1
- package/dist/templates/files.test.js +0 -174
- package/dist/templates/files.test.js.map +0 -1
- package/dist/utils/config.test.d.ts +0 -1
- package/dist/utils/config.test.js +0 -117
- package/dist/utils/config.test.js.map +0 -1
- package/dist/utils/template-resolver.test.d.ts +0 -1
- package/dist/utils/template-resolver.test.js +0 -86
- package/dist/utils/template-resolver.test.js.map +0 -1
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import type { Architecture } from '../../types/folder-tree';
|
|
2
|
+
/**
|
|
3
|
+
* Classifies a FSD violation into one of three kinds:
|
|
4
|
+
* - "same-layer" — both files live in the same FSD layer
|
|
5
|
+
* - "higher-layer" — file imports from a layer that sits ABOVE it
|
|
6
|
+
* - "modular" — modular-arch forbidden dependency
|
|
7
|
+
*/
|
|
8
|
+
export type ViolationKind = 'fsd-same-layer' | 'fsd-higher-layer' | 'modular-forbidden';
|
|
9
|
+
/**
|
|
10
|
+
* Returns a concise, actionable hint for a given violation.
|
|
11
|
+
* Exported for unit testing.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildHint(kind: ViolationKind, fromLayer: string, toLayer: string): string;
|
|
2
14
|
export interface CheckViolation {
|
|
3
15
|
file: string;
|
|
4
16
|
importPath: string;
|
|
17
|
+
/** Human-readable description of what rule was broken. */
|
|
5
18
|
message: string;
|
|
19
|
+
/** Concrete suggestion on how to fix the violation. */
|
|
20
|
+
hint: string;
|
|
6
21
|
}
|
|
7
22
|
export interface CheckResult {
|
|
8
23
|
violations: CheckViolation[];
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildHint = buildHint;
|
|
6
7
|
exports.parseImports = parseImports;
|
|
7
8
|
exports.resolveLayer = resolveLayer;
|
|
8
9
|
exports.collectSourceFiles = collectSourceFiles;
|
|
@@ -33,6 +34,72 @@ const MODULAR_FORBIDDEN = {
|
|
|
33
34
|
shared: ['modules', 'core'],
|
|
34
35
|
core: ['modules'],
|
|
35
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Per-pair advice table for FSD violations.
|
|
39
|
+
*
|
|
40
|
+
* Key format: "<fromLayer>-><toLayer>"
|
|
41
|
+
* Falls back to generic advice when a specific pair is not listed.
|
|
42
|
+
*/
|
|
43
|
+
const FSD_PAIR_HINTS = {
|
|
44
|
+
// Same-layer cross-imports
|
|
45
|
+
'features->features': 'Extract the shared logic into shared/ (e.g. shared/lib or shared/api) ' +
|
|
46
|
+
'or lift it into a widget that composes both features.',
|
|
47
|
+
'entities->entities': 'Move the shared data type or helper to shared/. ' +
|
|
48
|
+
'Entities must remain independent of each other.',
|
|
49
|
+
'widgets->widgets': 'Extract the common UI piece into shared/ui or compose them inside a page instead.',
|
|
50
|
+
'pages->pages': 'Pages should not depend on each other. ' +
|
|
51
|
+
'Move the shared UI to widgets/ or shared/ui.',
|
|
52
|
+
// Higher-layer imports (lower importing from higher)
|
|
53
|
+
'shared->entities': 'shared/ is the foundation — it must not know about entities. ' +
|
|
54
|
+
'Move the type/helper to shared/ itself, or invert the dependency.',
|
|
55
|
+
'shared->features': 'shared/ must not import from features/. ' +
|
|
56
|
+
'Extract only the primitive/generic part into shared/.',
|
|
57
|
+
'shared->widgets': 'shared/ must not import from widgets/. ' +
|
|
58
|
+
'The component should live in shared/ui or be passed as a prop.',
|
|
59
|
+
'shared->pages': 'shared/ must not import from pages/. ' +
|
|
60
|
+
'Anything shared across pages belongs in shared/ or widgets/.',
|
|
61
|
+
'entities->features': 'Entities must not depend on features. ' +
|
|
62
|
+
'If you need a callback/handler, pass it as a prop or use an event bus.',
|
|
63
|
+
'entities->widgets': 'Entities must not depend on widgets. ' +
|
|
64
|
+
'Lift the dependency inversion: pass the widget as a ReactNode prop.',
|
|
65
|
+
'entities->pages': 'Entities must not depend on pages. ' +
|
|
66
|
+
'Pages are composed at the top — entities should never reference them.',
|
|
67
|
+
'features->widgets': 'Features must not import from widgets. ' +
|
|
68
|
+
'A widget composes features, not the other way around.',
|
|
69
|
+
'features->pages': 'Features must not import from pages. ' +
|
|
70
|
+
'Consider moving the shared piece down to shared/ or entities/.',
|
|
71
|
+
'widgets->pages': 'Widgets must not import from pages. ' +
|
|
72
|
+
'Pages are the top-level composers — extract the shared part into widgets/ itself.',
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Returns a concise, actionable hint for a given violation.
|
|
76
|
+
* Exported for unit testing.
|
|
77
|
+
*/
|
|
78
|
+
function buildHint(kind, fromLayer, toLayer) {
|
|
79
|
+
if (kind === 'modular-forbidden') {
|
|
80
|
+
if (fromLayer === 'shared') {
|
|
81
|
+
return ('shared/ is infrastructure — it must not import from modules/. ' +
|
|
82
|
+
'Move the dependency into the module itself or create a shared abstraction.');
|
|
83
|
+
}
|
|
84
|
+
if (fromLayer === 'core') {
|
|
85
|
+
return ('core/ sets up the application shell and must not depend on feature modules. ' +
|
|
86
|
+
'Use dependency injection or an event bus to decouple them.');
|
|
87
|
+
}
|
|
88
|
+
return (`"${fromLayer}" must not import from "${toLayer}" in modular architecture. ` +
|
|
89
|
+
'Consider inverting the dependency or extracting shared logic into shared/.');
|
|
90
|
+
}
|
|
91
|
+
const key = `${fromLayer}->${toLayer}`;
|
|
92
|
+
if (FSD_PAIR_HINTS[key])
|
|
93
|
+
return FSD_PAIR_HINTS[key];
|
|
94
|
+
// Generic fallback
|
|
95
|
+
if (kind === 'fsd-same-layer') {
|
|
96
|
+
return (`Two slices inside "${fromLayer}" must not import from each other. ` +
|
|
97
|
+
'Extract shared logic to shared/ or compose them in a higher layer.');
|
|
98
|
+
}
|
|
99
|
+
// fsd-higher-layer fallback
|
|
100
|
+
return (`"${fromLayer}" sits below "${toLayer}" in the FSD hierarchy and must not import from it. ` +
|
|
101
|
+
'Move the shared code down to a layer that both can depend on (e.g. shared/ or entities/).');
|
|
102
|
+
}
|
|
36
103
|
// ---------------------------------------------------------------------------
|
|
37
104
|
// Import parsing — extracts all static import paths from a TS/TSX file
|
|
38
105
|
// ---------------------------------------------------------------------------
|
|
@@ -81,11 +148,13 @@ function checkFsdViolations(srcPath, relFilePath, imports) {
|
|
|
81
148
|
continue; // unknown target layer
|
|
82
149
|
// Violation: importing from the same layer OR a higher layer
|
|
83
150
|
if (targetLayerIdx >= fileLayerIdx) {
|
|
151
|
+
const kind = targetLayerIdx === fileLayerIdx ? 'fsd-same-layer' : 'fsd-higher-layer';
|
|
84
152
|
violations.push({
|
|
85
153
|
file: relFilePath,
|
|
86
154
|
importPath: imp,
|
|
87
155
|
message: `Layer "${fileLayer}" must not import from "${targetLayer}" ` +
|
|
88
156
|
`(${targetLayer} is at the same level or higher in FSD hierarchy)`,
|
|
157
|
+
hint: buildHint(kind, fileLayer, targetLayer),
|
|
89
158
|
});
|
|
90
159
|
}
|
|
91
160
|
}
|
|
@@ -116,6 +185,7 @@ function checkModularViolations(srcPath, relFilePath, imports) {
|
|
|
116
185
|
file: relFilePath,
|
|
117
186
|
importPath: imp,
|
|
118
187
|
message: `Layer "${fileLayer}" must not import from "${targetLayer}" in modular architecture`,
|
|
188
|
+
hint: buildHint('modular-forbidden', fileLayer, targetLayer),
|
|
119
189
|
});
|
|
120
190
|
}
|
|
121
191
|
}
|
|
@@ -174,12 +244,11 @@ function checkCommand() {
|
|
|
174
244
|
for (const v of violations) {
|
|
175
245
|
console.log(chalk_1.default.bold(chalk_1.default.white(` ${v.file}`)));
|
|
176
246
|
console.log(chalk_1.default.gray(` import "${v.importPath}"`));
|
|
177
|
-
console.log(chalk_1.default.red(` ${v.message}
|
|
247
|
+
console.log(chalk_1.default.red(` ✗ ${v.message}`));
|
|
248
|
+
console.log(chalk_1.default.yellow(` → Fix: ${v.hint}\n`));
|
|
178
249
|
}
|
|
179
|
-
logger_1.logger.info(chalk_1.default.yellow('Tip: ') +
|
|
180
|
-
'Each layer should only import from layers below it in the hierarchy.');
|
|
181
250
|
if (config.architecture === 'fsd') {
|
|
182
|
-
|
|
251
|
+
console.log(chalk_1.default.gray(' FSD order (low → high): shared → entities → features → widgets → pages → app\n'));
|
|
183
252
|
}
|
|
184
253
|
process.exit(1);
|
|
185
254
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/check/index.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/check/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,11 +8,14 @@ const generate_1 = require("./commands/generate");
|
|
|
8
8
|
const init_1 = require("./commands/init");
|
|
9
9
|
const migrate_1 = require("./commands/migrate");
|
|
10
10
|
const validate_1 = require("./commands/validate");
|
|
11
|
+
// Read version from package.json at runtime — stays in sync automatically.
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
13
|
+
const { version } = require('../package.json');
|
|
11
14
|
const program = new commander_1.Command();
|
|
12
15
|
program
|
|
13
16
|
.name('component-forge')
|
|
14
17
|
.description('Architecture-first CLI for scalable React projects')
|
|
15
|
-
.version(
|
|
18
|
+
.version(version);
|
|
16
19
|
// ---------------------------------------------------------------------------
|
|
17
20
|
// init
|
|
18
21
|
// ---------------------------------------------------------------------------
|
|
@@ -41,8 +44,34 @@ program
|
|
|
41
44
|
}
|
|
42
45
|
return value;
|
|
43
46
|
})
|
|
44
|
-
.argument('<name>', 'Slice name
|
|
47
|
+
.argument('<name>', 'Slice name — supports nested paths (e.g. auth/LoginForm) to place the slice inside a subfolder')
|
|
45
48
|
.option('--dry-run', 'Preview files that would be generated without writing them')
|
|
49
|
+
.addHelpText('after', `
|
|
50
|
+
Slice types and their generated structure:
|
|
51
|
+
feature Full vertical slice → ui/<Name>.tsx model/index.ts api/index.ts index.ts
|
|
52
|
+
entity Data-layer slice → model/index.ts api/index.ts index.ts
|
|
53
|
+
widget Composite UI block → ui/<Name>.tsx model/index.ts index.ts
|
|
54
|
+
page Route-level shell → ui/<Name>Page.tsx index.ts
|
|
55
|
+
component Pure UI atom → <Name>.tsx index.ts
|
|
56
|
+
module Vertical module → ui/<Name>.tsx model/index.ts api/index.ts index.ts
|
|
57
|
+
|
|
58
|
+
Nested paths:
|
|
59
|
+
The <name> argument supports "/" separators to nest the slice inside a subdirectory.
|
|
60
|
+
The basename is used for the component name in generated files.
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
$ component-forge g feature auth
|
|
64
|
+
Creates: src/features/auth/
|
|
65
|
+
|
|
66
|
+
$ component-forge g feature auth/LoginForm
|
|
67
|
+
Creates: src/features/auth/LoginForm/ (component name: LoginForm)
|
|
68
|
+
|
|
69
|
+
$ component-forge g entity user/profile/Address
|
|
70
|
+
Creates: src/entities/user/profile/Address/ (component name: Address)
|
|
71
|
+
|
|
72
|
+
$ component-forge g component Button --dry-run
|
|
73
|
+
Preview: src/shared/ui/Button/
|
|
74
|
+
`)
|
|
46
75
|
.action((type, name, options) => {
|
|
47
76
|
(0, generate_1.generateCommand)(type, name, { dryRun: options.dryRun });
|
|
48
77
|
});
|
|
@@ -61,6 +90,13 @@ program
|
|
|
61
90
|
program
|
|
62
91
|
.command('check')
|
|
63
92
|
.description('Check that imports do not violate architecture layer boundaries')
|
|
93
|
+
.addHelpText('after', `
|
|
94
|
+
Each violation is printed with a targeted "→ Fix:" hint.
|
|
95
|
+
Exits with code 1 when violations are found (useful in CI pipelines).
|
|
96
|
+
|
|
97
|
+
Example:
|
|
98
|
+
$ component-forge check
|
|
99
|
+
`)
|
|
64
100
|
.action(() => {
|
|
65
101
|
(0, check_1.checkCommand)();
|
|
66
102
|
});
|
|
@@ -71,6 +107,14 @@ program
|
|
|
71
107
|
.command('migrate')
|
|
72
108
|
.description('Analyse current project structure and propose a migration plan')
|
|
73
109
|
.requiredOption('--to <architecture>', 'Target architecture: fsd | modular')
|
|
110
|
+
.addHelpText('after', `
|
|
111
|
+
Scans your source directory and prints a step-by-step migration plan.
|
|
112
|
+
No files are moved — this is a dry-run analysis only.
|
|
113
|
+
|
|
114
|
+
Examples:
|
|
115
|
+
$ component-forge migrate --to fsd
|
|
116
|
+
$ component-forge migrate --to modular
|
|
117
|
+
`)
|
|
74
118
|
.action((options) => {
|
|
75
119
|
if (!['fsd', 'modular'].includes(options.to)) {
|
|
76
120
|
console.error(`error: --to must be "fsd" or "modular", got "${options.to}"`);
|
|
@@ -85,6 +129,14 @@ program
|
|
|
85
129
|
.command('explain')
|
|
86
130
|
.description('Print architecture documentation in the terminal')
|
|
87
131
|
.argument('<topic>', `Topic to explain: ${explain_1.AVAILABLE_TOPICS.join(' | ')}`)
|
|
132
|
+
.addHelpText('after', `
|
|
133
|
+
Available topics: fsd, modular, layers, slices, segments
|
|
134
|
+
|
|
135
|
+
Examples:
|
|
136
|
+
$ component-forge explain fsd
|
|
137
|
+
$ component-forge explain layers
|
|
138
|
+
$ component-forge explain slices
|
|
139
|
+
`)
|
|
88
140
|
.action((topic) => {
|
|
89
141
|
(0, explain_1.explainCommand)(topic);
|
|
90
142
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAmC;AAEnC,4CAA+C;AAC/C,gDAAqE;AACrE,kDAAqE;AACrE,0CAA6C;AAC7C,gDAAmD;AACnD,kDAAqD;AAGrD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,iBAAiB,CAAC;KACvB,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,8EAA8E;AAC9E,OAAO;AACP,8EAA8E;AAE9E,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wEAAwE,CAAC;KACrF,QAAQ,CAAC,gBAAgB,EAAE,kEAAkE,CAAC;KAC9F,MAAM,CAAC,CAAC,YAAqB,EAAE,EAAE;IAChC,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7E,OAAO,CAAC,KAAK,CAAC,wDAAwD,YAAY,GAAG,CAAC,CAAA;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,IAAA,kBAAW,EAAC,YAAwC,CAAC,CAAA;AACvD,CAAC,CAAC,CAAA;AAEJ,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,MAAM,WAAW,GAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;AAE/F,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,+BAA+B,CAAC;KAC5C,QAAQ,CAAC,QAAQ,EAAE,eAAe,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;IACvE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAkB,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,wBAAwB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACnE,CAAC;IACD,OAAO,KAAkB,CAAA;AAC3B,CAAC,CAAC;KACD,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xanahlight/component-forge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Architecture-first CLI for scalable React projects",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"node": ">=20.0.0"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "tsc",
|
|
16
|
+
"build": "tsc -p tsconfig.build.json",
|
|
17
17
|
"dev": "ts-node src/index.ts",
|
|
18
18
|
"prepublishOnly": "npm run build",
|
|
19
19
|
"format": "prettier --write .",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,151 +0,0 @@
|
|
|
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
|
-
const node_os_1 = __importDefault(require("node:os"));
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
-
const vitest_1 = require("vitest");
|
|
10
|
-
const index_1 = require("./index");
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// Helpers
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
let tmpDir;
|
|
15
|
-
function write(relPath, content) {
|
|
16
|
-
const full = node_path_1.default.join(tmpDir, relPath);
|
|
17
|
-
fs_extra_1.default.ensureDirSync(node_path_1.default.dirname(full));
|
|
18
|
-
fs_extra_1.default.writeFileSync(full, content);
|
|
19
|
-
}
|
|
20
|
-
(0, vitest_1.beforeEach)(() => {
|
|
21
|
-
tmpDir = fs_extra_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), 'cf-check-'));
|
|
22
|
-
});
|
|
23
|
-
(0, vitest_1.afterEach)(() => {
|
|
24
|
-
fs_extra_1.default.removeSync(tmpDir);
|
|
25
|
-
});
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
// parseImports
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
(0, vitest_1.describe)('parseImports', () => {
|
|
30
|
-
(0, vitest_1.it)('extracts named imports', () => {
|
|
31
|
-
const src = `import { foo } from './foo'\nimport type { Bar } from '../bar'`;
|
|
32
|
-
(0, vitest_1.expect)((0, index_1.parseImports)(src)).toEqual(['./foo', '../bar']);
|
|
33
|
-
});
|
|
34
|
-
(0, vitest_1.it)('extracts default imports', () => {
|
|
35
|
-
(0, vitest_1.expect)((0, index_1.parseImports)(`import React from 'react'`)).toEqual(['react']);
|
|
36
|
-
});
|
|
37
|
-
(0, vitest_1.it)('extracts re-exports', () => {
|
|
38
|
-
(0, vitest_1.expect)((0, index_1.parseImports)(`export { foo } from './foo'`)).toEqual(['./foo']);
|
|
39
|
-
});
|
|
40
|
-
(0, vitest_1.it)('ignores non-import lines', () => {
|
|
41
|
-
(0, vitest_1.expect)((0, index_1.parseImports)(`const x = 1\nconsole.log(x)`)).toEqual([]);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// resolveLayer
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
(0, vitest_1.describe)('resolveLayer', () => {
|
|
48
|
-
(0, vitest_1.it)('returns first path segment as layer', () => {
|
|
49
|
-
(0, vitest_1.expect)((0, index_1.resolveLayer)('features/auth/index.ts')).toBe('features');
|
|
50
|
-
(0, vitest_1.expect)((0, index_1.resolveLayer)('shared/ui/Button.tsx')).toBe('shared');
|
|
51
|
-
});
|
|
52
|
-
(0, vitest_1.it)('returns single-segment layer', () => {
|
|
53
|
-
(0, vitest_1.expect)((0, index_1.resolveLayer)('app')).toBe('app');
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
// ---------------------------------------------------------------------------
|
|
57
|
-
// collectSourceFiles
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
(0, vitest_1.describe)('collectSourceFiles', () => {
|
|
60
|
-
(0, vitest_1.it)('finds ts and tsx files', () => {
|
|
61
|
-
write('features/auth/index.ts', '');
|
|
62
|
-
write('shared/ui/Button.tsx', '');
|
|
63
|
-
write('shared/ui/Button.test.ts', ''); // should be excluded
|
|
64
|
-
const files = (0, index_1.collectSourceFiles)(tmpDir);
|
|
65
|
-
(0, vitest_1.expect)(files).toContain(node_path_1.default.join('features', 'auth', 'index.ts'));
|
|
66
|
-
(0, vitest_1.expect)(files).toContain(node_path_1.default.join('shared', 'ui', 'Button.tsx'));
|
|
67
|
-
(0, vitest_1.expect)(files.some((f) => f.endsWith('.test.ts'))).toBe(false);
|
|
68
|
-
});
|
|
69
|
-
(0, vitest_1.it)('returns empty array for non-existent dir', () => {
|
|
70
|
-
(0, vitest_1.expect)((0, index_1.collectSourceFiles)('/non/existent/path')).toEqual([]);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// FSD violations
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
(0, vitest_1.describe)('runCheck — FSD', () => {
|
|
77
|
-
(0, vitest_1.it)('passes when lower layer imports from even lower layer (entities → shared)', () => {
|
|
78
|
-
write('entities/user/index.ts', `import { Button } from '../../shared/ui/Button'`);
|
|
79
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
80
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(0);
|
|
81
|
-
(0, vitest_1.expect)(result.checkedFiles).toBe(1);
|
|
82
|
-
});
|
|
83
|
-
(0, vitest_1.it)('detects feature importing from feature (same level)', () => {
|
|
84
|
-
write('features/auth/index.ts', `import { foo } from '../../features/search/index'`);
|
|
85
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
86
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(1);
|
|
87
|
-
(0, vitest_1.expect)(result.violations[0].message).toMatch(/must not import from "features"/);
|
|
88
|
-
});
|
|
89
|
-
(0, vitest_1.it)('detects entity importing from feature (higher level)', () => {
|
|
90
|
-
write('entities/user/index.ts', `import { login } from '../../features/auth/index'`);
|
|
91
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
92
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(1);
|
|
93
|
-
(0, vitest_1.expect)(result.violations[0].message).toMatch(/must not import from "features"/);
|
|
94
|
-
});
|
|
95
|
-
(0, vitest_1.it)('detects shared importing from entities (higher level)', () => {
|
|
96
|
-
write('shared/ui/Avatar.ts', `import { User } from '../../entities/user/model'`);
|
|
97
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
98
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(1);
|
|
99
|
-
(0, vitest_1.expect)(result.violations[0].message).toMatch(/must not import from "entities"/);
|
|
100
|
-
});
|
|
101
|
-
(0, vitest_1.it)('passes when feature imports from entities (lower level)', () => {
|
|
102
|
-
write('features/auth/index.ts', `import { User } from '../../entities/user/index'`);
|
|
103
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
104
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(0);
|
|
105
|
-
});
|
|
106
|
-
(0, vitest_1.it)('passes when pages imports from widgets (lower level)', () => {
|
|
107
|
-
write('pages/home/index.ts', `import { Header } from '../../widgets/header/index'`);
|
|
108
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
109
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(0);
|
|
110
|
-
});
|
|
111
|
-
(0, vitest_1.it)('ignores external (non-relative) imports', () => {
|
|
112
|
-
write('features/auth/index.ts', `import React from 'react'`);
|
|
113
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
114
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(0);
|
|
115
|
-
});
|
|
116
|
-
(0, vitest_1.it)('reports multiple violations across multiple files', () => {
|
|
117
|
-
write('entities/user/index.ts', `import { login } from '../../features/auth/index'`);
|
|
118
|
-
write('shared/ui/Button.ts', `import { User } from '../../entities/user/model'`);
|
|
119
|
-
const result = (0, index_1.runCheck)(tmpDir, 'fsd');
|
|
120
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(2);
|
|
121
|
-
(0, vitest_1.expect)(result.checkedFiles).toBe(2);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
// ---------------------------------------------------------------------------
|
|
125
|
-
// Modular violations
|
|
126
|
-
// ---------------------------------------------------------------------------
|
|
127
|
-
(0, vitest_1.describe)('runCheck — modular', () => {
|
|
128
|
-
(0, vitest_1.it)('passes when module imports from another module', () => {
|
|
129
|
-
write('modules/auth/index.ts', `import { foo } from '../../modules/ui/index'`);
|
|
130
|
-
const result = (0, index_1.runCheck)(tmpDir, 'modular');
|
|
131
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(0);
|
|
132
|
-
});
|
|
133
|
-
(0, vitest_1.it)('detects shared importing from modules', () => {
|
|
134
|
-
write('shared/utils/helper.ts', `import { login } from '../../modules/auth/index'`);
|
|
135
|
-
const result = (0, index_1.runCheck)(tmpDir, 'modular');
|
|
136
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(1);
|
|
137
|
-
(0, vitest_1.expect)(result.violations[0].message).toMatch(/must not import from "modules"/);
|
|
138
|
-
});
|
|
139
|
-
(0, vitest_1.it)('detects core importing from modules', () => {
|
|
140
|
-
write('core/router.ts', `import { AuthModule } from '../modules/auth/index'`);
|
|
141
|
-
const result = (0, index_1.runCheck)(tmpDir, 'modular');
|
|
142
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(1);
|
|
143
|
-
(0, vitest_1.expect)(result.violations[0].message).toMatch(/must not import from "modules"/);
|
|
144
|
-
});
|
|
145
|
-
(0, vitest_1.it)('passes when module imports from shared', () => {
|
|
146
|
-
write('modules/auth/index.ts', `import { Button } from '../../shared/ui/Button'`);
|
|
147
|
-
const result = (0, index_1.runCheck)(tmpDir, 'modular');
|
|
148
|
-
(0, vitest_1.expect)(result.violations).toHaveLength(0);
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
//# sourceMappingURL=check.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"check.test.js","sourceRoot":"","sources":["../../../src/commands/check/check.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const index_1 = require("./index");
|
|
5
|
-
(0, vitest_1.describe)('renderTopic', () => {
|
|
6
|
-
(0, vitest_1.it)('renders fsd topic with key sections', () => {
|
|
7
|
-
const output = (0, index_1.renderTopic)('fsd');
|
|
8
|
-
(0, vitest_1.expect)(output).toContain('Feature-Sliced Design');
|
|
9
|
-
(0, vitest_1.expect)(output).toContain('shared');
|
|
10
|
-
(0, vitest_1.expect)(output).toContain('entities');
|
|
11
|
-
(0, vitest_1.expect)(output).toContain('features');
|
|
12
|
-
(0, vitest_1.expect)(output).toContain('widgets');
|
|
13
|
-
(0, vitest_1.expect)(output).toContain('pages');
|
|
14
|
-
(0, vitest_1.expect)(output).toContain('app');
|
|
15
|
-
(0, vitest_1.expect)(output).toContain('Import rules');
|
|
16
|
-
});
|
|
17
|
-
(0, vitest_1.it)('renders modular topic with key sections', () => {
|
|
18
|
-
const output = (0, index_1.renderTopic)('modular');
|
|
19
|
-
(0, vitest_1.expect)(output).toContain('Modular Architecture');
|
|
20
|
-
(0, vitest_1.expect)(output).toContain('modules');
|
|
21
|
-
(0, vitest_1.expect)(output).toContain('core');
|
|
22
|
-
(0, vitest_1.expect)(output).toContain('shared');
|
|
23
|
-
(0, vitest_1.expect)(output).toContain('Import rules');
|
|
24
|
-
});
|
|
25
|
-
(0, vitest_1.it)('renders layers topic with FSD layer reference', () => {
|
|
26
|
-
const output = (0, index_1.renderTopic)('layers');
|
|
27
|
-
(0, vitest_1.expect)(output).toContain('FSD Layer Reference');
|
|
28
|
-
(0, vitest_1.expect)(output).toContain('shared');
|
|
29
|
-
(0, vitest_1.expect)(output).toContain('entities');
|
|
30
|
-
(0, vitest_1.expect)(output).toContain('features');
|
|
31
|
-
});
|
|
32
|
-
(0, vitest_1.it)('renders all topic combining all sections', () => {
|
|
33
|
-
const output = (0, index_1.renderTopic)('all');
|
|
34
|
-
(0, vitest_1.expect)(output).toContain('Feature-Sliced Design');
|
|
35
|
-
(0, vitest_1.expect)(output).toContain('Modular Architecture');
|
|
36
|
-
(0, vitest_1.expect)(output).toContain('FSD Layer Reference');
|
|
37
|
-
});
|
|
38
|
-
(0, vitest_1.it)('returns error message for unknown topic', () => {
|
|
39
|
-
const output = (0, index_1.renderTopic)('unknown-topic');
|
|
40
|
-
(0, vitest_1.expect)(output).toContain('Unknown topic');
|
|
41
|
-
(0, vitest_1.expect)(output).toContain('unknown-topic');
|
|
42
|
-
(0, vitest_1.expect)(output).toContain('Available topics');
|
|
43
|
-
});
|
|
44
|
-
(0, vitest_1.it)('is case-insensitive', () => {
|
|
45
|
-
const lower = (0, index_1.renderTopic)('fsd');
|
|
46
|
-
const upper = (0, index_1.renderTopic)('FSD');
|
|
47
|
-
// Same length means same content (ANSI codes are identical)
|
|
48
|
-
(0, vitest_1.expect)(lower.length).toBe(upper.length);
|
|
49
|
-
});
|
|
50
|
-
(0, vitest_1.it)('AVAILABLE_TOPICS contains expected topics', () => {
|
|
51
|
-
(0, vitest_1.expect)(index_1.AVAILABLE_TOPICS).toContain('fsd');
|
|
52
|
-
(0, vitest_1.expect)(index_1.AVAILABLE_TOPICS).toContain('modular');
|
|
53
|
-
(0, vitest_1.expect)(index_1.AVAILABLE_TOPICS).toContain('layers');
|
|
54
|
-
(0, vitest_1.expect)(index_1.AVAILABLE_TOPICS).toContain('all');
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
//# sourceMappingURL=explain.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"explain.test.js","sourceRoot":"","sources":["../../../src/commands/explain/explain.test.ts"],"names":[],"mappings":"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"}
|