@cloud-ru/ft-deps-validator 1.1.1 → 1.1.2-preview-9ce1a08.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.
Files changed (115) hide show
  1. package/README.md +34 -15
  2. package/dist/cjs/Checker/MonorepoChecker.d.ts +10 -0
  3. package/dist/cjs/Checker/MonorepoChecker.js +57 -0
  4. package/dist/cjs/Checker/RepoChecker.d.ts +8 -0
  5. package/dist/cjs/Checker/RepoChecker.js +36 -0
  6. package/dist/cjs/Checker/__tests__/MonorepoChecker.spec.js +305 -0
  7. package/dist/cjs/Checker/__tests__/RepoChecker.spec.js +116 -0
  8. package/dist/cjs/Checker/index.d.ts +2 -0
  9. package/dist/cjs/Checker/index.js +7 -0
  10. package/dist/cjs/Config/MonorepoConfig.d.ts +12 -0
  11. package/dist/cjs/Config/MonorepoConfig.js +42 -0
  12. package/dist/cjs/Config/RepoConfig.d.ts +10 -0
  13. package/dist/cjs/Config/RepoConfig.js +27 -0
  14. package/dist/cjs/Config/__tests__/MonorepoConfig.spec.js +296 -0
  15. package/dist/cjs/Config/__tests__/RepoConfig.spec.d.ts +1 -0
  16. package/dist/cjs/Config/__tests__/RepoConfig.spec.js +99 -0
  17. package/dist/cjs/Config/index.d.ts +2 -0
  18. package/dist/cjs/Config/index.js +7 -0
  19. package/dist/cjs/Report/__tests__/Report.spec.d.ts +1 -0
  20. package/dist/cjs/Report/__tests__/Report.spec.js +176 -0
  21. package/dist/cjs/Report/index.d.ts +11 -0
  22. package/dist/cjs/Report/index.js +55 -0
  23. package/dist/cjs/index.d.ts +0 -1
  24. package/dist/cjs/index.js +13 -57
  25. package/dist/{esm/types/config.d.ts → cjs/types.d.ts} +14 -3
  26. package/dist/cjs/utils/__tests__/getCliArguments.spec.d.ts +1 -0
  27. package/dist/cjs/utils/__tests__/getCliArguments.spec.js +70 -0
  28. package/dist/cjs/utils/getCliArguments.d.ts +6 -6
  29. package/dist/cjs/utils/getCliArguments.js +1 -27
  30. package/dist/cjs/utils/getConfigFile.d.ts +4 -3
  31. package/dist/cjs/utils/getConfigFile.js +3 -9
  32. package/dist/cjs/utils/getEnvironment.d.ts +3 -0
  33. package/dist/cjs/utils/getEnvironment.js +50 -0
  34. package/dist/cjs/utils/readPackageJsonFile.d.ts +9 -0
  35. package/dist/cjs/utils/readPackageJsonFile.js +28 -0
  36. package/dist/esm/Checker/MonorepoChecker.d.ts +10 -0
  37. package/dist/esm/Checker/MonorepoChecker.js +53 -0
  38. package/dist/esm/Checker/RepoChecker.d.ts +8 -0
  39. package/dist/esm/Checker/RepoChecker.js +29 -0
  40. package/dist/esm/Checker/__tests__/MonorepoChecker.spec.d.ts +1 -0
  41. package/dist/esm/Checker/__tests__/MonorepoChecker.spec.js +300 -0
  42. package/dist/esm/Checker/__tests__/RepoChecker.spec.d.ts +1 -0
  43. package/dist/esm/Checker/__tests__/RepoChecker.spec.js +111 -0
  44. package/dist/esm/Checker/index.d.ts +2 -0
  45. package/dist/esm/Checker/index.js +2 -0
  46. package/dist/esm/Config/MonorepoConfig.d.ts +12 -0
  47. package/dist/esm/Config/MonorepoConfig.js +35 -0
  48. package/dist/esm/Config/RepoConfig.d.ts +10 -0
  49. package/dist/esm/Config/RepoConfig.js +20 -0
  50. package/dist/esm/Config/__tests__/MonorepoConfig.spec.d.ts +1 -0
  51. package/dist/esm/Config/__tests__/MonorepoConfig.spec.js +291 -0
  52. package/dist/esm/Config/__tests__/RepoConfig.spec.d.ts +1 -0
  53. package/dist/esm/Config/__tests__/RepoConfig.spec.js +94 -0
  54. package/dist/esm/Config/index.d.ts +2 -0
  55. package/dist/esm/Config/index.js +2 -0
  56. package/dist/esm/Report/__tests__/Report.spec.d.ts +1 -0
  57. package/dist/esm/Report/__tests__/Report.spec.js +174 -0
  58. package/dist/esm/Report/index.d.ts +11 -0
  59. package/dist/esm/Report/index.js +51 -0
  60. package/dist/esm/index.d.ts +0 -1
  61. package/dist/esm/index.js +14 -55
  62. package/dist/{cjs/types/config.d.ts → esm/types.d.ts} +14 -3
  63. package/dist/esm/types.js +1 -0
  64. package/dist/esm/utils/__tests__/getCliArguments.spec.d.ts +1 -0
  65. package/dist/esm/utils/__tests__/getCliArguments.spec.js +68 -0
  66. package/dist/esm/utils/getCliArguments.d.ts +6 -6
  67. package/dist/esm/utils/getCliArguments.js +1 -27
  68. package/dist/esm/utils/getConfigFile.d.ts +4 -3
  69. package/dist/esm/utils/getConfigFile.js +3 -9
  70. package/dist/esm/utils/getEnvironment.d.ts +3 -0
  71. package/dist/esm/utils/getEnvironment.js +42 -0
  72. package/dist/esm/utils/readPackageJsonFile.d.ts +9 -0
  73. package/dist/esm/utils/readPackageJsonFile.js +20 -0
  74. package/package.json +2 -2
  75. package/src/Checker/MonorepoChecker.ts +45 -0
  76. package/src/Checker/RepoChecker.ts +23 -0
  77. package/src/Checker/__tests__/MonorepoChecker.spec.ts +330 -0
  78. package/src/Checker/__tests__/RepoChecker.spec.ts +132 -0
  79. package/src/Checker/index.ts +2 -0
  80. package/src/Config/MonorepoConfig.ts +51 -0
  81. package/src/Config/RepoConfig.ts +30 -0
  82. package/src/Config/__tests__/MonorepoConfig.spec.ts +348 -0
  83. package/src/Config/__tests__/RepoConfig.spec.ts +131 -0
  84. package/src/Config/index.ts +2 -0
  85. package/src/Report/__tests__/Report.spec.ts +221 -0
  86. package/src/Report/index.ts +75 -0
  87. package/src/index.ts +14 -67
  88. package/src/{types/config.ts → types.ts} +15 -3
  89. package/src/utils/__tests__/getCliArguments.spec.ts +89 -0
  90. package/src/utils/getCliArguments.ts +1 -35
  91. package/src/utils/getConfigFile.ts +7 -11
  92. package/src/utils/getEnvironment.ts +53 -0
  93. package/src/utils/readPackageJsonFile.ts +20 -0
  94. package/dist/cjs/types/cliArguments.d.ts +0 -4
  95. package/dist/cjs/types/config.js +0 -2
  96. package/dist/cjs/types/state.d.ts +0 -6
  97. package/dist/cjs/types/state.js +0 -2
  98. package/dist/cjs/utils/getMonorepoPrefix.d.ts +0 -6
  99. package/dist/cjs/utils/getMonorepoPrefix.js +0 -33
  100. package/dist/cjs/utils/initializeState.d.ts +0 -8
  101. package/dist/cjs/utils/initializeState.js +0 -40
  102. package/dist/esm/types/cliArguments.d.ts +0 -4
  103. package/dist/esm/types/state.d.ts +0 -6
  104. package/dist/esm/utils/getMonorepoPrefix.d.ts +0 -6
  105. package/dist/esm/utils/getMonorepoPrefix.js +0 -27
  106. package/dist/esm/utils/initializeState.d.ts +0 -8
  107. package/dist/esm/utils/initializeState.js +0 -34
  108. package/src/types/cliArguments.ts +0 -5
  109. package/src/types/state.ts +0 -6
  110. package/src/utils/getMonorepoPrefix.ts +0 -32
  111. package/src/utils/initializeState.ts +0 -51
  112. /package/dist/{esm/types/cliArguments.js → cjs/Checker/__tests__/MonorepoChecker.spec.d.ts} +0 -0
  113. /package/dist/{esm/types/config.js → cjs/Checker/__tests__/RepoChecker.spec.d.ts} +0 -0
  114. /package/dist/{esm/types/state.js → cjs/Config/__tests__/MonorepoConfig.spec.d.ts} +0 -0
  115. /package/dist/cjs/{types/cliArguments.js → types.js} +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @cloud-ru/ft-deps-validator
