@cloud-ru/ft-deps-validator 1.1.1 → 1.1.2-preview-8996d18.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/README.md +34 -15
- package/dist/cjs/Checker/MonorepoChecker.d.ts +10 -0
- package/dist/cjs/Checker/MonorepoChecker.js +57 -0
- package/dist/cjs/Checker/RepoChecker.d.ts +8 -0
- package/dist/cjs/Checker/RepoChecker.js +36 -0
- package/dist/cjs/Checker/__tests__/MonorepoChecker.spec.js +305 -0
- package/dist/cjs/Checker/__tests__/RepoChecker.spec.js +116 -0
- package/dist/cjs/Checker/index.d.ts +2 -0
- package/dist/cjs/Checker/index.js +7 -0
- package/dist/cjs/Config/MonorepoConfig.d.ts +12 -0
- package/dist/cjs/Config/MonorepoConfig.js +42 -0
- package/dist/cjs/Config/RepoConfig.d.ts +10 -0
- package/dist/cjs/Config/RepoConfig.js +27 -0
- package/dist/cjs/Config/__tests__/MonorepoConfig.spec.js +291 -0
- package/dist/cjs/Config/__tests__/RepoConfig.spec.d.ts +1 -0
- package/dist/cjs/Config/__tests__/RepoConfig.spec.js +99 -0
- package/dist/cjs/Config/index.d.ts +2 -0
- package/dist/cjs/Config/index.js +7 -0
- package/dist/cjs/Report/__tests__/Report.spec.d.ts +1 -0
- package/dist/cjs/Report/__tests__/Report.spec.js +176 -0
- package/dist/cjs/Report/index.d.ts +11 -0
- package/dist/cjs/Report/index.js +55 -0
- package/dist/cjs/index.d.ts +0 -1
- package/dist/cjs/index.js +13 -57
- package/dist/{esm/types/config.d.ts → cjs/types.d.ts} +14 -3
- package/dist/cjs/utils/__tests__/getCliArguments.spec.d.ts +1 -0
- package/dist/cjs/utils/__tests__/getCliArguments.spec.js +70 -0
- package/dist/cjs/utils/getCliArguments.d.ts +6 -6
- package/dist/cjs/utils/getCliArguments.js +1 -27
- package/dist/cjs/utils/getConfigFile.d.ts +4 -3
- package/dist/cjs/utils/getConfigFile.js +3 -9
- package/dist/cjs/utils/getEnvironment.d.ts +3 -0
- package/dist/cjs/utils/getEnvironment.js +50 -0
- package/dist/cjs/utils/readPackageJsonFile.d.ts +9 -0
- package/dist/cjs/utils/readPackageJsonFile.js +28 -0
- package/dist/esm/Checker/MonorepoChecker.d.ts +10 -0
- package/dist/esm/Checker/MonorepoChecker.js +53 -0
- package/dist/esm/Checker/RepoChecker.d.ts +8 -0
- package/dist/esm/Checker/RepoChecker.js +29 -0
- package/dist/esm/Checker/__tests__/MonorepoChecker.spec.d.ts +1 -0
- package/dist/esm/Checker/__tests__/MonorepoChecker.spec.js +300 -0
- package/dist/esm/Checker/__tests__/RepoChecker.spec.d.ts +1 -0
- package/dist/esm/Checker/__tests__/RepoChecker.spec.js +111 -0
- package/dist/esm/Checker/index.d.ts +2 -0
- package/dist/esm/Checker/index.js +2 -0
- package/dist/esm/Config/MonorepoConfig.d.ts +12 -0
- package/dist/esm/Config/MonorepoConfig.js +35 -0
- package/dist/esm/Config/RepoConfig.d.ts +10 -0
- package/dist/esm/Config/RepoConfig.js +20 -0
- package/dist/esm/Config/__tests__/MonorepoConfig.spec.d.ts +1 -0
- package/dist/esm/Config/__tests__/MonorepoConfig.spec.js +289 -0
- package/dist/esm/Config/__tests__/RepoConfig.spec.d.ts +1 -0
- package/dist/esm/Config/__tests__/RepoConfig.spec.js +94 -0
- package/dist/esm/Config/index.d.ts +2 -0
- package/dist/esm/Config/index.js +2 -0
- package/dist/esm/Report/__tests__/Report.spec.d.ts +1 -0
- package/dist/esm/Report/__tests__/Report.spec.js +174 -0
- package/dist/esm/Report/index.d.ts +11 -0
- package/dist/esm/Report/index.js +51 -0
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +14 -55
- package/dist/{cjs/types/config.d.ts → esm/types.d.ts} +14 -3
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils/__tests__/getCliArguments.spec.d.ts +1 -0
- package/dist/esm/utils/__tests__/getCliArguments.spec.js +68 -0
- package/dist/esm/utils/getCliArguments.d.ts +6 -6
- package/dist/esm/utils/getCliArguments.js +1 -27
- package/dist/esm/utils/getConfigFile.d.ts +4 -3
- package/dist/esm/utils/getConfigFile.js +3 -9
- package/dist/esm/utils/getEnvironment.d.ts +3 -0
- package/dist/esm/utils/getEnvironment.js +42 -0
- package/dist/esm/utils/readPackageJsonFile.d.ts +9 -0
- package/dist/esm/utils/readPackageJsonFile.js +20 -0
- package/package.json +2 -2
- package/src/Checker/MonorepoChecker.ts +45 -0
- package/src/Checker/RepoChecker.ts +23 -0
- package/src/Checker/__tests__/MonorepoChecker.spec.ts +330 -0
- package/src/Checker/__tests__/RepoChecker.spec.ts +132 -0
- package/src/Checker/index.ts +2 -0
- package/src/Config/MonorepoConfig.ts +51 -0
- package/src/Config/RepoConfig.ts +30 -0
- package/src/Config/__tests__/MonorepoConfig.spec.ts +346 -0
- package/src/Config/__tests__/RepoConfig.spec.ts +131 -0
- package/src/Config/index.ts +2 -0
- package/src/Report/__tests__/Report.spec.ts +221 -0
- package/src/Report/index.ts +75 -0
- package/src/index.ts +14 -67
- package/src/{types/config.ts → types.ts} +15 -3
- package/src/utils/__tests__/getCliArguments.spec.ts +89 -0
- package/src/utils/getCliArguments.ts +1 -35
- package/src/utils/getConfigFile.ts +7 -11
- package/src/utils/getEnvironment.ts +53 -0
- package/src/utils/readPackageJsonFile.ts +20 -0
- package/dist/cjs/types/cliArguments.d.ts +0 -4
- package/dist/cjs/types/config.js +0 -2
- package/dist/cjs/types/state.d.ts +0 -6
- package/dist/cjs/types/state.js +0 -2
- package/dist/cjs/utils/getMonorepoPrefix.d.ts +0 -6
- package/dist/cjs/utils/getMonorepoPrefix.js +0 -33
- package/dist/cjs/utils/initializeState.d.ts +0 -8
- package/dist/cjs/utils/initializeState.js +0 -40
- package/dist/esm/types/cliArguments.d.ts +0 -4
- package/dist/esm/types/state.d.ts +0 -6
- package/dist/esm/utils/getMonorepoPrefix.d.ts +0 -6
- package/dist/esm/utils/getMonorepoPrefix.js +0 -27
- package/dist/esm/utils/initializeState.d.ts +0 -8
- package/dist/esm/utils/initializeState.js +0 -34
- package/src/types/cliArguments.ts +0 -5
- package/src/types/state.ts +0 -6
- package/src/utils/getMonorepoPrefix.ts +0 -32
- package/src/utils/initializeState.ts +0 -51
- /package/dist/{esm/types/cliArguments.js → cjs/Checker/__tests__/MonorepoChecker.spec.d.ts} +0 -0
- /package/dist/{esm/types/config.js → cjs/Checker/__tests__/RepoChecker.spec.d.ts} +0 -0
- /package/dist/{esm/types/state.js → cjs/Config/__tests__/MonorepoConfig.spec.d.ts} +0 -0
- /package/dist/cjs/{types/cliArguments.js → types.js} +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { readPackageJsonFile, readPackageJsonFileSync } from '../utils/readPackageJsonFile';
|
|
11
|
+
import { RepoChecker } from './RepoChecker';
|
|
12
|
+
export class MonorepoChecker extends RepoChecker {
|
|
13
|
+
constructor(config) {
|
|
14
|
+
super(config);
|
|
15
|
+
this.actualVersions = {};
|
|
16
|
+
this.config.getFolders().reduce((acc, folder) => {
|
|
17
|
+
const pkg = readPackageJsonFileSync(folder);
|
|
18
|
+
acc[pkg.name] = pkg.version;
|
|
19
|
+
return acc;
|
|
20
|
+
}, this.actualVersions);
|
|
21
|
+
}
|
|
22
|
+
checkFolder(path) {
|
|
23
|
+
const _super = Object.create(null, {
|
|
24
|
+
checkFolder: { get: () => super.checkFolder }
|
|
25
|
+
});
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
const [result, pkg] = yield Promise.all([_super.checkFolder.call(this, path), readPackageJsonFile(path)]);
|
|
28
|
+
for (const [dep, version] of Object.entries(pkg.dependencies)) {
|
|
29
|
+
const actualVersion = this.actualVersions[dep];
|
|
30
|
+
if (actualVersion !== version) {
|
|
31
|
+
const message = `"${dep}" has wrong version "${version}", but need "${actualVersion}".`;
|
|
32
|
+
if (result.wrongVersions) {
|
|
33
|
+
result.wrongVersions.push();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
result.wrongVersions = [message];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const devDep of Object.keys(pkg.devDependencies)) {
|
|
41
|
+
if (this.actualVersions[devDep]) {
|
|
42
|
+
if (result.internalAsDev) {
|
|
43
|
+
result.internalAsDev.push(devDep);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
result.internalAsDev = [devDep];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -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,29 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import depcheck from 'depcheck';
|
|
11
|
+
import { Report } from '../Report';
|
|
12
|
+
export class RepoChecker {
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
check() {
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
const folders = this.config.getFolders();
|
|
19
|
+
const report = new Report();
|
|
20
|
+
yield Promise.all(folders.map(folder => this.checkFolder(folder).then(result => report.add(folder, result))));
|
|
21
|
+
return report;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
checkFolder(path) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
return depcheck(path, this.config.getFolderOptions(path));
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import depcheck from 'depcheck';
|
|
11
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
12
|
+
import { readPackageJsonFile, readPackageJsonFileSync } from '../../utils/readPackageJsonFile';
|
|
13
|
+
import { MonorepoChecker } from '../MonorepoChecker';
|
|
14
|
+
vi.mock('depcheck', () => ({
|
|
15
|
+
default: vi.fn(),
|
|
16
|
+
}));
|
|
17
|
+
vi.mock('../../utils/readPackageJsonFile', () => ({
|
|
18
|
+
readPackageJsonFile: vi.fn(),
|
|
19
|
+
readPackageJsonFileSync: vi.fn(),
|
|
20
|
+
}));
|
|
21
|
+
describe('MonorepoChecker', () => {
|
|
22
|
+
let mockConfig;
|
|
23
|
+
const mockDepcheck = vi.mocked(depcheck);
|
|
24
|
+
const mockReadPackageJsonFile = vi.mocked(readPackageJsonFile);
|
|
25
|
+
const mockReadPackageJsonFileSync = vi.mocked(readPackageJsonFileSync);
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
vi.clearAllMocks();
|
|
28
|
+
mockConfig = {
|
|
29
|
+
getFolders: vi.fn(),
|
|
30
|
+
getFolderOptions: vi.fn(),
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
describe('check', () => {
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue([]);
|
|
36
|
+
});
|
|
37
|
+
it('should add wrongVersions when dependency version does not match', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
const folders = ['/test/folder1', '/test/folder2'];
|
|
39
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
40
|
+
mockReadPackageJsonFileSync
|
|
41
|
+
.mockReturnValueOnce({
|
|
42
|
+
name: '@test/package1',
|
|
43
|
+
version: '1.0.0',
|
|
44
|
+
dependencies: {},
|
|
45
|
+
devDependencies: {},
|
|
46
|
+
})
|
|
47
|
+
.mockReturnValueOnce({
|
|
48
|
+
name: '@test/package2',
|
|
49
|
+
version: '2.0.0',
|
|
50
|
+
dependencies: {},
|
|
51
|
+
devDependencies: {},
|
|
52
|
+
});
|
|
53
|
+
const checkState = { dependencies: [] };
|
|
54
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
55
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
56
|
+
name: 'test-package',
|
|
57
|
+
version: '1.0.0',
|
|
58
|
+
dependencies: { '@test/package1': '1.1.0' },
|
|
59
|
+
devDependencies: {},
|
|
60
|
+
});
|
|
61
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
62
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
63
|
+
const report = yield checker.check();
|
|
64
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
65
|
+
expect(exitCode).toBe(1);
|
|
66
|
+
}));
|
|
67
|
+
it('should not add wrongVersions when dependency version matches', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
|
+
const folders = ['/test/folder1'];
|
|
69
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
70
|
+
mockReadPackageJsonFileSync.mockReturnValue({
|
|
71
|
+
name: '@test/package1',
|
|
72
|
+
version: '1.0.0',
|
|
73
|
+
dependencies: {},
|
|
74
|
+
devDependencies: {},
|
|
75
|
+
});
|
|
76
|
+
const checkState = { dependencies: [] };
|
|
77
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
78
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
79
|
+
name: 'test-package',
|
|
80
|
+
version: '1.0.0',
|
|
81
|
+
dependencies: { '@test/package1': '1.0.0' },
|
|
82
|
+
devDependencies: {},
|
|
83
|
+
});
|
|
84
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
85
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
86
|
+
const report = yield checker.check();
|
|
87
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
88
|
+
expect(exitCode).toBe(0);
|
|
89
|
+
}));
|
|
90
|
+
it('should add to existing wrongVersions array', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
91
|
+
const folders = ['/test/folder1'];
|
|
92
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
93
|
+
mockReadPackageJsonFileSync.mockReturnValue({
|
|
94
|
+
name: '@test/package1',
|
|
95
|
+
version: '1.0.0',
|
|
96
|
+
dependencies: {},
|
|
97
|
+
devDependencies: {},
|
|
98
|
+
});
|
|
99
|
+
const checkState = {
|
|
100
|
+
dependencies: [],
|
|
101
|
+
wrongVersions: ['existing error'],
|
|
102
|
+
};
|
|
103
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
104
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
105
|
+
name: 'test-package',
|
|
106
|
+
version: '1.0.0',
|
|
107
|
+
dependencies: { '@test/package1': '1.1.0' },
|
|
108
|
+
devDependencies: {},
|
|
109
|
+
});
|
|
110
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
111
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
112
|
+
const report = yield checker.check();
|
|
113
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
114
|
+
expect(exitCode).toBe(1);
|
|
115
|
+
}));
|
|
116
|
+
it('should add internalAsDev when internal package is in devDependencies', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
117
|
+
const folders = ['/test/folder1'];
|
|
118
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
119
|
+
mockReadPackageJsonFileSync.mockReturnValue({
|
|
120
|
+
name: '@test/package1',
|
|
121
|
+
version: '1.0.0',
|
|
122
|
+
dependencies: {},
|
|
123
|
+
devDependencies: {},
|
|
124
|
+
});
|
|
125
|
+
const checkState = { dependencies: [] };
|
|
126
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
127
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
128
|
+
name: 'test-package',
|
|
129
|
+
version: '1.0.0',
|
|
130
|
+
dependencies: {},
|
|
131
|
+
devDependencies: { '@test/package1': '1.0.0' },
|
|
132
|
+
});
|
|
133
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
134
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
135
|
+
const report = yield checker.check();
|
|
136
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
137
|
+
expect(exitCode).toBe(1);
|
|
138
|
+
}));
|
|
139
|
+
it('should not add internalAsDev when package is not internal', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
140
|
+
const folders = ['/test/folder1'];
|
|
141
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
142
|
+
mockReadPackageJsonFileSync.mockReturnValue({
|
|
143
|
+
name: '@test/package1',
|
|
144
|
+
version: '1.0.0',
|
|
145
|
+
dependencies: {},
|
|
146
|
+
devDependencies: {},
|
|
147
|
+
});
|
|
148
|
+
const checkState = { dependencies: [] };
|
|
149
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
150
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
151
|
+
name: 'test-package',
|
|
152
|
+
version: '1.0.0',
|
|
153
|
+
dependencies: {},
|
|
154
|
+
devDependencies: { 'external-package': '1.0.0' },
|
|
155
|
+
});
|
|
156
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
157
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
158
|
+
const report = yield checker.check();
|
|
159
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
160
|
+
expect(exitCode).toBe(0);
|
|
161
|
+
}));
|
|
162
|
+
it('should add to existing internalAsDev array', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
163
|
+
const folders = ['/test/folder1'];
|
|
164
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
165
|
+
mockReadPackageJsonFileSync.mockReturnValue({
|
|
166
|
+
name: '@test/package1',
|
|
167
|
+
version: '1.0.0',
|
|
168
|
+
dependencies: {},
|
|
169
|
+
devDependencies: {},
|
|
170
|
+
});
|
|
171
|
+
const checkState = {
|
|
172
|
+
dependencies: [],
|
|
173
|
+
internalAsDev: ['existing-package'],
|
|
174
|
+
};
|
|
175
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
176
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
177
|
+
name: 'test-package',
|
|
178
|
+
version: '1.0.0',
|
|
179
|
+
dependencies: {},
|
|
180
|
+
devDependencies: { '@test/package1': '1.0.0' },
|
|
181
|
+
});
|
|
182
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
183
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
184
|
+
const report = yield checker.check();
|
|
185
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
186
|
+
expect(exitCode).toBe(1);
|
|
187
|
+
}));
|
|
188
|
+
it('should handle multiple wrong versions', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
189
|
+
const folders = ['/test/folder1', '/test/folder2'];
|
|
190
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
191
|
+
mockReadPackageJsonFileSync
|
|
192
|
+
.mockReturnValueOnce({
|
|
193
|
+
name: '@test/package1',
|
|
194
|
+
version: '1.0.0',
|
|
195
|
+
dependencies: {},
|
|
196
|
+
devDependencies: {},
|
|
197
|
+
})
|
|
198
|
+
.mockReturnValueOnce({
|
|
199
|
+
name: '@test/package2',
|
|
200
|
+
version: '2.0.0',
|
|
201
|
+
dependencies: {},
|
|
202
|
+
devDependencies: {},
|
|
203
|
+
});
|
|
204
|
+
const checkState = { dependencies: [] };
|
|
205
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
206
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
207
|
+
name: 'test-package',
|
|
208
|
+
version: '1.0.0',
|
|
209
|
+
dependencies: {
|
|
210
|
+
'@test/package1': '1.1.0',
|
|
211
|
+
'@test/package2': '2.1.0',
|
|
212
|
+
},
|
|
213
|
+
devDependencies: {},
|
|
214
|
+
});
|
|
215
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
216
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
217
|
+
const report = yield checker.check();
|
|
218
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
219
|
+
expect(exitCode).toBe(1);
|
|
220
|
+
}));
|
|
221
|
+
it('should handle both wrongVersions and internalAsDev', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
222
|
+
const folders = ['/test/folder1', '/test/folder2'];
|
|
223
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
224
|
+
mockReadPackageJsonFileSync
|
|
225
|
+
.mockReturnValueOnce({
|
|
226
|
+
name: '@test/package1',
|
|
227
|
+
version: '1.0.0',
|
|
228
|
+
dependencies: {},
|
|
229
|
+
devDependencies: {},
|
|
230
|
+
})
|
|
231
|
+
.mockReturnValueOnce({
|
|
232
|
+
name: '@test/package2',
|
|
233
|
+
version: '2.0.0',
|
|
234
|
+
dependencies: {},
|
|
235
|
+
devDependencies: {},
|
|
236
|
+
});
|
|
237
|
+
const checkState = { dependencies: [] };
|
|
238
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
239
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
240
|
+
name: 'test-package',
|
|
241
|
+
version: '1.0.0',
|
|
242
|
+
dependencies: { '@test/package1': '1.1.0' },
|
|
243
|
+
devDependencies: { '@test/package2': '2.0.0' },
|
|
244
|
+
});
|
|
245
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
246
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
247
|
+
const report = yield checker.check();
|
|
248
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
249
|
+
expect(exitCode).toBe(1);
|
|
250
|
+
}));
|
|
251
|
+
it('should add wrongVersions for external packages (when actualVersion is undefined)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
252
|
+
const folders = ['/test/folder1'];
|
|
253
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
254
|
+
mockReadPackageJsonFileSync.mockReturnValue({
|
|
255
|
+
name: '@test/package1',
|
|
256
|
+
version: '1.0.0',
|
|
257
|
+
dependencies: {},
|
|
258
|
+
devDependencies: {},
|
|
259
|
+
});
|
|
260
|
+
const checkState = { dependencies: [] };
|
|
261
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
262
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
263
|
+
name: 'test-package',
|
|
264
|
+
version: '1.0.0',
|
|
265
|
+
dependencies: { 'external-package': '1.0.0' },
|
|
266
|
+
devDependencies: {},
|
|
267
|
+
});
|
|
268
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
269
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
270
|
+
const report = yield checker.check();
|
|
271
|
+
// Текущая реализация добавляет ошибку для внешних пакетов,
|
|
272
|
+
// так как actualVersion === undefined, и условие undefined !== "1.0.0" будет true
|
|
273
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
274
|
+
expect(exitCode).toBe(1);
|
|
275
|
+
}));
|
|
276
|
+
it('should handle empty dependencies and devDependencies', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
277
|
+
const folders = ['/test/folder1'];
|
|
278
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
279
|
+
mockReadPackageJsonFileSync.mockReturnValue({
|
|
280
|
+
name: '@test/package1',
|
|
281
|
+
version: '1.0.0',
|
|
282
|
+
dependencies: {},
|
|
283
|
+
devDependencies: {},
|
|
284
|
+
});
|
|
285
|
+
const checkState = { dependencies: [] };
|
|
286
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
287
|
+
mockReadPackageJsonFile.mockResolvedValue({
|
|
288
|
+
name: 'test-package',
|
|
289
|
+
version: '1.0.0',
|
|
290
|
+
dependencies: {},
|
|
291
|
+
devDependencies: {},
|
|
292
|
+
});
|
|
293
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
294
|
+
const checker = new MonorepoChecker(mockConfig);
|
|
295
|
+
const report = yield checker.check();
|
|
296
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
297
|
+
expect(exitCode).toBe(0);
|
|
298
|
+
}));
|
|
299
|
+
});
|
|
300
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import depcheck from 'depcheck';
|
|
11
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
12
|
+
import { RepoChecker } from '../RepoChecker';
|
|
13
|
+
vi.mock('depcheck', () => ({
|
|
14
|
+
default: vi.fn(),
|
|
15
|
+
}));
|
|
16
|
+
describe('RepoChecker', () => {
|
|
17
|
+
let mockConfig;
|
|
18
|
+
const mockDepcheck = vi.mocked(depcheck);
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
mockConfig = {
|
|
22
|
+
getFolders: vi.fn(),
|
|
23
|
+
getFolderOptions: vi.fn(),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
describe('constructor', () => {
|
|
27
|
+
it('should initialize with config', () => {
|
|
28
|
+
const checker = new RepoChecker(mockConfig);
|
|
29
|
+
expect(checker).toBeInstanceOf(RepoChecker);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe('check', () => {
|
|
33
|
+
it('should call getFolders on config', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
+
const folders = ['/test/folder1'];
|
|
35
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
36
|
+
const checkState = { dependencies: [] };
|
|
37
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
38
|
+
const checker = new RepoChecker(mockConfig);
|
|
39
|
+
yield checker.check();
|
|
40
|
+
expect(mockConfig.getFolders).toHaveBeenCalledTimes(1);
|
|
41
|
+
}));
|
|
42
|
+
it('should call checkFolder for each folder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
const folders = ['/test/folder1', '/test/folder2'];
|
|
44
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
45
|
+
const checkState1 = { dependencies: ['dep1'] };
|
|
46
|
+
const checkState2 = { dependencies: ['dep2'] };
|
|
47
|
+
mockDepcheck.mockResolvedValueOnce(checkState1).mockResolvedValueOnce(checkState2);
|
|
48
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
49
|
+
const checker = new RepoChecker(mockConfig);
|
|
50
|
+
yield checker.check();
|
|
51
|
+
expect(mockDepcheck).toHaveBeenCalledTimes(2);
|
|
52
|
+
}));
|
|
53
|
+
it('should call getFolderOptions for each folder with correct path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
+
const folders = ['/test/folder1', '/test/folder2'];
|
|
55
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
56
|
+
const options1 = { ignoreBinPackage: false };
|
|
57
|
+
const options2 = { ignoreBinPackage: false };
|
|
58
|
+
vi.mocked(mockConfig.getFolderOptions)
|
|
59
|
+
.mockReturnValueOnce(options1)
|
|
60
|
+
.mockReturnValueOnce(options2);
|
|
61
|
+
const checkState = { dependencies: [] };
|
|
62
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
63
|
+
const checker = new RepoChecker(mockConfig);
|
|
64
|
+
yield checker.check();
|
|
65
|
+
expect(mockConfig.getFolderOptions).toHaveBeenCalledWith('/test/folder1');
|
|
66
|
+
expect(mockConfig.getFolderOptions).toHaveBeenCalledWith('/test/folder2');
|
|
67
|
+
}));
|
|
68
|
+
it('should call depcheck with correct path and options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
const folders = ['/test/folder1'];
|
|
70
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
71
|
+
const options = { ignoreBinPackage: false, skipMissing: false };
|
|
72
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue(options);
|
|
73
|
+
const checkState = { dependencies: [] };
|
|
74
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
75
|
+
const checker = new RepoChecker(mockConfig);
|
|
76
|
+
yield checker.check();
|
|
77
|
+
expect(mockDepcheck).toHaveBeenCalledWith('/test/folder1', options);
|
|
78
|
+
}));
|
|
79
|
+
it('should add results to report for each folder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
|
+
const folders = ['/test/folder1', '/test/folder2'];
|
|
81
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
82
|
+
const checkState1 = { dependencies: ['dep1'] };
|
|
83
|
+
const checkState2 = { dependencies: ['dep2'] };
|
|
84
|
+
mockDepcheck.mockResolvedValueOnce(checkState1).mockResolvedValueOnce(checkState2);
|
|
85
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
86
|
+
const checker = new RepoChecker(mockConfig);
|
|
87
|
+
const report = yield checker.check();
|
|
88
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
89
|
+
expect(exitCode).toBe(1);
|
|
90
|
+
}));
|
|
91
|
+
it('should return Report instance', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
const folders = ['/test/folder1'];
|
|
93
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue(folders);
|
|
94
|
+
const checkState = { dependencies: [] };
|
|
95
|
+
mockDepcheck.mockResolvedValue(checkState);
|
|
96
|
+
vi.mocked(mockConfig.getFolderOptions).mockReturnValue({});
|
|
97
|
+
const checker = new RepoChecker(mockConfig);
|
|
98
|
+
const report = yield checker.check();
|
|
99
|
+
expect(report).toBeDefined();
|
|
100
|
+
expect(report.printResultAndGetExitCode).toBeDefined();
|
|
101
|
+
}));
|
|
102
|
+
it('should handle empty folders array', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
vi.mocked(mockConfig.getFolders).mockReturnValue([]);
|
|
104
|
+
const checker = new RepoChecker(mockConfig);
|
|
105
|
+
const report = yield checker.check();
|
|
106
|
+
expect(mockDepcheck).not.toHaveBeenCalled();
|
|
107
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
108
|
+
expect(exitCode).toBe(0);
|
|
109
|
+
}));
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { globSync } from 'glob';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { RepoConfig } from './RepoConfig';
|
|
4
|
+
export class MonorepoConfig extends RepoConfig {
|
|
5
|
+
constructor(env) {
|
|
6
|
+
super(env);
|
|
7
|
+
this.rootPackagesFolderPattern = env.rootPackagesFolderPattern;
|
|
8
|
+
this.ignoredPackagesFolderFiles = env.ignoredPackagesFolderFiles || [];
|
|
9
|
+
this.packages = env.packages || {};
|
|
10
|
+
}
|
|
11
|
+
getFolderOptions(folderPath) {
|
|
12
|
+
var _a, _b;
|
|
13
|
+
const options = super.getFolderOptions(folderPath);
|
|
14
|
+
const folder = path.basename(folderPath);
|
|
15
|
+
const folderIgnores = this.packages[folder];
|
|
16
|
+
if (!folderIgnores) {
|
|
17
|
+
return options;
|
|
18
|
+
}
|
|
19
|
+
if ((_a = folderIgnores.ignorePatterns) === null || _a === void 0 ? void 0 : _a.length) {
|
|
20
|
+
options.ignorePatterns = [...(options.ignorePatterns || []), ...folderIgnores.ignorePatterns];
|
|
21
|
+
}
|
|
22
|
+
if ((_b = folderIgnores.ignoreMatches) === null || _b === void 0 ? void 0 : _b.length) {
|
|
23
|
+
options.ignoreMatches = [...(options.ignoreMatches || []), ...folderIgnores.ignoreMatches];
|
|
24
|
+
}
|
|
25
|
+
return options;
|
|
26
|
+
}
|
|
27
|
+
getFolders() {
|
|
28
|
+
if (!this.folders) {
|
|
29
|
+
this.folders = globSync(this.rootPackagesFolderPattern, {
|
|
30
|
+
ignore: this.ignoredPackagesFolderFiles,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return this.folders;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Options } from 'depcheck';
|
|
2
|
+
import { RepoEnvType } from '../types';
|
|
3
|
+
export declare class RepoConfig {
|
|
4
|
+
protected pwd: string;
|
|
5
|
+
private ignorePatterns?;
|
|
6
|
+
private ignoreMatches?;
|
|
7
|
+
constructor(env: RepoEnvType);
|
|
8
|
+
getFolders(): string[];
|
|
9
|
+
getFolderOptions(_folder: string): Options;
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
export class RepoConfig {
|
|
3
|
+
constructor(env) {
|
|
4
|
+
this.pwd = path.resolve(env.cwd);
|
|
5
|
+
this.ignoreMatches = env.ignoreMatches || [];
|
|
6
|
+
this.ignorePatterns = env.ignorePatterns || [];
|
|
7
|
+
}
|
|
8
|
+
getFolders() {
|
|
9
|
+
return [this.pwd];
|
|
10
|
+
}
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
12
|
+
getFolderOptions(_folder) {
|
|
13
|
+
return {
|
|
14
|
+
ignoreBinPackage: false,
|
|
15
|
+
skipMissing: false,
|
|
16
|
+
ignorePatterns: this.ignorePatterns,
|
|
17
|
+
ignoreMatches: this.ignoreMatches,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|