knip 1.0.0-alpha.0 → 1.0.0-alpha.2
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 +2 -2
- package/dist/configuration-chief.js +4 -2
- package/dist/dependency-deputy.d.ts +4 -11
- package/dist/dependency-deputy.js +14 -15
- package/dist/index.js +25 -12
- package/dist/issue-collector.d.ts +3 -5
- package/dist/issue-collector.js +6 -8
- package/dist/plugins/eslint/index.js +6 -6
- package/dist/plugins/rollup/index.js +1 -1
- package/dist/reporters/codeowners.js +8 -8
- package/dist/source-lab.d.ts +3 -6
- package/dist/source-lab.js +18 -38
- package/dist/types/config.d.ts +1 -0
- package/dist/types/issues.d.ts +1 -0
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/validate.d.ts +12 -0
- package/dist/types/validate.js +11 -1
- package/dist/util/glob.d.ts +1 -0
- package/dist/util/glob.js +1 -0
- package/dist/util/members.d.ts +1 -1
- package/dist/util/modules.d.ts +2 -0
- package/dist/util/modules.js +6 -0
- package/dist/workspace-worker.js +27 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,8 +20,8 @@ The dots don't connect themselves. This is where Knip comes in:
|
|
|
20
20
|
- [x] Finds used dependencies not listed in `package.json`.
|
|
21
21
|
- [x] Finds duplicate exports.
|
|
22
22
|
- [x] Finds unused members of classes and enums
|
|
23
|
-
- [x]
|
|
24
|
-
- [x] Growing list of plugins (= less to configure and custom dependency resolvers)
|
|
23
|
+
- [x] Built-in support for monorepos (workspaces)
|
|
24
|
+
- [x] Growing list of built-in plugins (= less to configure and custom dependency resolvers)
|
|
25
25
|
- [x] Supports JavaScript (without `tsconfig.json`, or TypeScript `allowJs: true`).
|
|
26
26
|
- [x] Features multiple [reporters][1] and supports [custom reporters][2] (think JSON and `CODEOWNERS`)
|
|
27
27
|
- [x] Run Knip as part of your CI environment to detect issues and prevent regressions.
|
|
@@ -18,8 +18,8 @@ const defaultConfig = {
|
|
|
18
18
|
ignoreWorkspaces: [],
|
|
19
19
|
workspaces: {
|
|
20
20
|
[ROOT_WORKSPACE_NAME]: {
|
|
21
|
-
entryFiles: ['index.{js,ts}', 'src/index.{js,ts}'],
|
|
22
|
-
projectFiles: ['**/*.ts'],
|
|
21
|
+
entryFiles: ['index.{js,ts,tsx}', 'src/index.{js,ts,tsx}'],
|
|
22
|
+
projectFiles: ['**/*.{js,ts,tsx}'],
|
|
23
23
|
ignore: [],
|
|
24
24
|
paths: {},
|
|
25
25
|
},
|
|
@@ -103,10 +103,12 @@ export default class ConfigurationChief {
|
|
|
103
103
|
const config = isObject ? arrayify(pluginConfig.config) : arrayify(pluginConfig);
|
|
104
104
|
const entryFiles = isObject && 'entryFiles' in pluginConfig ? arrayify(pluginConfig.entryFiles) : [];
|
|
105
105
|
const projectFiles = isObject && 'projectFiles' in pluginConfig ? arrayify(pluginConfig.projectFiles) : entryFiles;
|
|
106
|
+
const sampleFiles = isObject && 'sampleFiles' in pluginConfig ? arrayify(pluginConfig.sampleFiles) : [];
|
|
106
107
|
workspaces[workspaceName][pluginName] = {
|
|
107
108
|
config,
|
|
108
109
|
entryFiles,
|
|
109
110
|
projectFiles,
|
|
111
|
+
sampleFiles,
|
|
110
112
|
};
|
|
111
113
|
}
|
|
112
114
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WorkspaceConfiguration } from './types/config.js';
|
|
2
|
+
import type { Issue } from './types/issues.js';
|
|
2
3
|
import type { WorkspaceManifests } from './types/workspace.js';
|
|
3
4
|
import type { PackageJson } from 'type-fest';
|
|
4
5
|
export default class DependencyDeputy {
|
|
@@ -8,14 +9,12 @@ export default class DependencyDeputy {
|
|
|
8
9
|
referencedDependencies: Map<string, Set<string>>;
|
|
9
10
|
peerDependencies: Map<string, Map<string, Set<string>>>;
|
|
10
11
|
tsConfigPathGlobs: Map<string, string[]>;
|
|
11
|
-
isProduction: boolean;
|
|
12
12
|
constructor();
|
|
13
|
-
addWorkspace({ name, dir, manifestPath, manifest,
|
|
13
|
+
addWorkspace({ name, dir, manifestPath, manifest, }: {
|
|
14
14
|
name: string;
|
|
15
15
|
dir: string;
|
|
16
16
|
manifestPath: string;
|
|
17
17
|
manifest: PackageJson;
|
|
18
|
-
isProduction: boolean;
|
|
19
18
|
}): void;
|
|
20
19
|
cancelWorkspace(workspaceName: string): void;
|
|
21
20
|
getManifest(workspaceName: string): PackageJson | undefined;
|
|
@@ -47,13 +46,7 @@ export default class DependencyDeputy {
|
|
|
47
46
|
resolvePackageName(moduleSpecifier: string): string;
|
|
48
47
|
private isInDependencies;
|
|
49
48
|
settleDependencyIssues(): {
|
|
50
|
-
dependencyIssues:
|
|
51
|
-
|
|
52
|
-
symbol: string;
|
|
53
|
-
}[];
|
|
54
|
-
devDependencyIssues: {
|
|
55
|
-
filePath: string;
|
|
56
|
-
symbol: string;
|
|
57
|
-
}[];
|
|
49
|
+
dependencyIssues: Issue[];
|
|
50
|
+
devDependencyIssues: Issue[];
|
|
58
51
|
};
|
|
59
52
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isBuiltin } from 'node:module';
|
|
2
2
|
import micromatch from 'micromatch';
|
|
3
|
+
import { isDefinitelyTyped, getDefinitelyTypedPackage } from './util/modules.js';
|
|
3
4
|
const IGNORE_DEFINITELY_TYPED = ['node'];
|
|
4
5
|
export default class DependencyDeputy {
|
|
5
6
|
_manifests = new Map();
|
|
@@ -8,13 +9,12 @@ export default class DependencyDeputy {
|
|
|
8
9
|
referencedDependencies;
|
|
9
10
|
peerDependencies;
|
|
10
11
|
tsConfigPathGlobs = new Map();
|
|
11
|
-
isProduction = false;
|
|
12
12
|
constructor() {
|
|
13
13
|
this.referencedDependencies = new Map();
|
|
14
14
|
this.peerDependencies = new Map();
|
|
15
15
|
this.canceledWorkspaces = new Set();
|
|
16
16
|
}
|
|
17
|
-
addWorkspace({ name, dir, manifestPath, manifest,
|
|
17
|
+
addWorkspace({ name, dir, manifestPath, manifest, }) {
|
|
18
18
|
const scripts = Object.values(manifest.scripts ?? {});
|
|
19
19
|
const dependencies = Object.keys(manifest.dependencies ?? {});
|
|
20
20
|
const peerDependencies = Object.keys(manifest.peerDependencies ?? {});
|
|
@@ -33,7 +33,6 @@ export default class DependencyDeputy {
|
|
|
33
33
|
productionDependencies,
|
|
34
34
|
allDependencies: [...productionDependencies, ...devDependencies],
|
|
35
35
|
});
|
|
36
|
-
this.isProduction = isProduction;
|
|
37
36
|
}
|
|
38
37
|
cancelWorkspace(workspaceName) {
|
|
39
38
|
this.canceledWorkspaces.add(workspaceName);
|
|
@@ -71,12 +70,14 @@ export default class DependencyDeputy {
|
|
|
71
70
|
const packageName = this.resolvePackageName(moduleSpecifier);
|
|
72
71
|
const workspaceNames = isStrict ? [workspace.name] : [workspace.name, ...[...workspace.ancestors].reverse()];
|
|
73
72
|
const closestWorkspaceName = workspaceNames.find(name => this.isInDependencies(name, packageName));
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
const typesPackageName = !isDefinitelyTyped(packageName) && getDefinitelyTypedPackage(packageName);
|
|
74
|
+
const closestWorkspaceNameForTypes = typesPackageName && workspaceNames.find(name => this.isInDependencies(name, typesPackageName));
|
|
75
|
+
if (closestWorkspaceName || closestWorkspaceNameForTypes) {
|
|
76
|
+
closestWorkspaceName && this.addReferencedDependency(closestWorkspaceName, packageName);
|
|
77
|
+
closestWorkspaceNameForTypes && this.addReferencedDependency(closestWorkspaceNameForTypes, typesPackageName);
|
|
78
|
+
return;
|
|
79
79
|
}
|
|
80
|
+
return moduleSpecifier;
|
|
80
81
|
}
|
|
81
82
|
isInternalDependency(workspaceName, moduleSpecifier) {
|
|
82
83
|
if (moduleSpecifier.startsWith('/') || moduleSpecifier.startsWith('.'))
|
|
@@ -106,15 +107,13 @@ export default class DependencyDeputy {
|
|
|
106
107
|
continue;
|
|
107
108
|
const referencedDependencies = this.referencedDependencies.get(workspaceName);
|
|
108
109
|
const isUnreferencedDependency = (dependency) => {
|
|
110
|
+
if (referencedDependencies?.has(dependency))
|
|
111
|
+
return false;
|
|
109
112
|
const [scope, typedDependency] = dependency.split('/');
|
|
110
113
|
if (scope === '@types') {
|
|
111
114
|
if (IGNORE_DEFINITELY_TYPED.includes(typedDependency))
|
|
112
115
|
return false;
|
|
113
|
-
|
|
114
|
-
return false;
|
|
115
|
-
const [scope, name] = typedDependency.split('__');
|
|
116
|
-
const typedPackageName = scope && name ? `@${scope}/${name}` : typedDependency;
|
|
117
|
-
return referencedDependencies ? !referencedDependencies.has(typedPackageName) : false;
|
|
116
|
+
return !referencedDependencies?.has(typedDependency);
|
|
118
117
|
}
|
|
119
118
|
if (!referencedDependencies?.has(dependency)) {
|
|
120
119
|
const peerDependencies = Array.from(this.peerDependencies.get(workspaceName)?.get(dependency) ?? []);
|
|
@@ -124,10 +123,10 @@ export default class DependencyDeputy {
|
|
|
124
123
|
};
|
|
125
124
|
this.getProductionDependencies(workspaceName)
|
|
126
125
|
.filter(isUnreferencedDependency)
|
|
127
|
-
.forEach(symbol => dependencyIssues.push({ filePath: manifestPath, symbol }));
|
|
126
|
+
.forEach(symbol => dependencyIssues.push({ type: 'dependencies', filePath: manifestPath, symbol }));
|
|
128
127
|
this.getDevDependencies(workspaceName)
|
|
129
128
|
.filter(isUnreferencedDependency)
|
|
130
|
-
.forEach(symbol => devDependencyIssues.push({ filePath: manifestPath, symbol }));
|
|
129
|
+
.forEach(symbol => devDependencyIssues.push({ type: 'devDependencies', filePath: manifestPath, symbol }));
|
|
131
130
|
}
|
|
132
131
|
return { dependencyIssues, devDependencyIssues };
|
|
133
132
|
}
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,10 @@ import SourceLab from './source-lab.js';
|
|
|
7
7
|
import { compact } from './util/array.js';
|
|
8
8
|
import { ROOT_WORKSPACE_NAME } from './util/constants.js';
|
|
9
9
|
import { debugLogObject, debugLogFiles } from './util/debug.js';
|
|
10
|
+
import { _findExternalImportModuleSpecifiers } from './util/externalImports.js';
|
|
10
11
|
import { findFile, loadJSON } from './util/fs.js';
|
|
11
12
|
import { _glob } from './util/glob.js';
|
|
13
|
+
import { _findDuplicateExportedNames } from './util/project.js';
|
|
12
14
|
import { loadTSConfig } from './util/tsconfig-loader.js';
|
|
13
15
|
import WorkspaceWorker from './workspace-worker.js';
|
|
14
16
|
export const main = async (unresolvedConfiguration) => {
|
|
@@ -16,7 +18,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
16
18
|
const chief = new ConfigurationChief({ cwd });
|
|
17
19
|
const deputy = new DependencyDeputy();
|
|
18
20
|
debugLogObject(1, 'Unresolved configuration', unresolvedConfiguration);
|
|
19
|
-
const collector = new IssueCollector({ cwd, isShowProgress
|
|
21
|
+
const collector = new IssueCollector({ cwd, isShowProgress });
|
|
20
22
|
collector.updateMessage('Reading configuration and manifest files...');
|
|
21
23
|
await chief.loadLocalConfig();
|
|
22
24
|
const workspaces = await chief.getActiveWorkspaces();
|
|
@@ -30,7 +32,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
30
32
|
const negatedWorkspacePatterns = Object.values(workspaces)
|
|
31
33
|
.filter(workspace => workspace.name !== ROOT_WORKSPACE_NAME)
|
|
32
34
|
.map(workspace => `!${workspace.name}`);
|
|
33
|
-
const lab = new SourceLab({
|
|
35
|
+
const lab = new SourceLab({ report, workspaceDirs });
|
|
34
36
|
const principal = new ProjectPrincipal();
|
|
35
37
|
for (const { name, dir, config, ancestors } of workspaces) {
|
|
36
38
|
const isRoot = name === ROOT_WORKSPACE_NAME;
|
|
@@ -39,7 +41,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
39
41
|
const manifest = isRoot ? chief.manifest : manifestPath && (await loadJSON(manifestPath));
|
|
40
42
|
if (!manifestPath || !manifest)
|
|
41
43
|
continue;
|
|
42
|
-
deputy.addWorkspace({ name, dir, manifestPath, manifest
|
|
44
|
+
deputy.addWorkspace({ name, dir, manifestPath, manifest });
|
|
43
45
|
const tsConfigFilePath = path.join(dir, 'tsconfig.json');
|
|
44
46
|
const tsConfig = await loadTSConfig(tsConfigFilePath);
|
|
45
47
|
if (isRoot && tsConfig) {
|
|
@@ -189,10 +191,10 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
189
191
|
if (!deputy.isInternalDependency(name, issue.symbol)) {
|
|
190
192
|
if (!workspaceDependencies.includes(issue.symbol)) {
|
|
191
193
|
if (isStrict) {
|
|
192
|
-
collector.addIssue(
|
|
194
|
+
collector.addIssue(issue);
|
|
193
195
|
}
|
|
194
196
|
else if (!rootDependencies.includes(issue.symbol)) {
|
|
195
|
-
collector.addIssue(
|
|
197
|
+
collector.addIssue(issue);
|
|
196
198
|
}
|
|
197
199
|
}
|
|
198
200
|
}
|
|
@@ -207,23 +209,34 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
207
209
|
collector.addFilesIssues(unreferencedProductionFiles);
|
|
208
210
|
collector.updateMessage('Connecting the dots...');
|
|
209
211
|
usedProductionFiles.forEach(sourceFile => {
|
|
212
|
+
collector.counters.processed++;
|
|
210
213
|
const filePath = sourceFile.getFilePath();
|
|
211
214
|
const workspaceDir = workspaceDirs.find(workspaceDir => filePath.startsWith(workspaceDir));
|
|
212
215
|
const workspace = workspaces.find(workspace => workspace.dir === workspaceDir);
|
|
213
|
-
|
|
214
|
-
|
|
216
|
+
if (workspace && (report.dependencies || report.unlisted)) {
|
|
217
|
+
const externalModuleSpecifiers = _findExternalImportModuleSpecifiers(sourceFile);
|
|
215
218
|
externalModuleSpecifiers.forEach(moduleSpecifier => {
|
|
216
219
|
const unlistedDependency = deputy.maybeAddListedReferencedDependency(workspace, moduleSpecifier, isStrict);
|
|
217
220
|
if (unlistedDependency)
|
|
218
|
-
collector.addIssue('unlisted',
|
|
221
|
+
collector.addIssue({ type: 'unlisted', filePath, symbol: unlistedDependency });
|
|
219
222
|
});
|
|
220
223
|
}
|
|
224
|
+
if (report.duplicates) {
|
|
225
|
+
const duplicateExports = _findDuplicateExportedNames(sourceFile);
|
|
226
|
+
duplicateExports.forEach(symbols => {
|
|
227
|
+
const symbol = symbols.join('|');
|
|
228
|
+
collector.addIssue({ type: 'duplicates', filePath, symbol, symbols });
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const issues = lab.analyzeSourceFile(sourceFile);
|
|
232
|
+
issues.forEach(issue => issue.type && collector.addIssue(issue));
|
|
221
233
|
});
|
|
222
234
|
collector.removeProgress();
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
235
|
+
if (report.dependencies) {
|
|
236
|
+
const { dependencyIssues, devDependencyIssues } = deputy.settleDependencyIssues();
|
|
237
|
+
dependencyIssues.forEach(issue => collector.addIssue(issue));
|
|
238
|
+
if (!isProduction)
|
|
239
|
+
devDependencyIssues.forEach(issue => collector.addIssue(issue));
|
|
227
240
|
}
|
|
228
241
|
const { issues, counters } = collector.getIssues();
|
|
229
242
|
debugLogObject(3, 'Issues', issues);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { LineRewriter } from './util/log.js';
|
|
2
|
-
import type { Issue,
|
|
2
|
+
import type { Issue, Report } from './types/issues.js';
|
|
3
3
|
type IssueCollectorOptions = {
|
|
4
4
|
cwd: string;
|
|
5
5
|
isShowProgress?: boolean;
|
|
6
|
-
isProduction?: boolean;
|
|
7
6
|
report?: Report;
|
|
8
7
|
};
|
|
9
8
|
export default class IssueCollector {
|
|
@@ -15,12 +14,11 @@ export default class IssueCollector {
|
|
|
15
14
|
referencedFiles: Set<string>;
|
|
16
15
|
cwd: string;
|
|
17
16
|
isShowProgress: boolean;
|
|
18
|
-
|
|
19
|
-
constructor({ cwd, isShowProgress, isProduction, report }: IssueCollectorOptions);
|
|
17
|
+
constructor({ cwd, isShowProgress, report }: IssueCollectorOptions);
|
|
20
18
|
setIsShowProgress(isShowProgress: boolean): void;
|
|
21
19
|
setProjectFilesCount(count: number): void;
|
|
22
20
|
addFilesIssues(filePaths: Set<string>): void;
|
|
23
|
-
addIssue(
|
|
21
|
+
addIssue(issue: Issue): void;
|
|
24
22
|
setReport(report: Report): void;
|
|
25
23
|
updateMessage(message: string): void;
|
|
26
24
|
updateProgress(issue?: Issue): void;
|
package/dist/issue-collector.js
CHANGED
|
@@ -11,10 +11,8 @@ export default class IssueCollector {
|
|
|
11
11
|
referencedFiles;
|
|
12
12
|
cwd;
|
|
13
13
|
isShowProgress = false;
|
|
14
|
-
|
|
15
|
-
constructor({ cwd, isShowProgress = false, isProduction = false, report }) {
|
|
14
|
+
constructor({ cwd, isShowProgress = false, report }) {
|
|
16
15
|
this.lineRewriter = new LineRewriter();
|
|
17
|
-
this.isProduction = isProduction;
|
|
18
16
|
this.cwd = cwd;
|
|
19
17
|
this.setIsShowProgress(isShowProgress);
|
|
20
18
|
this.report = report ?? initReport();
|
|
@@ -38,13 +36,13 @@ export default class IssueCollector {
|
|
|
38
36
|
}
|
|
39
37
|
});
|
|
40
38
|
}
|
|
41
|
-
addIssue(
|
|
39
|
+
addIssue(issue) {
|
|
42
40
|
issue.filePath = path.relative(this.cwd, issue.filePath);
|
|
43
41
|
const key = relative(issue.filePath);
|
|
44
|
-
this.issues[
|
|
45
|
-
if (!this.issues[
|
|
46
|
-
this.issues[
|
|
47
|
-
this.counters[
|
|
42
|
+
this.issues[issue.type][key] = this.issues[issue.type][key] ?? {};
|
|
43
|
+
if (!this.issues[issue.type][key][issue.symbol]) {
|
|
44
|
+
this.issues[issue.type][key][issue.symbol] = issue;
|
|
45
|
+
this.counters[issue.type]++;
|
|
48
46
|
this.updateProgress(issue);
|
|
49
47
|
}
|
|
50
48
|
}
|
|
@@ -8,6 +8,7 @@ export const isEnabled = ({ dependencies }) => {
|
|
|
8
8
|
return dependencies.has('eslint');
|
|
9
9
|
};
|
|
10
10
|
export const CONFIG_FILE_PATTERNS = ['eslint.config.js', '.eslintrc', '.eslintrc.json', '.eslintrc.js'];
|
|
11
|
+
const SAMPLE_FILE_PATHS = ['__placeholder__.js', '__placeholder__.ts'];
|
|
11
12
|
const resolvePluginPackageName = (pluginName) => {
|
|
12
13
|
return pluginName.startsWith('@')
|
|
13
14
|
? pluginName.includes('/')
|
|
@@ -15,16 +16,15 @@ const resolvePluginPackageName = (pluginName) => {
|
|
|
15
16
|
: `${pluginName}/eslint-plugin`
|
|
16
17
|
: `eslint-plugin-${pluginName}`;
|
|
17
18
|
};
|
|
18
|
-
const findESLintDependencies = async (configFilePath, { cwd }) => {
|
|
19
|
+
const findESLintDependencies = async (configFilePath, { cwd, config }) => {
|
|
19
20
|
if (path.basename(configFilePath) === 'eslint.config.js') {
|
|
20
21
|
return [];
|
|
21
22
|
}
|
|
22
23
|
else {
|
|
23
24
|
const engine = new ESLint({ cwd, overrideConfigFile: configFilePath, useEslintrc: false });
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const dependencies = [jsConfig, tsConfig, tsxConfig].map(config => {
|
|
25
|
+
const calculateConfigForFile = async (sampleFile) => await engine.calculateConfigForFile(sampleFile);
|
|
26
|
+
const sampleFiles = config?.sampleFiles.length > 0 ? config.sampleFiles : SAMPLE_FILE_PATHS;
|
|
27
|
+
const dependencies = await Promise.all(sampleFiles.map(calculateConfigForFile)).then(configs => configs.flatMap(config => {
|
|
28
28
|
if (!config)
|
|
29
29
|
return [];
|
|
30
30
|
const plugins = config.plugins?.map(resolvePluginPackageName) ?? [];
|
|
@@ -32,7 +32,7 @@ const findESLintDependencies = async (configFilePath, { cwd }) => {
|
|
|
32
32
|
const extraParsers = config.parserOptions?.babelOptions?.presets ?? [];
|
|
33
33
|
const settings = config.settings ? getDependenciesFromSettings(config.settings) : [];
|
|
34
34
|
return [...parsers, ...extraParsers, ...plugins, ...settings].map(getPackageName);
|
|
35
|
-
});
|
|
35
|
+
}));
|
|
36
36
|
return compact(dependencies.flat());
|
|
37
37
|
}
|
|
38
38
|
};
|
|
@@ -43,20 +43,20 @@ export default ({ report, issues, options }) => {
|
|
|
43
43
|
const fallbackOwner = dependenciesOwner;
|
|
44
44
|
const calcFileOwnership = (filePath) => codeownersEngine.calcFileOwnership(relative(filePath))[0] ?? fallbackOwner;
|
|
45
45
|
const addOwner = (issue) => ({ ...issue, owner: calcFileOwnership(issue.filePath) });
|
|
46
|
-
for (const [
|
|
46
|
+
for (const [type, isReportType] of Object.entries(report)) {
|
|
47
47
|
if (isReportType) {
|
|
48
|
-
const title = reportMultipleGroups && ISSUE_TYPE_TITLE[
|
|
49
|
-
if (issues[
|
|
50
|
-
const toIssue = (filePath) => ({ filePath, symbol: filePath });
|
|
51
|
-
const issuesForType = Array.from(issues[
|
|
48
|
+
const title = reportMultipleGroups && ISSUE_TYPE_TITLE[type];
|
|
49
|
+
if (issues[type] instanceof Set) {
|
|
50
|
+
const toIssue = (filePath) => ({ type, filePath, symbol: filePath });
|
|
51
|
+
const issuesForType = Array.from(issues[type]).map(toIssue);
|
|
52
52
|
logIssueSet(issuesForType.map(addOwner), title);
|
|
53
53
|
}
|
|
54
|
-
else if (
|
|
55
|
-
const issuesForType = Object.values(issues[
|
|
54
|
+
else if (type === 'duplicates') {
|
|
55
|
+
const issuesForType = Object.values(issues[type]).map(Object.values).flat().map(addOwner);
|
|
56
56
|
logIssueRecord(issuesForType, title);
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
const issuesForType = Object.values(issues[
|
|
59
|
+
const issuesForType = Object.values(issues[type]).map(issues => {
|
|
60
60
|
const items = Object.values(issues);
|
|
61
61
|
return addOwner({ ...items[0], symbols: items.map(issue => issue.symbol) });
|
|
62
62
|
});
|
package/dist/source-lab.d.ts
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import { SourceFile } from 'ts-morph';
|
|
2
|
-
import
|
|
3
|
-
import type { Report } from './types/issues.js';
|
|
2
|
+
import type { Report, Issue } from './types/issues.js';
|
|
4
3
|
type FileLabOptions = {
|
|
5
|
-
issueManager: IssueCollector;
|
|
6
4
|
report: Report;
|
|
7
5
|
workspaceDirs: string[];
|
|
8
6
|
};
|
|
9
7
|
export default class SourceLab {
|
|
10
|
-
issueManager: IssueCollector;
|
|
11
8
|
report: Report;
|
|
12
9
|
workspaceDirs: string[];
|
|
13
10
|
skipExportsAnalysis: Set<unknown>;
|
|
14
11
|
isReportExports: boolean;
|
|
15
12
|
isReportValues: boolean;
|
|
16
13
|
isReportTypes: boolean;
|
|
17
|
-
constructor({
|
|
14
|
+
constructor({ report, workspaceDirs }: FileLabOptions);
|
|
18
15
|
skipExportsAnalysisFor(filePath: string | string[]): void;
|
|
19
|
-
analyzeSourceFile(sourceFile: SourceFile):
|
|
16
|
+
analyzeSourceFile(sourceFile: SourceFile): Set<Issue>;
|
|
20
17
|
private analyzeExports;
|
|
21
18
|
}
|
|
22
19
|
export {};
|
package/dist/source-lab.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import { ts, Node } from 'ts-morph';
|
|
2
|
-
import { _findExternalImportModuleSpecifiers } from './util/externalImports.js';
|
|
3
2
|
import { findUnusedClassMembers, findUnusedEnumMembers } from './util/members.js';
|
|
4
|
-
import {
|
|
3
|
+
import { _hasReferencingDefaultImport, _findReferencingNamespaceNodes, _getExportedDeclarations, _findReferences, hasExternalReferences, } from './util/project.js';
|
|
5
4
|
import { getType } from './util/type.js';
|
|
6
5
|
export default class SourceLab {
|
|
7
|
-
issueManager;
|
|
8
6
|
report;
|
|
9
7
|
workspaceDirs;
|
|
10
8
|
skipExportsAnalysis;
|
|
11
9
|
isReportExports;
|
|
12
10
|
isReportValues;
|
|
13
11
|
isReportTypes;
|
|
14
|
-
constructor({
|
|
15
|
-
this.issueManager = issueManager;
|
|
12
|
+
constructor({ report, workspaceDirs }) {
|
|
16
13
|
this.report = report;
|
|
17
14
|
this.workspaceDirs = workspaceDirs;
|
|
18
15
|
this.skipExportsAnalysis = new Set();
|
|
@@ -27,30 +24,18 @@ export default class SourceLab {
|
|
|
27
24
|
filePath.forEach(filePath => this.skipExportsAnalysis.add(filePath));
|
|
28
25
|
}
|
|
29
26
|
analyzeSourceFile(sourceFile) {
|
|
30
|
-
const
|
|
31
|
-
const report = this.report;
|
|
32
|
-
let externalModuleSpecifiers = [];
|
|
33
|
-
im.counters.processed++;
|
|
27
|
+
const issues = new Set();
|
|
34
28
|
const filePath = sourceFile.getFilePath();
|
|
35
|
-
if (report.dependencies || report.unlisted) {
|
|
36
|
-
externalModuleSpecifiers = _findExternalImportModuleSpecifiers(sourceFile);
|
|
37
|
-
}
|
|
38
|
-
if (report.duplicates) {
|
|
39
|
-
const duplicateExports = _findDuplicateExportedNames(sourceFile);
|
|
40
|
-
duplicateExports.forEach(symbols => {
|
|
41
|
-
const symbol = symbols.join('|');
|
|
42
|
-
im.addIssue('duplicates', { filePath, symbol, symbols });
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
29
|
if (this.skipExportsAnalysis.has(filePath))
|
|
46
|
-
return
|
|
30
|
+
return issues;
|
|
47
31
|
if (this.isReportExports) {
|
|
48
|
-
this.analyzeExports(sourceFile);
|
|
32
|
+
const exportsIssues = this.analyzeExports(sourceFile);
|
|
33
|
+
exportsIssues.forEach(issue => issues.add(issue));
|
|
49
34
|
}
|
|
50
|
-
return
|
|
35
|
+
return issues;
|
|
51
36
|
}
|
|
52
37
|
analyzeExports(sourceFile) {
|
|
53
|
-
const
|
|
38
|
+
const issues = new Set();
|
|
54
39
|
const report = this.report;
|
|
55
40
|
const filePath = sourceFile.getFilePath();
|
|
56
41
|
const exportDeclarations = _getExportedDeclarations(sourceFile);
|
|
@@ -70,7 +55,8 @@ export default class SourceLab {
|
|
|
70
55
|
if (declaration.isKind(ts.SyntaxKind.EnumDeclaration)) {
|
|
71
56
|
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier);
|
|
72
57
|
if (report.enumMembers) {
|
|
73
|
-
findUnusedEnumMembers(declaration, filePath).forEach(member =>
|
|
58
|
+
findUnusedEnumMembers(declaration, filePath).forEach(member => issues.add({
|
|
59
|
+
type: 'enumMembers',
|
|
74
60
|
filePath,
|
|
75
61
|
symbol: member.getName(),
|
|
76
62
|
parentSymbol: identifier?.getText(),
|
|
@@ -80,7 +66,8 @@ export default class SourceLab {
|
|
|
80
66
|
else if (declaration.isKind(ts.SyntaxKind.ClassDeclaration)) {
|
|
81
67
|
identifier = declaration.getFirstChildByKind(ts.SyntaxKind.Identifier);
|
|
82
68
|
if (report.classMembers) {
|
|
83
|
-
findUnusedClassMembers(declaration, filePath).forEach(member =>
|
|
69
|
+
findUnusedClassMembers(declaration, filePath).forEach(member => issues.add({
|
|
70
|
+
type: 'classMembers',
|
|
84
71
|
filePath,
|
|
85
72
|
symbol: member.getName(),
|
|
86
73
|
parentSymbol: identifier?.getText(),
|
|
@@ -119,38 +106,31 @@ export default class SourceLab {
|
|
|
119
106
|
}
|
|
120
107
|
if (identifier || fakeIdentifier) {
|
|
121
108
|
const identifierText = fakeIdentifier ?? identifier?.getText() ?? '*';
|
|
122
|
-
if (report.exports && im.issues.exports[filePath]?.[identifierText])
|
|
123
|
-
return;
|
|
124
|
-
if (report.types && im.issues.types[filePath]?.[identifierText])
|
|
125
|
-
return;
|
|
126
|
-
if (report.nsExports && im.issues.nsExports[filePath]?.[identifierText])
|
|
127
|
-
return;
|
|
128
|
-
if (report.nsTypes && im.issues.nsTypes[filePath]?.[identifierText])
|
|
129
|
-
return;
|
|
130
109
|
const refs = _findReferences(identifier);
|
|
131
110
|
if (refs.length === 0) {
|
|
132
|
-
|
|
111
|
+
issues.add({ type: 'exports', filePath, symbol: identifierText });
|
|
133
112
|
}
|
|
134
113
|
else {
|
|
135
114
|
if (hasExternalReferences(refs, filePath))
|
|
136
115
|
return;
|
|
137
116
|
if (_findReferencingNamespaceNodes(sourceFile).length > 0) {
|
|
138
117
|
if (type) {
|
|
139
|
-
|
|
118
|
+
issues.add({ type: 'nsTypes', filePath, symbol: identifierText, symbolType: type });
|
|
140
119
|
}
|
|
141
120
|
else {
|
|
142
|
-
|
|
121
|
+
issues.add({ type: 'nsExports', filePath, symbol: identifierText });
|
|
143
122
|
}
|
|
144
123
|
}
|
|
145
124
|
else if (type) {
|
|
146
|
-
|
|
125
|
+
issues.add({ type: 'types', filePath, symbol: identifierText, symbolType: type });
|
|
147
126
|
}
|
|
148
127
|
else {
|
|
149
|
-
|
|
128
|
+
issues.add({ type: 'exports', filePath, symbol: identifierText });
|
|
150
129
|
}
|
|
151
130
|
}
|
|
152
131
|
}
|
|
153
132
|
});
|
|
154
133
|
});
|
|
134
|
+
return issues;
|
|
155
135
|
}
|
|
156
136
|
}
|
package/dist/types/config.d.ts
CHANGED
package/dist/types/issues.d.ts
CHANGED
package/dist/types/plugins.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PackageJson } from 'type-fest';
|
|
2
|
+
import { PluginConfiguration } from './config.js';
|
|
2
3
|
type IsPluginEnabledCallbackOptions = {
|
|
3
4
|
manifest: PackageJson;
|
|
4
5
|
dependencies: Set<string>;
|
|
@@ -7,5 +8,6 @@ export type IsPluginEnabledCallback = (options: IsPluginEnabledCallbackOptions)
|
|
|
7
8
|
export type GenericPluginCallback = (configFilePath: string, { cwd, manifest }: {
|
|
8
9
|
cwd: string;
|
|
9
10
|
manifest: PackageJson;
|
|
11
|
+
config: PluginConfiguration;
|
|
10
12
|
}) => Promise<string[]> | string[];
|
|
11
13
|
export {};
|
package/dist/types/validate.d.ts
CHANGED
|
@@ -85,16 +85,19 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
85
85
|
entryFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
86
86
|
productionEntryFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
87
87
|
projectFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
88
|
+
sampleFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
88
89
|
}, "strip", z.ZodTypeAny, {
|
|
89
90
|
config?: string | string[] | undefined;
|
|
90
91
|
entryFiles?: string | string[] | undefined;
|
|
91
92
|
projectFiles?: string | string[] | undefined;
|
|
92
93
|
productionEntryFiles?: string | string[] | undefined;
|
|
94
|
+
sampleFiles?: string | string[] | undefined;
|
|
93
95
|
}, {
|
|
94
96
|
config?: string | string[] | undefined;
|
|
95
97
|
entryFiles?: string | string[] | undefined;
|
|
96
98
|
projectFiles?: string | string[] | undefined;
|
|
97
99
|
productionEntryFiles?: string | string[] | undefined;
|
|
100
|
+
sampleFiles?: string | string[] | undefined;
|
|
98
101
|
}>]>>;
|
|
99
102
|
gatsby: z.ZodOptional<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
|
|
100
103
|
config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
@@ -290,6 +293,7 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
290
293
|
entryFiles?: string | string[] | undefined;
|
|
291
294
|
projectFiles?: string | string[] | undefined;
|
|
292
295
|
productionEntryFiles?: string | string[] | undefined;
|
|
296
|
+
sampleFiles?: string | string[] | undefined;
|
|
293
297
|
} | undefined;
|
|
294
298
|
gatsby?: string | string[] | {
|
|
295
299
|
config?: string | string[] | undefined;
|
|
@@ -385,6 +389,7 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
385
389
|
entryFiles?: string | string[] | undefined;
|
|
386
390
|
projectFiles?: string | string[] | undefined;
|
|
387
391
|
productionEntryFiles?: string | string[] | undefined;
|
|
392
|
+
sampleFiles?: string | string[] | undefined;
|
|
388
393
|
} | undefined;
|
|
389
394
|
gatsby?: string | string[] | {
|
|
390
395
|
config?: string | string[] | undefined;
|
|
@@ -517,16 +522,19 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
517
522
|
entryFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
518
523
|
productionEntryFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
519
524
|
projectFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
525
|
+
sampleFiles: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
520
526
|
}, "strip", z.ZodTypeAny, {
|
|
521
527
|
config?: string | string[] | undefined;
|
|
522
528
|
entryFiles?: string | string[] | undefined;
|
|
523
529
|
projectFiles?: string | string[] | undefined;
|
|
524
530
|
productionEntryFiles?: string | string[] | undefined;
|
|
531
|
+
sampleFiles?: string | string[] | undefined;
|
|
525
532
|
}, {
|
|
526
533
|
config?: string | string[] | undefined;
|
|
527
534
|
entryFiles?: string | string[] | undefined;
|
|
528
535
|
projectFiles?: string | string[] | undefined;
|
|
529
536
|
productionEntryFiles?: string | string[] | undefined;
|
|
537
|
+
sampleFiles?: string | string[] | undefined;
|
|
530
538
|
}>]>>;
|
|
531
539
|
gatsby: z.ZodOptional<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
|
|
532
540
|
config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
@@ -726,6 +734,7 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
726
734
|
entryFiles?: string | string[] | undefined;
|
|
727
735
|
projectFiles?: string | string[] | undefined;
|
|
728
736
|
productionEntryFiles?: string | string[] | undefined;
|
|
737
|
+
sampleFiles?: string | string[] | undefined;
|
|
729
738
|
} | undefined;
|
|
730
739
|
gatsby?: string | string[] | {
|
|
731
740
|
config?: string | string[] | undefined;
|
|
@@ -821,6 +830,7 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
821
830
|
entryFiles?: string | string[] | undefined;
|
|
822
831
|
projectFiles?: string | string[] | undefined;
|
|
823
832
|
productionEntryFiles?: string | string[] | undefined;
|
|
833
|
+
sampleFiles?: string | string[] | undefined;
|
|
824
834
|
} | undefined;
|
|
825
835
|
gatsby?: string | string[] | {
|
|
826
836
|
config?: string | string[] | undefined;
|
|
@@ -921,6 +931,7 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
921
931
|
entryFiles?: string | string[] | undefined;
|
|
922
932
|
projectFiles?: string | string[] | undefined;
|
|
923
933
|
productionEntryFiles?: string | string[] | undefined;
|
|
934
|
+
sampleFiles?: string | string[] | undefined;
|
|
924
935
|
} | undefined;
|
|
925
936
|
gatsby?: string | string[] | {
|
|
926
937
|
config?: string | string[] | undefined;
|
|
@@ -1016,6 +1027,7 @@ export declare const LocalConfiguration: z.ZodObject<z.extendShape<z.extendShape
|
|
|
1016
1027
|
entryFiles?: string | string[] | undefined;
|
|
1017
1028
|
projectFiles?: string | string[] | undefined;
|
|
1018
1029
|
productionEntryFiles?: string | string[] | undefined;
|
|
1030
|
+
sampleFiles?: string | string[] | undefined;
|
|
1019
1031
|
} | undefined;
|
|
1020
1032
|
gatsby?: string | string[] | {
|
|
1021
1033
|
config?: string | string[] | undefined;
|
package/dist/types/validate.js
CHANGED
|
@@ -21,12 +21,22 @@ const pluginWithEntryFilesSchema = z.union([
|
|
|
21
21
|
projectFiles: globSchema.optional(),
|
|
22
22
|
}),
|
|
23
23
|
]);
|
|
24
|
+
const pluginWithSampleFilesSchema = z.union([
|
|
25
|
+
globSchema,
|
|
26
|
+
z.object({
|
|
27
|
+
config: globSchema.optional(),
|
|
28
|
+
entryFiles: globSchema.optional(),
|
|
29
|
+
productionEntryFiles: globSchema.optional(),
|
|
30
|
+
projectFiles: globSchema.optional(),
|
|
31
|
+
sampleFiles: globSchema.optional(),
|
|
32
|
+
}),
|
|
33
|
+
]);
|
|
24
34
|
const pluginsConfigurationSchema = z.object({
|
|
25
35
|
babel: pluginWithEntryFilesSchema,
|
|
26
36
|
capacitor: pluginWithEntryFilesSchema,
|
|
27
37
|
changesets: pluginWithEntryFilesSchema,
|
|
28
38
|
cypress: pluginWithEntryFilesSchema,
|
|
29
|
-
eslint:
|
|
39
|
+
eslint: pluginWithSampleFilesSchema,
|
|
30
40
|
gatsby: pluginWithEntryFilesSchema,
|
|
31
41
|
jest: pluginWithEntryFilesSchema,
|
|
32
42
|
next: pluginWithEntryFilesSchema,
|
package/dist/util/glob.d.ts
CHANGED
package/dist/util/glob.js
CHANGED
|
@@ -10,6 +10,7 @@ const prependDirToPattern = (workingDir, pattern) => {
|
|
|
10
10
|
return path.posix.join(workingDir, pattern);
|
|
11
11
|
};
|
|
12
12
|
export const negate = (pattern) => `!${pattern}`;
|
|
13
|
+
export const removeProductionSuffix = (pattern) => pattern.replace(/!$/, '');
|
|
13
14
|
const sortNegatedLast = (a, b) => (a.startsWith('!') ? 1 : b.startsWith('!') ? -1 : 0);
|
|
14
15
|
const glob = async ({ cwd, workingDir = cwd, patterns, ignore = [], gitignore = true, }) => {
|
|
15
16
|
const cwdPosix = ensurePosixPath(cwd);
|
package/dist/util/members.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { MethodDeclaration, PropertyDeclaration } from 'ts-morph';
|
|
2
2
|
import type { ClassDeclaration, EnumDeclaration } from 'ts-morph';
|
|
3
|
-
export declare const findUnusedClassMembers: (declaration: ClassDeclaration, filePath: string) => (
|
|
3
|
+
export declare const findUnusedClassMembers: (declaration: ClassDeclaration, filePath: string) => (MethodDeclaration | PropertyDeclaration)[];
|
|
4
4
|
export declare const findUnusedEnumMembers: (declaration: EnumDeclaration, filePath: string) => import("ts-morph").EnumMember[];
|
package/dist/util/modules.d.ts
CHANGED
package/dist/util/modules.js
CHANGED
|
@@ -8,3 +8,9 @@ export const getPackageName = (value) => {
|
|
|
8
8
|
}
|
|
9
9
|
return value.startsWith('/') ? value : value.split('/')[0];
|
|
10
10
|
};
|
|
11
|
+
export const isDefinitelyTyped = (packageName) => packageName.startsWith('@types/');
|
|
12
|
+
export const getDefinitelyTypedPackage = (packageName) => {
|
|
13
|
+
if (isDefinitelyTyped(packageName))
|
|
14
|
+
return packageName;
|
|
15
|
+
return '@types/' + packageName.replace('@', '__');
|
|
16
|
+
};
|
package/dist/workspace-worker.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as npm from './npm-scripts/index.js';
|
|
|
3
3
|
import * as plugins from './plugins/index.js';
|
|
4
4
|
import { ROOT_WORKSPACE_NAME, TEST_FILE_PATTERNS } from './util/constants.js';
|
|
5
5
|
import { debugLogFiles, debugLogIssues } from './util/debug.js';
|
|
6
|
-
import { _pureGlob, negate } from './util/glob.js';
|
|
6
|
+
import { _pureGlob, negate, removeProductionSuffix } from './util/glob.js';
|
|
7
7
|
const negatedTestFilePatterns = TEST_FILE_PATTERNS.map(negate);
|
|
8
8
|
export default class WorkspaceWorker {
|
|
9
9
|
name;
|
|
@@ -51,7 +51,7 @@ export default class WorkspaceWorker {
|
|
|
51
51
|
}
|
|
52
52
|
getConfigForPlugin(pluginName) {
|
|
53
53
|
return (this.config[pluginName] ??
|
|
54
|
-
this.rootWorkspaceConfig[pluginName] ?? { config: [], entryFiles: [], projectFiles: [] });
|
|
54
|
+
this.rootWorkspaceConfig[pluginName] ?? { config: [], entryFiles: [], projectFiles: [], sampleFiles: [] });
|
|
55
55
|
}
|
|
56
56
|
async init() {
|
|
57
57
|
this.setEnabledPlugins();
|
|
@@ -69,7 +69,7 @@ export default class WorkspaceWorker {
|
|
|
69
69
|
async initReferencedDependencies() {
|
|
70
70
|
const { dependencies, peerDependencies } = await npm.findDependencies(this.rootConfig.ignoreBinaries, this.manifest, this.isRoot, this.dir, this.rootWorkspaceDir);
|
|
71
71
|
const filePath = path.join(this.dir, 'package.json');
|
|
72
|
-
dependencies.forEach(dependency => this.referencedDependencyIssues.add({ filePath, symbol: dependency }));
|
|
72
|
+
dependencies.forEach(dependency => this.referencedDependencyIssues.add({ type: 'unlisted', filePath, symbol: dependency }));
|
|
73
73
|
dependencies.forEach(dependency => this.referencedDependencies.add(dependency));
|
|
74
74
|
this.peerDependencies = peerDependencies;
|
|
75
75
|
}
|
|
@@ -79,7 +79,7 @@ export default class WorkspaceWorker {
|
|
|
79
79
|
return [];
|
|
80
80
|
return [entryFiles, TEST_FILE_PATTERNS, this.isRoot ? this.negatedWorkspacePatterns : []]
|
|
81
81
|
.flat()
|
|
82
|
-
.map(
|
|
82
|
+
.map(removeProductionSuffix);
|
|
83
83
|
}
|
|
84
84
|
getProjectFilePatterns() {
|
|
85
85
|
const { projectFiles } = this.config;
|
|
@@ -87,7 +87,7 @@ export default class WorkspaceWorker {
|
|
|
87
87
|
return [];
|
|
88
88
|
return [projectFiles, TEST_FILE_PATTERNS, this.isRoot ? this.negatedWorkspacePatterns : []]
|
|
89
89
|
.flat()
|
|
90
|
-
.map(
|
|
90
|
+
.map(removeProductionSuffix);
|
|
91
91
|
}
|
|
92
92
|
getPluginEntryFilePatterns(isProduction = false) {
|
|
93
93
|
const patterns = [];
|
|
@@ -103,7 +103,7 @@ export default class WorkspaceWorker {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
return patterns.flat().map(
|
|
106
|
+
return patterns.flat().map(removeProductionSuffix);
|
|
107
107
|
}
|
|
108
108
|
getPluginProjectFilePatterns() {
|
|
109
109
|
const patterns = [];
|
|
@@ -118,7 +118,7 @@ export default class WorkspaceWorker {
|
|
|
118
118
|
patterns.push(projectFilePatterns.length > 0 ? projectFilePatterns : entryFilesPatterns);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
return patterns.flat().map(
|
|
121
|
+
return patterns.flat().map(removeProductionSuffix);
|
|
122
122
|
}
|
|
123
123
|
getPluginConfigPatterns() {
|
|
124
124
|
const patterns = [];
|
|
@@ -130,7 +130,7 @@ export default class WorkspaceWorker {
|
|
|
130
130
|
patterns.push(...pluginConfig.config);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
|
-
return patterns.flat().map(
|
|
133
|
+
return patterns.flat().map(removeProductionSuffix);
|
|
134
134
|
}
|
|
135
135
|
getProductionEntryFilePatterns() {
|
|
136
136
|
const entryFiles = this.config.entryFiles.filter(p => p.endsWith('!'));
|
|
@@ -139,18 +139,18 @@ export default class WorkspaceWorker {
|
|
|
139
139
|
const negatedEntryFiles = this.config.entryFiles.filter(p => !p.endsWith('!')).map(negate);
|
|
140
140
|
return [entryFiles, negatedEntryFiles, negatedTestFilePatterns, this.isRoot ? this.negatedWorkspacePatterns : []]
|
|
141
141
|
.flat()
|
|
142
|
-
.map(
|
|
142
|
+
.map(removeProductionSuffix);
|
|
143
143
|
}
|
|
144
144
|
getProductionProjectFilePatterns() {
|
|
145
145
|
const projectFiles = this.config.projectFiles;
|
|
146
146
|
if (projectFiles.length === 0)
|
|
147
147
|
return this.getProductionEntryFilePatterns();
|
|
148
|
-
const _projectFiles = this.config.projectFiles.map(
|
|
149
|
-
if (!
|
|
150
|
-
return negate(
|
|
151
|
-
return
|
|
148
|
+
const _projectFiles = this.config.projectFiles.map(pattern => {
|
|
149
|
+
if (!pattern.endsWith('!') && !pattern.startsWith('!'))
|
|
150
|
+
return negate(pattern);
|
|
151
|
+
return pattern;
|
|
152
152
|
});
|
|
153
|
-
const negatedEntryFiles = this.config.entryFiles.filter(
|
|
153
|
+
const negatedEntryFiles = this.config.entryFiles.filter(pattern => !pattern.endsWith('!')).map(negate);
|
|
154
154
|
const negatedPluginConfigPatterns = this.getPluginConfigPatterns().map(negate);
|
|
155
155
|
const negatedPluginEntryFilePatterns = this.getPluginEntryFilePatterns(true).map(negate);
|
|
156
156
|
const negatedPluginProjectFilePatterns = this.getPluginProjectFilePatterns().map(negate);
|
|
@@ -164,7 +164,7 @@ export default class WorkspaceWorker {
|
|
|
164
164
|
this.isRoot ? this.negatedWorkspacePatterns : [],
|
|
165
165
|
]
|
|
166
166
|
.flat()
|
|
167
|
-
.map(
|
|
167
|
+
.map(removeProductionSuffix);
|
|
168
168
|
}
|
|
169
169
|
getProductionPluginEntryFilePatterns() {
|
|
170
170
|
const patterns = [];
|
|
@@ -178,10 +178,9 @@ export default class WorkspaceWorker {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
|
|
182
|
-
if (p.length === 0)
|
|
181
|
+
if (patterns.length === 0)
|
|
183
182
|
return [];
|
|
184
|
-
return [
|
|
183
|
+
return [patterns.flat().map(removeProductionSuffix), negatedTestFilePatterns].flat();
|
|
185
184
|
}
|
|
186
185
|
getConfigurationEntryFilePattern(pluginName) {
|
|
187
186
|
const pluginConfig = this.getConfigForPlugin(pluginName);
|
|
@@ -213,14 +212,19 @@ export default class WorkspaceWorker {
|
|
|
213
212
|
const cwd = this.dir;
|
|
214
213
|
const ignore = this.getWorkspaceIgnorePatterns();
|
|
215
214
|
const configFilePaths = await _pureGlob({ patterns, cwd, ignore });
|
|
215
|
+
const pluginConfig = this.getConfigForPlugin(pluginName);
|
|
216
216
|
debugLogFiles(1, `Globbed ${pluginName} config file paths`, configFilePaths);
|
|
217
217
|
if (configFilePaths.length === 0)
|
|
218
218
|
return [];
|
|
219
|
-
const
|
|
220
|
-
const dependencies = await pluginCallback(configFilePath, {
|
|
221
|
-
|
|
219
|
+
const referencedDependencyIssues = (await Promise.all(configFilePaths.map(async (configFilePath) => {
|
|
220
|
+
const dependencies = await pluginCallback(configFilePath, {
|
|
221
|
+
cwd,
|
|
222
|
+
manifest: this.manifest,
|
|
223
|
+
config: pluginConfig,
|
|
224
|
+
});
|
|
225
|
+
return dependencies.map(symbol => ({ type: 'unlisted', filePath: configFilePath, symbol }));
|
|
222
226
|
}))).flat();
|
|
223
|
-
debugLogIssues(1, `Dependencies used by ${pluginName} configuration`,
|
|
224
|
-
return
|
|
227
|
+
debugLogIssues(1, `Dependencies used by ${pluginName} configuration`, referencedDependencyIssues);
|
|
228
|
+
return referencedDependencyIssues;
|
|
225
229
|
}
|
|
226
230
|
}
|