2
2
 
3
- Validator for unused, missing or wrong version dependencies in monorepo's packages.
3
+ Validator for unused, missing or wrong version dependencies in monorepo's packages or regular repositories.
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,22 +12,24 @@ npm i @cloud-ru/ft-deps-validator
12
12
 
13
13
  ### Basic usage (via npx)
14
14
 
15
- Run from the root of your monorepo:
15
+ Run from the root of your repository:
16
16
 
17
17
  ```bash
18
18
  npx @cloud-ru/ft-deps-validator
19
19
  ```
20
20
 
21
- This will check all packages in the `packages/*` directory relative to the current working directory.
21
+ The package automatically detects if it's a monorepo or a regular repository:
22
+ - **Monorepo**: If `packages` folder exists in the current directory, it will check all packages in `packages/*`
23
+ - **Regular repository**: If `packages` folder doesn't exist, it will check the current directory as a single package
22
24
 
23
25
  ### Specify working directory
24
26
 
25
27
  If you need to run from a different location:
26
28
 
27
29
  ```bash
28
- npx @cloud-ru/ft-deps-validator --cwd /path/to/your/monorepo
30
+ npx @cloud-ru/ft-deps-validator --cwd /path/to/your/repo
29
31
  # or using alias
30
- npx @cloud-ru/ft-deps-validator -d /path/to/your/monorepo
32
+ npx @cloud-ru/ft-deps-validator -d /path/to/your/repo
31
33
  ```
