knip 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IssueFixer.d.ts +21 -0
- package/dist/IssueFixer.js +75 -0
- package/dist/ProjectPrincipal.d.ts +3 -1
- package/dist/ProjectPrincipal.js +5 -3
- package/dist/cli.js +3 -1
- package/dist/index.js +19 -3
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/exports.d.ts +3 -0
- package/dist/typescript/getImportsAndExports.d.ts +5 -2
- package/dist/typescript/getImportsAndExports.js +5 -3
- package/dist/typescript/visitors/exports/exportAssignment.js +3 -2
- package/dist/typescript/visitors/exports/exportDeclaration.js +3 -8
- package/dist/typescript/visitors/exports/exportKeyword.js +67 -12
- package/dist/typescript/visitors/exports/moduleExportsAccessExpression.js +20 -5
- package/dist/util/cli-arguments.d.ts +3 -1
- package/dist/util/cli-arguments.js +5 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +12 -2
- package/schema.json +15 -13
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ExportPos } from './types/exports.js';
|
|
2
|
+
import type { Issues } from './types/issues.js';
|
|
3
|
+
export declare class IssueFixer {
|
|
4
|
+
isEnabled: boolean;
|
|
5
|
+
cwd: string;
|
|
6
|
+
isFixDependencies: boolean;
|
|
7
|
+
isFixUnusedTypes: boolean;
|
|
8
|
+
isFixUnusedExports: boolean;
|
|
9
|
+
unusedTypeNodes: Map<string, Set<[number, number]>>;
|
|
10
|
+
unusedExportNodes: Map<string, Set<[number, number]>>;
|
|
11
|
+
constructor({ isEnabled, cwd, fixTypes }: {
|
|
12
|
+
isEnabled: boolean;
|
|
13
|
+
cwd: string;
|
|
14
|
+
fixTypes: string[];
|
|
15
|
+
});
|
|
16
|
+
addUnusedTypeNode(filePath: string, fix: ExportPos): void;
|
|
17
|
+
addUnusedExportNode(filePath: string, fix: ExportPos): void;
|
|
18
|
+
fixIssues(issues: Issues): Promise<void>;
|
|
19
|
+
private removeUnusedExportKeywords;
|
|
20
|
+
private removeUnusedDependencies;
|
|
21
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
2
|
+
import NPMCliPackageJson from '@npmcli/package-json';
|
|
3
|
+
import { dirname, join } from './util/path.js';
|
|
4
|
+
export class IssueFixer {
|
|
5
|
+
isEnabled = false;
|
|
6
|
+
cwd = process.cwd();
|
|
7
|
+
isFixDependencies = true;
|
|
8
|
+
isFixUnusedTypes = true;
|
|
9
|
+
isFixUnusedExports = true;
|
|
10
|
+
unusedTypeNodes = new Map();
|
|
11
|
+
unusedExportNodes = new Map();
|
|
12
|
+
constructor({ isEnabled, cwd, fixTypes = [] }) {
|
|
13
|
+
this.isEnabled = isEnabled;
|
|
14
|
+
this.cwd = cwd;
|
|
15
|
+
this.isFixDependencies = fixTypes.length === 0 || fixTypes.includes('dependencies');
|
|
16
|
+
this.isFixUnusedTypes = fixTypes.length === 0 || fixTypes.includes('types');
|
|
17
|
+
this.isFixUnusedExports = fixTypes.length === 0 || fixTypes.includes('exports');
|
|
18
|
+
}
|
|
19
|
+
addUnusedTypeNode(filePath, fix) {
|
|
20
|
+
if (fix.length === 0)
|
|
21
|
+
return;
|
|
22
|
+
if (this.unusedTypeNodes.has(filePath))
|
|
23
|
+
this.unusedTypeNodes.get(filePath).add(fix);
|
|
24
|
+
else
|
|
25
|
+
this.unusedTypeNodes.set(filePath, new Set([fix]));
|
|
26
|
+
}
|
|
27
|
+
addUnusedExportNode(filePath, fix) {
|
|
28
|
+
if (fix.length === 0)
|
|
29
|
+
return;
|
|
30
|
+
if (this.unusedExportNodes.has(filePath))
|
|
31
|
+
this.unusedExportNodes.get(filePath).add(fix);
|
|
32
|
+
else
|
|
33
|
+
this.unusedExportNodes.set(filePath, new Set([fix]));
|
|
34
|
+
}
|
|
35
|
+
async fixIssues(issues) {
|
|
36
|
+
await this.removeUnusedExportKeywords();
|
|
37
|
+
await this.removeUnusedDependencies(issues);
|
|
38
|
+
}
|
|
39
|
+
async removeUnusedExportKeywords() {
|
|
40
|
+
const filePaths = new Set([...this.unusedTypeNodes.keys(), ...this.unusedExportNodes.keys()]);
|
|
41
|
+
for (const filePath of filePaths) {
|
|
42
|
+
const exportPositions = [
|
|
43
|
+
...(this.isFixUnusedTypes ? this.unusedTypeNodes.get(filePath) ?? [] : []),
|
|
44
|
+
...(this.isFixUnusedExports ? this.unusedExportNodes.get(filePath) ?? [] : []),
|
|
45
|
+
].sort((a, b) => b[0] - a[0]);
|
|
46
|
+
if (exportPositions.length > 0) {
|
|
47
|
+
const text = await readFile(filePath, 'utf-8');
|
|
48
|
+
const sourceFileText = exportPositions.reduce((text, [start, end]) => text.substring(0, start) + text.substring(end), text);
|
|
49
|
+
await writeFile(filePath, sourceFileText);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async removeUnusedDependencies(issues) {
|
|
54
|
+
if (!this.isFixDependencies)
|
|
55
|
+
return;
|
|
56
|
+
const filePaths = new Set([...Object.keys(issues.dependencies), ...Object.keys(issues.devDependencies)]);
|
|
57
|
+
for (const filePath of filePaths) {
|
|
58
|
+
const manifest = await NPMCliPackageJson.load(dirname(join(this.cwd, filePath)));
|
|
59
|
+
const pkg = manifest.content;
|
|
60
|
+
if (filePath in issues.dependencies) {
|
|
61
|
+
Object.keys(issues.dependencies[filePath]).forEach(dependency => {
|
|
62
|
+
if (pkg.dependencies)
|
|
63
|
+
delete pkg.dependencies[dependency];
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (filePath in issues.devDependencies) {
|
|
67
|
+
Object.keys(issues.devDependencies[filePath]).forEach(dependency => {
|
|
68
|
+
if (pkg.devDependencies)
|
|
69
|
+
delete pkg.devDependencies[dependency];
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
await manifest.save();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -38,8 +38,10 @@ export declare class ProjectPrincipal {
|
|
|
38
38
|
getUsedResolvedFiles(): string[];
|
|
39
39
|
private getProgramSourceFiles;
|
|
40
40
|
getUnreferencedFiles(): string[];
|
|
41
|
-
analyzeSourceFile(filePath: string, { skipTypeOnly }: {
|
|
41
|
+
analyzeSourceFile(filePath: string, { skipTypeOnly, isFixExports, isFixTypes }: {
|
|
42
42
|
skipTypeOnly: boolean;
|
|
43
|
+
isFixExports: boolean;
|
|
44
|
+
isFixTypes: boolean;
|
|
43
45
|
}): {
|
|
44
46
|
imports: {
|
|
45
47
|
internal: import("./types/imports.js").Imports;
|
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -3,7 +3,7 @@ import { DEFAULT_EXTENSIONS } from './constants.js';
|
|
|
3
3
|
import { IGNORED_FILE_EXTENSIONS } from './constants.js';
|
|
4
4
|
import { getJSDocTags, getLineAndCharacterOfPosition, isInModuleBlock } from './typescript/ast-helpers.js';
|
|
5
5
|
import { createHosts } from './typescript/createHosts.js';
|
|
6
|
-
import {
|
|
6
|
+
import { _getImportsAndExports } from './typescript/getImportsAndExports.js';
|
|
7
7
|
import { createCustomModuleResolver } from './typescript/resolveModuleNames.js';
|
|
8
8
|
import { SourceFileManager } from './typescript/SourceFileManager.js';
|
|
9
9
|
import { compact } from './util/array.js';
|
|
@@ -113,7 +113,7 @@ export class ProjectPrincipal {
|
|
|
113
113
|
const sourceFiles = this.getProgramSourceFiles();
|
|
114
114
|
return Array.from(this.projectPaths).filter(filePath => !sourceFiles.has(filePath));
|
|
115
115
|
}
|
|
116
|
-
analyzeSourceFile(filePath, { skipTypeOnly }) {
|
|
116
|
+
analyzeSourceFile(filePath, { skipTypeOnly, isFixExports, isFixTypes }) {
|
|
117
117
|
const sourceFile = this.backend.fileManager.getSourceFile(filePath);
|
|
118
118
|
if (!sourceFile)
|
|
119
119
|
throw new Error(`Unable to find ${filePath}`);
|
|
@@ -121,9 +121,11 @@ export class ProjectPrincipal {
|
|
|
121
121
|
const getResolvedModule = specifier => this.backend.program?.getResolvedModule
|
|
122
122
|
? this.backend.program.getResolvedModule(sourceFile, specifier, undefined)
|
|
123
123
|
: sourceFile.resolvedModules?.get(specifier, undefined);
|
|
124
|
-
const { imports, exports, scripts } =
|
|
124
|
+
const { imports, exports, scripts } = _getImportsAndExports(sourceFile, getResolvedModule, {
|
|
125
125
|
skipTypeOnly,
|
|
126
126
|
skipExports,
|
|
127
|
+
isFixExports,
|
|
128
|
+
isFixTypes,
|
|
127
129
|
});
|
|
128
130
|
const { internal, unresolved, external } = imports;
|
|
129
131
|
const unresolvedImports = new Set();
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Performance } from './util/Performance.js';
|
|
|
7
7
|
import { runPreprocessors, runReporters } from './util/reporter.js';
|
|
8
8
|
import { version } from './version.js';
|
|
9
9
|
import { main } from './index.js';
|
|
10
|
-
const { debug: isDebug = false, help: isHelp, 'max-issues': maxIssues = '0', 'no-config-hints': noConfigHints = false, 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = false, 'include-entry-exports': isIncludeEntryExports = false, 'isolate-workspaces': isIsolateWorkspaces = false, performance: isObservePerf = false, production: isProduction = false, 'reporter-options': reporterOptions = '', 'preprocessor-options': preprocessorOptions = '', strict: isStrict = false, tsConfig, version: isVersion, } = parsedArgValues;
|
|
10
|
+
const { debug: isDebug = false, help: isHelp, 'max-issues': maxIssues = '0', 'no-config-hints': noConfigHints = false, 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = false, 'include-entry-exports': isIncludeEntryExports = false, 'isolate-workspaces': isIsolateWorkspaces = false, performance: isObservePerf = false, production: isProduction = false, 'reporter-options': reporterOptions = '', 'preprocessor-options': preprocessorOptions = '', strict: isStrict = false, fix: isFix = false, 'fix-type': fixTypes = [], tsConfig, version: isVersion, } = parsedArgValues;
|
|
11
11
|
if (isHelp) {
|
|
12
12
|
console.log(helpText);
|
|
13
13
|
process.exit(0);
|
|
@@ -29,6 +29,8 @@ const run = async () => {
|
|
|
29
29
|
isShowProgress,
|
|
30
30
|
isIncludeEntryExports,
|
|
31
31
|
isIsolateWorkspaces,
|
|
32
|
+
isFix,
|
|
33
|
+
fixTypes: fixTypes.flatMap(type => type.split(',')),
|
|
32
34
|
});
|
|
33
35
|
const initialData = {
|
|
34
36
|
report,
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { ConfigurationChief } from './ConfigurationChief.js';
|
|
|
5
5
|
import { ConsoleStreamer } from './ConsoleStreamer.js';
|
|
6
6
|
import { DependencyDeputy } from './DependencyDeputy.js';
|
|
7
7
|
import { IssueCollector } from './IssueCollector.js';
|
|
8
|
+
import { IssueFixer } from './IssueFixer.js';
|
|
8
9
|
import { PrincipalFactory } from './PrincipalFactory.js';
|
|
9
10
|
import { ProjectPrincipal } from './ProjectPrincipal.js';
|
|
10
11
|
import { debugLogObject, debugLogArray, debugLog } from './util/debug.js';
|
|
@@ -16,7 +17,7 @@ import { _resolveSpecifier } from './util/require.js';
|
|
|
16
17
|
import { loadTSConfig } from './util/tsconfig-loader.js';
|
|
17
18
|
import { WorkspaceWorker } from './WorkspaceWorker.js';
|
|
18
19
|
export const main = async (unresolvedConfiguration) => {
|
|
19
|
-
const { cwd, tsConfigFile, gitignore, isStrict, isProduction, isShowProgress, isIncludeEntryExports, isIsolateWorkspaces, } = unresolvedConfiguration;
|
|
20
|
+
const { cwd, tsConfigFile, gitignore, isStrict, isProduction, isShowProgress, isIncludeEntryExports, isIsolateWorkspaces, isFix, fixTypes, } = unresolvedConfiguration;
|
|
20
21
|
debugLogObject('*', 'Unresolved configuration (from CLI arguments)', unresolvedConfiguration);
|
|
21
22
|
const chief = new ConfigurationChief({ cwd, isProduction, isStrict, isIncludeEntryExports });
|
|
22
23
|
const deputy = new DependencyDeputy({ isProduction, isStrict });
|
|
@@ -30,6 +31,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
30
31
|
const report = chief.getIssueTypesToReport();
|
|
31
32
|
const rules = chief.getRules();
|
|
32
33
|
const filters = chief.getFilters();
|
|
34
|
+
const fixer = new IssueFixer({ isEnabled: isFix || fixTypes.length > 0, cwd, fixTypes });
|
|
33
35
|
const isReportDependencies = report.dependencies || report.unlisted || report.unresolved;
|
|
34
36
|
const isReportValues = report.exports || report.nsExports || report.classMembers;
|
|
35
37
|
const isReportTypes = report.types || report.nsTypes || report.enumMembers;
|
|
@@ -190,7 +192,11 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
190
192
|
const analyzeSourceFile = (filePath, _principal = principal) => {
|
|
191
193
|
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
192
194
|
if (workspace) {
|
|
193
|
-
const { imports, exports, scripts } = _principal.analyzeSourceFile(filePath, {
|
|
195
|
+
const { imports, exports, scripts } = _principal.analyzeSourceFile(filePath, {
|
|
196
|
+
skipTypeOnly: isStrict,
|
|
197
|
+
isFixExports: fixer.isFixUnusedExports,
|
|
198
|
+
isFixTypes: fixer.isFixUnusedTypes,
|
|
199
|
+
});
|
|
194
200
|
const { internal, external, unresolved } = imports;
|
|
195
201
|
const { exported, duplicate } = exports;
|
|
196
202
|
if (exported.size > 0)
|
|
@@ -308,8 +314,11 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
308
314
|
if (isProduction && exportedItem.jsDocTags.has('@internal'))
|
|
309
315
|
continue;
|
|
310
316
|
if (importsForExport && isSymbolImported(symbol, importsForExport)) {
|
|
311
|
-
if (
|
|
317
|
+
if (!isIncludeEntryExports &&
|
|
318
|
+
importsForExport.isReExport &&
|
|
319
|
+
isExportedInEntryFile(principal, importsForExport)) {
|
|
312
320
|
continue;
|
|
321
|
+
}
|
|
313
322
|
if (report.enumMembers && exportedItem.type === 'enum' && exportedItem.members) {
|
|
314
323
|
principal.findUnusedMembers(filePath, exportedItem.members).forEach(member => {
|
|
315
324
|
collector.addIssue({
|
|
@@ -348,6 +357,10 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
348
357
|
symbolType: exportedItem.type,
|
|
349
358
|
...principal.getPos(exportedItem.node, exportedItem.pos),
|
|
350
359
|
});
|
|
360
|
+
if (isType)
|
|
361
|
+
fixer.addUnusedTypeNode(filePath, exportedItem.fix);
|
|
362
|
+
else
|
|
363
|
+
fixer.addUnusedExportNode(filePath, exportedItem.fix);
|
|
351
364
|
}
|
|
352
365
|
}
|
|
353
366
|
}
|
|
@@ -371,6 +384,9 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
371
384
|
const unusedIgnoredWorkspaces = chief.getUnusedIgnoredWorkspaces();
|
|
372
385
|
unusedIgnoredWorkspaces.forEach(identifier => collector.addConfigurationHint({ type: 'ignoreWorkspaces', identifier }));
|
|
373
386
|
const { issues, counters, configurationHints } = collector.getIssues();
|
|
387
|
+
if (isFix) {
|
|
388
|
+
await fixer.fixIssues(issues);
|
|
389
|
+
}
|
|
374
390
|
streamer.clear();
|
|
375
391
|
return { report, issues, counters, rules, configurationHints };
|
|
376
392
|
};
|
package/dist/types/cli.d.ts
CHANGED
package/dist/types/exports.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import ts from 'typescript';
|
|
|
2
2
|
import type { SymbolType } from './issues.js';
|
|
3
3
|
type FilePath = string;
|
|
4
4
|
type Identifier = string;
|
|
5
|
+
export type ExportPos = [number, number] | [];
|
|
5
6
|
export type ExportItem = {
|
|
6
7
|
node: ts.Node;
|
|
7
8
|
pos: number;
|
|
@@ -9,12 +10,14 @@ export type ExportItem = {
|
|
|
9
10
|
type: SymbolType;
|
|
10
11
|
members?: ExportItemMember[];
|
|
11
12
|
jsDocTags?: Set<string>;
|
|
13
|
+
fix: ExportPos;
|
|
12
14
|
};
|
|
13
15
|
export type ExportItemMember = {
|
|
14
16
|
node: ts.Node;
|
|
15
17
|
identifier: Identifier;
|
|
16
18
|
pos: number;
|
|
17
19
|
type: SymbolType;
|
|
20
|
+
fix: ExportPos;
|
|
18
21
|
};
|
|
19
22
|
export type ExportItems = Map<string, Required<ExportItem>>;
|
|
20
23
|
export type Exports = Map<FilePath, ExportItems>;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import type { BoundSourceFile, GetResolvedModule } from './SourceFile.js';
|
|
3
|
-
import type { ExportItems as Exports, ExportItem } from '../types/exports.js';
|
|
3
|
+
import type { ExportItems as Exports, ExportItem, ExportPos } from '../types/exports.js';
|
|
4
4
|
import type { Imports, UnresolvedImport } from '../types/imports.js';
|
|
5
5
|
import type { IssueSymbol } from '../types/issues.js';
|
|
6
6
|
export type GetImportsAndExportsOptions = {
|
|
7
7
|
skipTypeOnly: boolean;
|
|
8
8
|
skipExports: boolean;
|
|
9
|
+
isFixExports: boolean;
|
|
10
|
+
isFixTypes: boolean;
|
|
9
11
|
};
|
|
10
12
|
export type AddImportOptions = {
|
|
11
13
|
specifier: string;
|
|
@@ -16,8 +18,9 @@ export type AddImportOptions = {
|
|
|
16
18
|
};
|
|
17
19
|
export type AddExportOptions = ExportItem & {
|
|
18
20
|
identifier: string;
|
|
21
|
+
fix: ExportPos;
|
|
19
22
|
};
|
|
20
|
-
export declare const
|
|
23
|
+
export declare const _getImportsAndExports: (sourceFile: BoundSourceFile, getResolvedModule: GetResolvedModule, options: GetImportsAndExportsOptions) => {
|
|
21
24
|
imports: {
|
|
22
25
|
internal: Imports;
|
|
23
26
|
external: Set<string>;
|
|
@@ -3,6 +3,7 @@ import ts from 'typescript';
|
|
|
3
3
|
import { getOrSet } from '../util/map.js';
|
|
4
4
|
import { isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
|
|
5
5
|
import { isInNodeModules } from '../util/path.js';
|
|
6
|
+
import { timerify } from '../util/Performance.js';
|
|
6
7
|
import { isDeclarationFileExtension, isAccessExpression, getAccessExpressionName, getJSDocTags, getLineAndCharacterOfPosition, } from './ast-helpers.js';
|
|
7
8
|
import getExportVisitors from './visitors/exports/index.js';
|
|
8
9
|
import { getJSXImplicitImportBase } from './visitors/helpers.js';
|
|
@@ -13,7 +14,7 @@ const getVisitors = (sourceFile) => ({
|
|
|
13
14
|
import: getImportVisitors(sourceFile),
|
|
14
15
|
script: getScriptVisitors(sourceFile),
|
|
15
16
|
});
|
|
16
|
-
|
|
17
|
+
const getImportsAndExports = (sourceFile, getResolvedModule, options) => {
|
|
17
18
|
const internalImports = new Map();
|
|
18
19
|
const externalImports = new Set();
|
|
19
20
|
const unresolvedImports = new Set();
|
|
@@ -94,7 +95,7 @@ export const getImportsAndExports = (sourceFile, getResolvedModule, options) =>
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
};
|
|
97
|
-
const addExport = ({ node, identifier, type, pos, posDecl, members = [] }) => {
|
|
98
|
+
const addExport = ({ node, identifier, type, pos, posDecl, members = [], fix }) => {
|
|
98
99
|
if (options.skipExports)
|
|
99
100
|
return;
|
|
100
101
|
const jsDocTags = getJSDocTags(node);
|
|
@@ -105,7 +106,7 @@ export const getImportsAndExports = (sourceFile, getResolvedModule, options) =>
|
|
|
105
106
|
exports.set(identifier, { ...item, members: crew, jsDocTags: tags });
|
|
106
107
|
}
|
|
107
108
|
else {
|
|
108
|
-
exports.set(identifier, { node, type, members, jsDocTags, pos, posDecl: posDecl ?? pos });
|
|
109
|
+
exports.set(identifier, { node, type, members, jsDocTags, pos, posDecl: posDecl ?? pos, fix });
|
|
109
110
|
}
|
|
110
111
|
if (!jsDocTags.has('@alias')) {
|
|
111
112
|
if (ts.isExportAssignment(node))
|
|
@@ -176,3 +177,4 @@ export const getImportsAndExports = (sourceFile, getResolvedModule, options) =>
|
|
|
176
177
|
scripts,
|
|
177
178
|
};
|
|
178
179
|
};
|
|
180
|
+
export const _getImportsAndExports = timerify(getImportsAndExports);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { SymbolType } from '../../../types/issues.js';
|
|
3
3
|
import { exportVisitor as visit } from '../index.js';
|
|
4
|
-
export default visit(() => true, node => {
|
|
4
|
+
export default visit(() => true, (node, { isFixExports }) => {
|
|
5
5
|
if (ts.isExportAssignment(node)) {
|
|
6
6
|
const pos = node.getChildAt(1).getStart();
|
|
7
|
-
|
|
7
|
+
const fix = isFixExports ? [node.getStart(), node.getEnd() + 1] : [];
|
|
8
|
+
return { node, identifier: 'default', type: SymbolType.UNKNOWN, pos, fix };
|
|
8
9
|
}
|
|
9
10
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { SymbolType } from '../../../types/issues.js';
|
|
3
3
|
import { exportVisitor as visit } from '../index.js';
|
|
4
|
-
export default visit(() => true, node => {
|
|
4
|
+
export default visit(() => true, (node, { isFixExports, isFixTypes }) => {
|
|
5
5
|
if (ts.isExportDeclaration(node)) {
|
|
6
6
|
if (node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
7
7
|
const type = node.isTypeOnly ? SymbolType.TYPE : SymbolType.UNKNOWN;
|
|
@@ -13,13 +13,8 @@ export default visit(() => true, node => {
|
|
|
13
13
|
const pos = element.name.pos;
|
|
14
14
|
const name = ts.getNameOfDeclaration(declaration);
|
|
15
15
|
const posDecl = name?.pos ?? declaration?.pos ?? pos;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
identifier,
|
|
19
|
-
type,
|
|
20
|
-
pos,
|
|
21
|
-
posDecl,
|
|
22
|
-
};
|
|
16
|
+
const fix = isFixExports || isFixTypes ? [element.getStart(), element.getEnd()] : [];
|
|
17
|
+
return { node: element, identifier, type, pos, posDecl, fix };
|
|
23
18
|
});
|
|
24
19
|
}
|
|
25
20
|
}
|
|
@@ -3,19 +3,21 @@ import { SymbolType } from '../../../types/issues.js';
|
|
|
3
3
|
import { compact } from '../../../util/array.js';
|
|
4
4
|
import { isGetOrSetAccessorDeclaration, isPrivateMember, stripQuotes } from '../../ast-helpers.js';
|
|
5
5
|
import { exportVisitor as visit } from '../index.js';
|
|
6
|
-
export default visit(() => true, node => {
|
|
7
|
-
const
|
|
8
|
-
if (
|
|
6
|
+
export default visit(() => true, (node, { isFixExports, isFixTypes }) => {
|
|
7
|
+
const exportKeyword = node.modifiers?.find(mod => mod.kind === ts.SyntaxKind.ExportKeyword);
|
|
8
|
+
if (exportKeyword) {
|
|
9
9
|
if (ts.isVariableStatement(node)) {
|
|
10
10
|
return node.declarationList.declarations.flatMap(declaration => {
|
|
11
11
|
if (ts.isObjectBindingPattern(declaration.name)) {
|
|
12
12
|
return compact(declaration.name.elements.map(element => {
|
|
13
13
|
if (ts.isIdentifier(element.name)) {
|
|
14
|
+
const fix = isFixExports ? [element.getStart(), element.getEnd()] : [];
|
|
14
15
|
return {
|
|
15
16
|
node: element,
|
|
16
17
|
identifier: element.name.escapedText.toString(),
|
|
17
18
|
type: SymbolType.UNKNOWN,
|
|
18
19
|
pos: element.name.getStart(),
|
|
20
|
+
fix,
|
|
19
21
|
};
|
|
20
22
|
}
|
|
21
23
|
}));
|
|
@@ -23,28 +25,47 @@ export default visit(() => true, node => {
|
|
|
23
25
|
else if (ts.isArrayBindingPattern(declaration.name)) {
|
|
24
26
|
return compact(declaration.name.elements.map(element => {
|
|
25
27
|
if (ts.isBindingElement(element)) {
|
|
28
|
+
const fix = isFixExports ? [element.getStart(), element.getEnd()] : [];
|
|
26
29
|
return {
|
|
27
30
|
node: element,
|
|
28
31
|
identifier: element.getText(),
|
|
29
32
|
type: SymbolType.UNKNOWN,
|
|
30
33
|
pos: element.getStart(),
|
|
34
|
+
fix,
|
|
31
35
|
};
|
|
32
36
|
}
|
|
33
37
|
}));
|
|
34
38
|
}
|
|
35
39
|
else {
|
|
36
40
|
const identifier = declaration.name.getText();
|
|
37
|
-
|
|
41
|
+
const fix = isFixExports ? [exportKeyword.getStart(), exportKeyword.getEnd() + 1] : [];
|
|
42
|
+
return {
|
|
43
|
+
node: declaration,
|
|
44
|
+
identifier,
|
|
45
|
+
type: SymbolType.UNKNOWN,
|
|
46
|
+
pos: declaration.name.getStart(),
|
|
47
|
+
fix,
|
|
48
|
+
};
|
|
38
49
|
}
|
|
39
50
|
});
|
|
40
51
|
}
|
|
52
|
+
const defaultKeyword = node.modifiers?.find(mod => mod.kind === ts.SyntaxKind.DefaultKeyword);
|
|
41
53
|
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
42
|
-
const identifier =
|
|
54
|
+
const identifier = defaultKeyword ? 'default' : node.name.getText();
|
|
43
55
|
const pos = (node.name ?? node.body ?? node).getStart();
|
|
44
|
-
|
|
56
|
+
const fix = isFixExports
|
|
57
|
+
? [exportKeyword.getStart(), (defaultKeyword ?? exportKeyword).getEnd() + 1]
|
|
58
|
+
: [];
|
|
59
|
+
return {
|
|
60
|
+
node,
|
|
61
|
+
identifier,
|
|
62
|
+
pos,
|
|
63
|
+
type: SymbolType.FUNCTION,
|
|
64
|
+
fix,
|
|
65
|
+
};
|
|
45
66
|
}
|
|
46
67
|
if (ts.isClassDeclaration(node) && node.name) {
|
|
47
|
-
const identifier =
|
|
68
|
+
const identifier = defaultKeyword ? 'default' : node.name.getText();
|
|
48
69
|
const pos = (node.name ?? node).getStart();
|
|
49
70
|
const members = node.members
|
|
50
71
|
.filter((member) => (ts.isPropertyDeclaration(member) ||
|
|
@@ -56,25 +77,59 @@ export default visit(() => true, node => {
|
|
|
56
77
|
identifier: member.name.getText(),
|
|
57
78
|
pos: member.name.getStart(),
|
|
58
79
|
type: SymbolType.MEMBER,
|
|
80
|
+
fix: [],
|
|
59
81
|
}));
|
|
60
|
-
|
|
82
|
+
const fix = isFixExports
|
|
83
|
+
? [exportKeyword.getStart(), (defaultKeyword ?? exportKeyword).getEnd() + 1]
|
|
84
|
+
: [];
|
|
85
|
+
return {
|
|
86
|
+
node,
|
|
87
|
+
identifier,
|
|
88
|
+
type: SymbolType.CLASS,
|
|
89
|
+
pos,
|
|
90
|
+
members,
|
|
91
|
+
fix,
|
|
92
|
+
};
|
|
61
93
|
}
|
|
62
94
|
if (ts.isTypeAliasDeclaration(node)) {
|
|
63
|
-
|
|
95
|
+
const fix = isFixTypes ? [exportKeyword.getStart(), exportKeyword.getEnd() + 1] : [];
|
|
96
|
+
return {
|
|
97
|
+
node,
|
|
98
|
+
identifier: node.name.getText(),
|
|
99
|
+
type: SymbolType.TYPE,
|
|
100
|
+
pos: node.name.getStart(),
|
|
101
|
+
fix,
|
|
102
|
+
};
|
|
64
103
|
}
|
|
65
104
|
if (ts.isInterfaceDeclaration(node)) {
|
|
66
|
-
|
|
105
|
+
const fix = isFixTypes ? [exportKeyword.getStart(), exportKeyword.getEnd() + 1] : [];
|
|
106
|
+
return {
|
|
107
|
+
node,
|
|
108
|
+
identifier: node.name.getText(),
|
|
109
|
+
type: SymbolType.INTERFACE,
|
|
110
|
+
pos: node.name.getStart(),
|
|
111
|
+
fix,
|
|
112
|
+
};
|
|
67
113
|
}
|
|
68
114
|
if (ts.isEnumDeclaration(node)) {
|
|
69
|
-
const identifier =
|
|
115
|
+
const identifier = defaultKeyword ? 'default' : node.name.getText();
|
|
70
116
|
const pos = node.name.getStart();
|
|
71
117
|
const members = node.members.map(member => ({
|
|
72
118
|
node: member,
|
|
73
119
|
identifier: stripQuotes(member.name.getText()),
|
|
74
120
|
pos: member.name.getStart(),
|
|
75
121
|
type: SymbolType.MEMBER,
|
|
122
|
+
fix: [],
|
|
76
123
|
}));
|
|
77
|
-
|
|
124
|
+
const fix = isFixTypes ? [exportKeyword.getStart(), exportKeyword.getEnd() + 1] : [];
|
|
125
|
+
return {
|
|
126
|
+
node,
|
|
127
|
+
identifier,
|
|
128
|
+
type: SymbolType.ENUM,
|
|
129
|
+
pos,
|
|
130
|
+
members,
|
|
131
|
+
fix,
|
|
132
|
+
};
|
|
78
133
|
}
|
|
79
134
|
}
|
|
80
135
|
});
|
|
@@ -4,7 +4,7 @@ import { stripQuotes } from '../../ast-helpers.js';
|
|
|
4
4
|
import { isJS } from '../helpers.js';
|
|
5
5
|
import { exportVisitor as visit } from '../index.js';
|
|
6
6
|
const isModuleExportsAccess = (node) => ts.isIdentifier(node.expression) && node.expression.escapedText === 'module' && node.name.escapedText === 'exports';
|
|
7
|
-
export default visit(isJS, node => {
|
|
7
|
+
export default visit(isJS, (node, { isFixExports }) => {
|
|
8
8
|
if (ts.isExpressionStatement(node)) {
|
|
9
9
|
if (ts.isBinaryExpression(node.expression)) {
|
|
10
10
|
if (ts.isPropertyAccessExpression(node.expression.left)) {
|
|
@@ -12,17 +12,25 @@ export default visit(isJS, node => {
|
|
|
12
12
|
isModuleExportsAccess(node.expression.left.expression)) {
|
|
13
13
|
const identifier = node.expression.left.name.getText();
|
|
14
14
|
const pos = node.expression.left.name.pos;
|
|
15
|
-
|
|
15
|
+
const fix = isFixExports ? [node.getStart(), node.getEnd()] : [];
|
|
16
|
+
return {
|
|
17
|
+
node: node.expression.left.name,
|
|
18
|
+
identifier,
|
|
19
|
+
type: SymbolType.UNKNOWN,
|
|
20
|
+
pos,
|
|
21
|
+
fix,
|
|
22
|
+
};
|
|
16
23
|
}
|
|
17
24
|
else if (isModuleExportsAccess(node.expression.left)) {
|
|
18
25
|
const expr = node.expression.right;
|
|
19
26
|
if (ts.isObjectLiteralExpression(expr) && expr.properties.every(ts.isShorthandPropertyAssignment)) {
|
|
20
27
|
return expr.properties.map(node => {
|
|
21
|
-
|
|
28
|
+
const fix = isFixExports ? [node.getStart(), node.getEnd()] : [];
|
|
29
|
+
return { node, identifier: node.getText(), type: SymbolType.UNKNOWN, pos: node.pos, fix };
|
|
22
30
|
});
|
|
23
31
|
}
|
|
24
32
|
else {
|
|
25
|
-
return { node, identifier: 'default', type: SymbolType.UNKNOWN, pos: expr.pos };
|
|
33
|
+
return { node, identifier: 'default', type: SymbolType.UNKNOWN, pos: expr.pos, fix: [] };
|
|
26
34
|
}
|
|
27
35
|
}
|
|
28
36
|
}
|
|
@@ -32,7 +40,14 @@ export default visit(isJS, node => {
|
|
|
32
40
|
isModuleExportsAccess(node.expression.left.expression)) {
|
|
33
41
|
const identifier = stripQuotes(node.expression.left.argumentExpression.getText());
|
|
34
42
|
const pos = node.expression.left.argumentExpression.pos;
|
|
35
|
-
|
|
43
|
+
const fix = isFixExports ? [node.getStart(), node.getEnd()] : [];
|
|
44
|
+
return {
|
|
45
|
+
node: node.expression.left.argumentExpression,
|
|
46
|
+
identifier,
|
|
47
|
+
type: SymbolType.UNKNOWN,
|
|
48
|
+
pos,
|
|
49
|
+
fix,
|
|
50
|
+
};
|
|
36
51
|
}
|
|
37
52
|
}
|
|
38
53
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolated workspaces in monorepo\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --performance Measure count and running time of expensive functions and display stats table\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n\nWebsite: https://knip.dev";
|
|
1
|
+
export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --fix Fix issues\n --fix-type Fix only issues of type, can be comma-separated or repeated (2)\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolated workspaces in monorepo\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --performance Measure count and running time of expensive functions and display stats table\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n(2) Fixable issue types: dependencies, exports, types\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n\nWebsite: https://knip.dev";
|
|
2
2
|
declare const _default: {
|
|
3
3
|
config: string | undefined;
|
|
4
4
|
debug: boolean | undefined;
|
|
@@ -6,6 +6,8 @@ declare const _default: {
|
|
|
6
6
|
directory: string | undefined;
|
|
7
7
|
exclude: string[] | undefined;
|
|
8
8
|
exports: boolean | undefined;
|
|
9
|
+
fix: boolean | undefined;
|
|
10
|
+
'fix-type': string[] | undefined;
|
|
9
11
|
help: boolean | undefined;
|
|
10
12
|
'ignore-internal': boolean | undefined;
|
|
11
13
|
include: string[] | undefined;
|
|
@@ -15,6 +15,8 @@ Options:
|
|
|
15
15
|
--exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)
|
|
16
16
|
--dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved
|
|
17
17
|
--exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates
|
|
18
|
+
--fix Fix issues
|
|
19
|
+
--fix-type Fix only issues of type, can be comma-separated or repeated (2)
|
|
18
20
|
--include-entry-exports Include entry files when reporting unused exports
|
|
19
21
|
--isolate-workspaces Isolated workspaces in monorepo
|
|
20
22
|
-n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)
|
|
@@ -31,6 +33,7 @@ Options:
|
|
|
31
33
|
-V, --version Print version
|
|
32
34
|
|
|
33
35
|
(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates
|
|
36
|
+
(2) Fixable issue types: dependencies, exports, types
|
|
34
37
|
|
|
35
38
|
Examples:
|
|
36
39
|
|
|
@@ -51,6 +54,8 @@ try {
|
|
|
51
54
|
directory: { type: 'string' },
|
|
52
55
|
exclude: { type: 'string', multiple: true },
|
|
53
56
|
exports: { type: 'boolean' },
|
|
57
|
+
fix: { type: 'boolean' },
|
|
58
|
+
'fix-type': { type: 'string', multiple: true },
|
|
54
59
|
help: { type: 'boolean', short: 'h' },
|
|
55
60
|
'ignore-internal': { type: 'boolean' },
|
|
56
61
|
include: { type: 'string', multiple: true },
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "3.
|
|
1
|
+
export declare const version = "3.7.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '3.
|
|
1
|
+
export const version = '3.7.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
|
|
5
5
|
"homepage": "https://knip.dev",
|
|
6
6
|
"repository": {
|
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
"name": "Lars Kappert",
|
|
15
15
|
"email": "lars@webpro.nl"
|
|
16
16
|
},
|
|
17
|
+
"funding": [
|
|
18
|
+
{
|
|
19
|
+
"type": "github",
|
|
20
|
+
"url": "https://github.com/sponsors/webpro"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "opencollective",
|
|
24
|
+
"url": "https://opencollective.com/webpro"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
17
27
|
"main": "./dist/index.js",
|
|
18
28
|
"bin": {
|
|
19
29
|
"knip": "./bin/knip.js"
|
|
@@ -45,6 +55,7 @@
|
|
|
45
55
|
"dependencies": {
|
|
46
56
|
"@ericcornelissen/bash-parser": "0.5.2",
|
|
47
57
|
"@npmcli/map-workspaces": "3.0.4",
|
|
58
|
+
"@npmcli/package-json": "5.0.0",
|
|
48
59
|
"@pkgjs/parseargs": "0.11.0",
|
|
49
60
|
"@pnpm/logger": "5.0.0",
|
|
50
61
|
"@pnpm/workspace.pkgs-graph": "^2.0.11",
|
|
@@ -70,7 +81,6 @@
|
|
|
70
81
|
"devDependencies": {
|
|
71
82
|
"@jest/types": "29.6.3",
|
|
72
83
|
"@knip/eslint-config": "0.0.0",
|
|
73
|
-
"@npmcli/package-json": "5.0.0",
|
|
74
84
|
"@release-it/bumper": "^6.0.1",
|
|
75
85
|
"@swc/cli": "^0.1.63",
|
|
76
86
|
"@swc/core": "^1.3.100",
|
package/schema.json
CHANGED
|
@@ -96,17 +96,17 @@
|
|
|
96
96
|
"rules": {
|
|
97
97
|
"type": "object",
|
|
98
98
|
"properties": {
|
|
99
|
-
"
|
|
99
|
+
"classMembers": { "$ref": "#/definitions/ruleValue" },
|
|
100
100
|
"dependencies": { "$ref": "#/definitions/ruleValue" },
|
|
101
|
-
"
|
|
102
|
-
"
|
|
101
|
+
"duplicates": { "$ref": "#/definitions/ruleValue" },
|
|
102
|
+
"enumMembers": { "$ref": "#/definitions/ruleValue" },
|
|
103
103
|
"exports": { "$ref": "#/definitions/ruleValue" },
|
|
104
|
+
"files": { "$ref": "#/definitions/ruleValue" },
|
|
104
105
|
"nsExports": { "$ref": "#/definitions/ruleValue" },
|
|
105
|
-
"classMembers": { "$ref": "#/definitions/ruleValue" },
|
|
106
|
-
"types": { "$ref": "#/definitions/ruleValue" },
|
|
107
106
|
"nsTypes": { "$ref": "#/definitions/ruleValue" },
|
|
108
|
-
"
|
|
109
|
-
"
|
|
107
|
+
"types": { "$ref": "#/definitions/ruleValue" },
|
|
108
|
+
"unlisted": { "$ref": "#/definitions/ruleValue" },
|
|
109
|
+
"unresolved": { "$ref": "#/definitions/ruleValue" }
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
},
|
|
@@ -123,16 +123,18 @@
|
|
|
123
123
|
"items": {
|
|
124
124
|
"type": "string",
|
|
125
125
|
"enum": [
|
|
126
|
-
"
|
|
126
|
+
"binaries",
|
|
127
|
+
"classMembers",
|
|
127
128
|
"dependencies",
|
|
128
|
-
"
|
|
129
|
+
"duplicates",
|
|
130
|
+
"enumMembers",
|
|
129
131
|
"exports",
|
|
132
|
+
"files",
|
|
130
133
|
"nsExports",
|
|
131
|
-
"classMembers",
|
|
132
|
-
"types",
|
|
133
134
|
"nsTypes",
|
|
134
|
-
"
|
|
135
|
-
"
|
|
135
|
+
"types",
|
|
136
|
+
"unlisted",
|
|
137
|
+
"unresolved"
|
|
136
138
|
]
|
|
137
139
|
}
|
|
138
140
|
},
|