32
34
 
33
35
  ### Custom packages folder pattern
@@ -40,12 +42,30 @@ npx @cloud-ru/ft-deps-validator --rootPackagesFolderPattern "apps/*"
40
42
  npx @cloud-ru/ft-deps-validator -p "apps/*"
41
43
  ```
42
44
 
43
- ### Combined options
44
-
45
- ```bash
46
- npx @cloud-ru/ft-deps-validator --cwd /path/to/monorepo --rootPackagesFolderPattern "packages/*"
45
+ ### Configuration file
46
+
47
+ You can create a `deps-validator.config.json` file in the root of your repository to configure the validator:
48
+
49
+ ```json
50
+ {
51
+ "rootPackagesFolderPattern": "packages/*",
52
+ "ignoredPackagesFolderFiles": ["packages/tsconfig.cjs.json"],
53
+ "ignorePatterns": ["dist", "__tests__"],
54
+ "ignoreMatches": ["react", "react-dom"],
55
+ "packages": {
56
+ "package-name": {
57
+ "ignorePatterns": ["build"],
58
+ "ignoreMatches": ["@some/package"]
59
+ }
60
+ }
61
+ }
47
62
  ```
48
63
 
64
+ Configuration priority (highest to lowest):
65
+ 1. CLI arguments
66
+ 2. Configuration file
67
+ 3. Default values
68
+
49
69
  ### Ignore specific patterns
50
70
 
51
71
  ```bash
@@ -61,11 +81,10 @@ npx @cloud-ru/ft-deps-validator --ignoreMatches "react" "react-dom"
61
81
  ## Options
62
82
 
63
83
  - `--cwd, -d` - Working directory (default: current working directory)
64
- - `--rootPackagesFolderPattern, -p` - Folder containing packages (glob pattern, e.g., "packages/*" or "apps/*")
65
- - `--prefix` - Specify monorepo prefix (if skipped will try to find automatically)
66
- - `--ignoredPackagesFolderFiles` - Specify one or more paths that should be ignored in packages folder
84
+ - `--rootPackagesFolderPattern, -p` - Folder containing packages (glob pattern, e.g., "packages/*" or "apps/*"). If not specified, automatically detects monorepo by checking for `packages` folder
85
+ - `--ignoredPackagesFolderFiles` - Specify one or more paths that should be ignored in packages folder (default: `['packages/tsconfig.cjs.json', 'packages/tsconfig.esm.json']`)
67
86
  - `--ignorePatterns` - Specify one or more directories names that should be ignored (default: `['stories', 'dist', '__tests__', '__e2e__']`)
68
- - `--ignoreMatches` - Specify one or more packages that should be ignored
87
+ - `--ignoreMatches` - Specify one or more packages that should be ignored (default: includes `react`, `react-dom`, `react-docgen-typescript`, and several figma-tokens packages)
69
88
  - `--help, -h` - Show help
70
89
  - `--version, -v` - Show version
71
90
 
@@ -73,5 +92,5 @@ npx @cloud-ru/ft-deps-validator --ignoreMatches "react" "react-dom"
73
92
 
74
93
  1. **Unused dependencies** - Dependencies that are declared but not used in the code
75
94
  2. **Missing dependencies** - Dependencies that are used but not declared in package.json
76
- 3. **Wrong versions** - Internal packages with incorrect version numbers
77
- 4. **Internal packages in devDependencies** - Internal packages that should be in dependencies, not devDependencies
95
+ 3. **Wrong versions** (monorepo only) - Internal packages with incorrect version numbers
96
+ 4. **Internal packages in devDependencies** (monorepo only) - Internal packages that should be in dependencies, not devDependencies
@@ -0,0 +1,10 @@
1
+ import { MonorepoConfig } from '../Config';
2
+ import { RepoChecker } from './RepoChecker';
3
+ export declare class MonorepoChecker extends RepoChecker {
4
+ private actualVersions;
5
+ constructor(config: MonorepoConfig);
6
+ protected checkFolder(path: string): Promise<Partial<Pick<import("depcheck").Results, "dependencies" | "missing"> & {
7
+ wrongVersions: string[];
8
+ internalAsDev: string[];
9
+ }>>;
10
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MonorepoChecker = void 0;
13
+ const readPackageJsonFile_1 = require("../utils/readPackageJsonFile");
14
+ const RepoChecker_1 = require("./RepoChecker");
15
+ class MonorepoChecker extends RepoChecker_1.RepoChecker {
16
+ constructor(config) {
17
+ super(config);
18
+ this.actualVersions = {};
19
+ this.config.getFolders().reduce((acc, folder) => {
20
+ const pkg = (0, readPackageJsonFile_1.readPackageJsonFileSync)(folder);
21
+ acc[pkg.name] = pkg.version;
22
+ return acc;
23
+ }, this.actualVersions);
24
+ }
25
+ checkFolder(path) {
26
+ const _super = Object.create(null, {
27
+ checkFolder: { get: () => super.checkFolder }
28
+ });
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ const [result, pkg] = yield Promise.all([_super.checkFolder.call(this, path), (0, readPackageJsonFile_1.readPackageJsonFile)(path)]);
31
+ for (const [dep, version] of Object.entries(pkg.dependencies)) {
32
+ const actualVersion = this.actualVersions[dep];
33
+ if (actualVersion !== version) {
34
+ const message = `"${dep}" has wrong version "${version}", but need "${actualVersion}".`;
35
+ if (result.wrongVersions) {
36
+ result.wrongVersions.push();
37
+ }
38
+ else {
39
+ result.wrongVersions = [message];
40
+ }
41
+ }
42
+ }
43
+ for (const devDep of Object.keys(pkg.devDependencies)) {
44
+ if (this.actualVersions[devDep]) {
45
+ if (result.internalAsDev) {
46
+ result.internalAsDev.push(devDep);
47
+ }
48
+ else {
49
+ result.internalAsDev = [devDep];
50
+ }
51
+ }
52
+ }
53
+ return result;
54
+ });
55
+ }
56
+ }
57
+ exports.MonorepoChecker = MonorepoChecker;
@@ -0,0 +1,8 @@
1
+ import { RepoConfig } from '../Config';
2
+ import { CheckState, Report } from '../Report';
3
+ export declare class RepoChecker {
4
+ protected config: RepoConfig;
5
+ constructor(config: RepoConfig);
6
+ check(): Promise<Report>;
7
+ protected checkFolder(path: string): Promise<CheckState>;
8
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RepoChecker = void 0;
16
+ const depcheck_1 = __importDefault(require("depcheck"));
17
+ const Report_1 = require("../Report");
18
+ class RepoChecker {
19
+ constructor(config) {
20
+ this.config = config;
21
+ }
22
+ check() {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ const folders = this.config.getFolders();
25
+ const report = new Report_1.Report();
26
+ yield Promise.all(folders.map(folder => this.checkFolder(folder).then(result => report.add(folder, result))));
27
+ return report;
28
+ });
29
+ }
30
+ checkFolder(path) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ return (0, depcheck_1.default)(path, this.config.getFolderOptions(path));
33
+ });
34
+ }
35
+ }
36
+ exports.RepoChecker = RepoChecker;
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const depcheck_1 = __importDefault(require("depcheck"));
16
+ const vitest_1 = require("vitest");
17
+ const readPackageJsonFile_1 = require("../../utils/readPackageJsonFile");
18
+ const MonorepoChecker_1 = require("../MonorepoChecker");
19
+ vitest_1.vi.mock('depcheck', () => ({
20
+ default: vitest_1.vi.fn(),
21
+ }));
22
+ vitest_1.vi.mock('../../utils/readPackageJsonFile', () => ({
23
+ readPackageJsonFile: vitest_1.vi.fn(),
24
+ readPackageJsonFileSync: vitest_1.vi.fn(),
25
+ }));
26
+ (0, vitest_1.describe)('MonorepoChecker', () => {
27
+ let mockConfig;
28
+ const mockDepcheck = vitest_1.vi.mocked(depcheck_1.default);
29
+ const mockReadPackageJsonFile = vitest_1.vi.mocked(readPackageJsonFile_1.readPackageJsonFile);
30
+ const mockReadPackageJsonFileSync = vitest_1.vi.mocked(readPackageJsonFile_1.readPackageJsonFileSync);
31
+ (0, vitest_1.beforeEach)(() => {
32
+ vitest_1.vi.clearAllMocks();
33
+ mockConfig = {
34
+ getFolders: vitest_1.vi.fn(),
35
+ getFolderOptions: vitest_1.vi.fn(),
36
+ };
37
+ });
38
+ (0, vitest_1.describe)('check', () => {
39
+ (0, vitest_1.beforeEach)(() => {
40
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue([]);
41
+ });
42
+ (0, vitest_1.it)('should add wrongVersions when dependency version does not match', () => __awaiter(void 0, void 0, void 0, function* () {
43
+ const folders = ['/test/folder1', '/test/folder2'];
44
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
45
+ mockReadPackageJsonFileSync
46
+ .mockReturnValueOnce({
47
+ name: '@test/package1',
48
+ version: '1.0.0',
49
+ dependencies: {},
50
+ devDependencies: {},
51
+ })
52
+ .mockReturnValueOnce({
53
+ name: '@test/package2',
54
+ version: '2.0.0',
55
+ dependencies: {},
56
+ devDependencies: {},
57
+ });
58
+ const checkState = { dependencies: [] };
59
+ mockDepcheck.mockResolvedValue(checkState);
60
+ mockReadPackageJsonFile.mockResolvedValue({
61
+ name: 'test-package',
62
+ version: '1.0.0',
63
+ dependencies: { '@test/package1': '1.1.0' },
64
+ devDependencies: {},
65
+ });
66
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
67
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
68
+ const report = yield checker.check();
69
+ const exitCode = report.printResultAndGetExitCode();
70
+ (0, vitest_1.expect)(exitCode).toBe(1);
71
+ }));
72
+ (0, vitest_1.it)('should not add wrongVersions when dependency version matches', () => __awaiter(void 0, void 0, void 0, function* () {
73
+ const folders = ['/test/folder1'];
74
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
75
+ mockReadPackageJsonFileSync.mockReturnValue({
76
+ name: '@test/package1',
77
+ version: '1.0.0',
78
+ dependencies: {},
79
+ devDependencies: {},
80
+ });
81
+ const checkState = { dependencies: [] };
82
+ mockDepcheck.mockResolvedValue(checkState);
83
+ mockReadPackageJsonFile.mockResolvedValue({
84
+ name: 'test-package',
85
+ version: '1.0.0',
86
+ dependencies: { '@test/package1': '1.0.0' },
87
+ devDependencies: {},
88
+ });
89
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
90
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
91
+ const report = yield checker.check();
92
+ const exitCode = report.printResultAndGetExitCode();
93
+ (0, vitest_1.expect)(exitCode).toBe(0);
94
+ }));
95
+ (0, vitest_1.it)('should add to existing wrongVersions array', () => __awaiter(void 0, void 0, void 0, function* () {
96
+ const folders = ['/test/folder1'];
97
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
98
+ mockReadPackageJsonFileSync.mockReturnValue({
99
+ name: '@test/package1',
100
+ version: '1.0.0',
101
+ dependencies: {},
102
+ devDependencies: {},
103
+ });
104
+ const checkState = {
105
+ dependencies: [],
106
+ wrongVersions: ['existing error'],
107
+ };
108
+ mockDepcheck.mockResolvedValue(checkState);
109
+ mockReadPackageJsonFile.mockResolvedValue({
110
+ name: 'test-package',
111
+ version: '1.0.0',
112
+ dependencies: { '@test/package1': '1.1.0' },
113
+ devDependencies: {},
114
+ });
115
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
116
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
117
+ const report = yield checker.check();
118
+ const exitCode = report.printResultAndGetExitCode();
119
+ (0, vitest_1.expect)(exitCode).toBe(1);
120
+ }));
121
+ (0, vitest_1.it)('should add internalAsDev when internal package is in devDependencies', () => __awaiter(void 0, void 0, void 0, function* () {
122
+ const folders = ['/test/folder1'];
123
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
124
+ mockReadPackageJsonFileSync.mockReturnValue({
125
+ name: '@test/package1',
126
+ version: '1.0.0',
127
+ dependencies: {},
128
+ devDependencies: {},
129
+ });
130
+ const checkState = { dependencies: [] };
131
+ mockDepcheck.mockResolvedValue(checkState);
132
+ mockReadPackageJsonFile.mockResolvedValue({
133
+ name: 'test-package',
134
+ version: '1.0.0',
135
+ dependencies: {},
136
+ devDependencies: { '@test/package1': '1.0.0' },
137
+ });
138
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
139
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
140
+ const report = yield checker.check();
141
+ const exitCode = report.printResultAndGetExitCode();
142
+ (0, vitest_1.expect)(exitCode).toBe(1);
143
+ }));
144
+ (0, vitest_1.it)('should not add internalAsDev when package is not internal', () => __awaiter(void 0, void 0, void 0, function* () {
145
+ const folders = ['/test/folder1'];
146
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
147
+ mockReadPackageJsonFileSync.mockReturnValue({
148
+ name: '@test/package1',
149
+ version: '1.0.0',
150
+ dependencies: {},
151
+ devDependencies: {},
152
+ });
153
+ const checkState = { dependencies: [] };
154
+ mockDepcheck.mockResolvedValue(checkState);
155
+ mockReadPackageJsonFile.mockResolvedValue({
156
+ name: 'test-package',
157
+ version: '1.0.0',
158
+ dependencies: {},
159
+ devDependencies: { 'external-package': '1.0.0' },
160
+ });
161
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
162
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
163
+ const report = yield checker.check();
164
+ const exitCode = report.printResultAndGetExitCode();
165
+ (0, vitest_1.expect)(exitCode).toBe(0);
166
+ }));
167
+ (0, vitest_1.it)('should add to existing internalAsDev array', () => __awaiter(void 0, void 0, void 0, function* () {
168
+ const folders = ['/test/folder1'];
169
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
170
+ mockReadPackageJsonFileSync.mockReturnValue({
171
+ name: '@test/package1',
172
+ version: '1.0.0',
173
+ dependencies: {},
174
+ devDependencies: {},
175
+ });
176
+ const checkState = {
177
+ dependencies: [],
178
+ internalAsDev: ['existing-package'],
179
+ };
180
+ mockDepcheck.mockResolvedValue(checkState);
181
+ mockReadPackageJsonFile.mockResolvedValue({
182
+ name: 'test-package',
183
+ version: '1.0.0',
184
+ dependencies: {},
185
+ devDependencies: { '@test/package1': '1.0.0' },
186
+ });
187
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
188
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
189
+ const report = yield checker.check();
190
+ const exitCode = report.printResultAndGetExitCode();
191
+ (0, vitest_1.expect)(exitCode).toBe(1);
192
+ }));
193
+ (0, vitest_1.it)('should handle multiple wrong versions', () => __awaiter(void 0, void 0, void 0, function* () {
194
+ const folders = ['/test/folder1', '/test/folder2'];
195
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
196
+ mockReadPackageJsonFileSync
197
+ .mockReturnValueOnce({
198
+ name: '@test/package1',
199
+ version: '1.0.0',
200
+ dependencies: {},
201
+ devDependencies: {},
202
+ })
203
+ .mockReturnValueOnce({
204
+ name: '@test/package2',
205
+ version: '2.0.0',
206
+ dependencies: {},
207
+ devDependencies: {},
208
+ });
209
+ const checkState = { dependencies: [] };
210
+ mockDepcheck.mockResolvedValue(checkState);
211
+ mockReadPackageJsonFile.mockResolvedValue({
212
+ name: 'test-package',
213
+ version: '1.0.0',
214
+ dependencies: {
215
+ '@test/package1': '1.1.0',
216
+ '@test/package2': '2.1.0',
217
+ },
218
+ devDependencies: {},
219
+ });
220
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
221
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
222
+ const report = yield checker.check();
223
+ const exitCode = report.printResultAndGetExitCode();
224
+ (0, vitest_1.expect)(exitCode).toBe(1);
225
+ }));
226
+ (0, vitest_1.it)('should handle both wrongVersions and internalAsDev', () => __awaiter(void 0, void 0, void 0, function* () {
227
+ const folders = ['/test/folder1', '/test/folder2'];
228
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
229
+ mockReadPackageJsonFileSync
230
+ .mockReturnValueOnce({
231
+ name: '@test/package1',
232
+ version: '1.0.0',
233
+ dependencies: {},
234
+ devDependencies: {},
235
+ })
236
+ .mockReturnValueOnce({
237
+ name: '@test/package2',
238
+ version: '2.0.0',
239
+ dependencies: {},
240
+ devDependencies: {},
241
+ });
242
+ const checkState = { dependencies: [] };
243
+ mockDepcheck.mockResolvedValue(checkState);
244
+ mockReadPackageJsonFile.mockResolvedValue({
245
+ name: 'test-package',
246
+ version: '1.0.0',
247
+ dependencies: { '@test/package1': '1.1.0' },
248
+ devDependencies: { '@test/package2': '2.0.0' },
249
+ });
250
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
251
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
252
+ const report = yield checker.check();
253
+ const exitCode = report.printResultAndGetExitCode();
254
+ (0, vitest_1.expect)(exitCode).toBe(1);
255
+ }));
256
+ (0, vitest_1.it)('should add wrongVersions for external packages (when actualVersion is undefined)', () => __awaiter(void 0, void 0, void 0, function* () {
257
+ const folders = ['/test/folder1'];
258
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
259
+ mockReadPackageJsonFileSync.mockReturnValue({
260
+ name: '@test/package1',
261
+ version: '1.0.0',
262
+ dependencies: {},
263
+ devDependencies: {},
264
+ });
265
+ const checkState = { dependencies: [] };
266
+ mockDepcheck.mockResolvedValue(checkState);
267
+ mockReadPackageJsonFile.mockResolvedValue({
268
+ name: 'test-package',
269
+ version: '1.0.0',
270
+ dependencies: { 'external-package': '1.0.0' },
271
+ devDependencies: {},
272
+ });
273
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
274
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
275
+ const report = yield checker.check();
276
+ // Текущая реализация добавляет ошибку для внешних пакетов,
277
+ // так как actualVersion === undefined, и условие undefined !== "1.0.0" будет true
278
+ const exitCode = report.printResultAndGetExitCode();
279
+ (0, vitest_1.expect)(exitCode).toBe(1);
280
+ }));
281
+ (0, vitest_1.it)('should handle empty dependencies and devDependencies', () => __awaiter(void 0, void 0, void 0, function* () {
282
+ const folders = ['/test/folder1'];
283
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
284
+ mockReadPackageJsonFileSync.mockReturnValue({
285
+ name: '@test/package1',
286
+ version: '1.0.0',
287
+ dependencies: {},
288
+ devDependencies: {},
289
+ });
290
+ const checkState = { dependencies: [] };
291
+ mockDepcheck.mockResolvedValue(checkState);
292
+ mockReadPackageJsonFile.mockResolvedValue({
293
+ name: 'test-package',
294
+ version: '1.0.0',
295
+ dependencies: {},
296
+ devDependencies: {},
297
+ });
298
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
299
+ const checker = new MonorepoChecker_1.MonorepoChecker(mockConfig);
300
+ const report = yield checker.check();
301
+ const exitCode = report.printResultAndGetExitCode();
302
+ (0, vitest_1.expect)(exitCode).toBe(0);
303
+ }));
304
+ });
305
+ });
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const depcheck_1 = __importDefault(require("depcheck"));
16
+ const vitest_1 = require("vitest");
17
+ const RepoChecker_1 = require("../RepoChecker");
18
+ vitest_1.vi.mock('depcheck', () => ({
19
+ default: vitest_1.vi.fn(),
20
+ }));
21
+ (0, vitest_1.describe)('RepoChecker', () => {
22
+ let mockConfig;
23
+ const mockDepcheck = vitest_1.vi.mocked(depcheck_1.default);
24
+ (0, vitest_1.beforeEach)(() => {
25
+ vitest_1.vi.clearAllMocks();
26
+ mockConfig = {
27
+ getFolders: vitest_1.vi.fn(),
28
+ getFolderOptions: vitest_1.vi.fn(),
29
+ };
30
+ });
31
+ (0, vitest_1.describe)('constructor', () => {
32
+ (0, vitest_1.it)('should initialize with config', () => {
33
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
34
+ (0, vitest_1.expect)(checker).toBeInstanceOf(RepoChecker_1.RepoChecker);
35
+ });
36
+ });
37
+ (0, vitest_1.describe)('check', () => {
38
+ (0, vitest_1.it)('should call getFolders on config', () => __awaiter(void 0, void 0, void 0, function* () {
39
+ const folders = ['/test/folder1'];
40
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
41
+ const checkState = { dependencies: [] };
42
+ mockDepcheck.mockResolvedValue(checkState);
43
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
44
+ yield checker.check();
45
+ (0, vitest_1.expect)(mockConfig.getFolders).toHaveBeenCalledTimes(1);
46
+ }));
47
+ (0, vitest_1.it)('should call checkFolder for each folder', () => __awaiter(void 0, void 0, void 0, function* () {
48
+ const folders = ['/test/folder1', '/test/folder2'];
49
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
50
+ const checkState1 = { dependencies: ['dep1'] };
51
+ const checkState2 = { dependencies: ['dep2'] };
52
+ mockDepcheck.mockResolvedValueOnce(checkState1).mockResolvedValueOnce(checkState2);
53
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
54
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
55
+ yield checker.check();
56
+ (0, vitest_1.expect)(mockDepcheck).toHaveBeenCalledTimes(2);
57
+ }));
58
+ (0, vitest_1.it)('should call getFolderOptions for each folder with correct path', () => __awaiter(void 0, void 0, void 0, function* () {
59
+ const folders = ['/test/folder1', '/test/folder2'];
60
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
61
+ const options1 = { ignoreBinPackage: false };
62
+ const options2 = { ignoreBinPackage: false };
63
+ vitest_1.vi.mocked(mockConfig.getFolderOptions)
64
+ .mockReturnValueOnce(options1)
65
+ .mockReturnValueOnce(options2);
66
+ const checkState = { dependencies: [] };
67
+ mockDepcheck.mockResolvedValue(checkState);
68
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
69
+ yield checker.check();
70
+ (0, vitest_1.expect)(mockConfig.getFolderOptions).toHaveBeenCalledWith('/test/folder1');
71
+ (0, vitest_1.expect)(mockConfig.getFolderOptions).toHaveBeenCalledWith('/test/folder2');
72
+ }));
73
+ (0, vitest_1.it)('should call depcheck with correct path and options', () => __awaiter(void 0, void 0, void 0, function* () {
74
+ const folders = ['/test/folder1'];
75
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
76
+ const options = { ignoreBinPackage: false, skipMissing: false };
77
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue(options);
78
+ const checkState = { dependencies: [] };
79
+ mockDepcheck.mockResolvedValue(checkState);
80
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
81
+ yield checker.check();
82
+ (0, vitest_1.expect)(mockDepcheck).toHaveBeenCalledWith('/test/folder1', options);
83
+ }));
84
+ (0, vitest_1.it)('should add results to report for each folder', () => __awaiter(void 0, void 0, void 0, function* () {
85
+ const folders = ['/test/folder1', '/test/folder2'];
86
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
87
+ const checkState1 = { dependencies: ['dep1'] };
88
+ const checkState2 = { dependencies: ['dep2'] };
89
+ mockDepcheck.mockResolvedValueOnce(checkState1).mockResolvedValueOnce(checkState2);
90
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
91
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
92
+ const report = yield checker.check();
93
+ const exitCode = report.printResultAndGetExitCode();
94
+ (0, vitest_1.expect)(exitCode).toBe(1);
95
+ }));
96
+ (0, vitest_1.it)('should return Report instance', () => __awaiter(void 0, void 0, void 0, function* () {
97
+ const folders = ['/test/folder1'];
98
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
99
+ const checkState = { dependencies: [] };
100
+ mockDepcheck.mockResolvedValue(checkState);
101
+ vitest_1.vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
102
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
103
+ const report = yield checker.check();
104
+ (0, vitest_1.expect)(report).toBeDefined();
105
+ (0, vitest_1.expect)(report.printResultAndGetExitCode).toBeDefined();
106
+ }));
107
+ (0, vitest_1.it)('should handle empty folders array', () => __awaiter(void 0, void 0, void 0, function* () {
108
+ vitest_1.vi.mocked(mockConfig.getFolders).mockReturnValue([]);
109
+ const checker = new RepoChecker_1.RepoChecker(mockConfig);
110
+ const report = yield checker.check();
111
+ (0, vitest_1.expect)(mockDepcheck).not.toHaveBeenCalled();
112
+ const exitCode = report.printResultAndGetExitCode();
113
+ (0, vitest_1.expect)(exitCode).toBe(0);
114
+ }));
115
+ });
116
+ });
@@ -0,0 +1,2 @@
1
+ export { RepoChecker } from './RepoChecker';
2
+ export { MonorepoChecker } from './MonorepoChecker';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MonorepoChecker = exports.RepoChecker = void 0;
4
+ var RepoChecker_1 = require("./RepoChecker");
5
+ Object.defineProperty(exports, "RepoChecker", { enumerable: true, get: function () { return RepoChecker_1.RepoChecker; } });
6
+ var MonorepoChecker_1 = require("./MonorepoChecker");
7
+ Object.defineProperty(exports, "MonorepoChecker", { enumerable: true, get: function () { return MonorepoChecker_1.MonorepoChecker; } });
@@ -0,0 +1,12 @@
1
+ import { Options } from 'depcheck';
2
+ import { MonorepoEnvType } from '../types';
3
+ import { RepoConfig } from './RepoConfig';
4
+ export declare class MonorepoConfig extends RepoConfig {
5
+ private rootPackagesFolderPattern;
6
+ private ignoredPackagesFolderFiles;
7
+ private packages;
8
+ private folders?;
9
+ constructor(env: MonorepoEnvType);
10
+ getFolderOptions(folderPath: string): Options;
11
+ getFolders(): string[];
12
+ }