knip 3.2.0 → 3.3.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/ProjectPrincipal.js +2 -1
- package/dist/plugins/vitest/index.js +6 -4
- package/dist/plugins/vitest/types.d.ts +8 -1
- package/dist/types/exports.d.ts +1 -0
- package/dist/typescript/SourceFile.d.ts +1 -0
- package/dist/typescript/ast-helpers.d.ts +0 -7
- package/dist/typescript/ast-helpers.js +0 -3
- package/dist/typescript/getImportsAndExports.js +2 -2
- package/dist/typescript/visitors/exports/exportDeclaration.js +10 -2
- package/dist/typescript/visitors/imports/jsDocType.js +37 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -4
- package/schema-jsonc.json +11 -0
- package/schema.json +1 -1
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -172,7 +172,8 @@ export class ProjectPrincipal {
|
|
|
172
172
|
}
|
|
173
173
|
getHasReferences(filePath, exportedItem) {
|
|
174
174
|
const hasReferences = { external: false, internal: false };
|
|
175
|
-
const
|
|
175
|
+
const pos = exportedItem.posDecl ?? exportedItem.pos;
|
|
176
|
+
const symbolReferences = this.findReferences(filePath, pos).flatMap(f => f.references);
|
|
176
177
|
for (const reference of symbolReferences) {
|
|
177
178
|
if (reference.fileName === filePath) {
|
|
178
179
|
if (!reference.isDefinition) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { compact } from '../../util/array.js';
|
|
2
|
-
import { dirname, join, relative } from '../../util/path.js';
|
|
2
|
+
import { dirname, isAbsolute, join, relative } from '../../util/path.js';
|
|
3
3
|
import { timerify } from '../../util/Performance.js';
|
|
4
4
|
import { hasDependency, load, tryResolve } from '../../util/plugin.js';
|
|
5
5
|
import { toEntryPattern } from '../../util/protocols.js';
|
|
@@ -14,7 +14,7 @@ export const CONFIG_FILE_PATTERNS = [
|
|
|
14
14
|
export const ENTRY_FILE_PATTERNS = ['**/*.{test,spec}.?(c|m)[jt]s?(x)'];
|
|
15
15
|
const resolveEntry = (containingFilePath, specifier) => {
|
|
16
16
|
const dir = dirname(containingFilePath);
|
|
17
|
-
const resolvedPath = tryResolve(join(dir, specifier), containingFilePath);
|
|
17
|
+
const resolvedPath = isAbsolute(specifier) ? specifier : tryResolve(join(dir, specifier), containingFilePath);
|
|
18
18
|
if (resolvedPath)
|
|
19
19
|
return toEntryPattern(relative(dir, resolvedPath));
|
|
20
20
|
return specifier;
|
|
@@ -47,9 +47,11 @@ export const findVitestDependencies = async (configFilePath, localConfig, option
|
|
|
47
47
|
}
|
|
48
48
|
return Array.from(dependencies);
|
|
49
49
|
}
|
|
50
|
+
const entry = localConfig.build?.lib?.entry ?? [];
|
|
51
|
+
const dependencies = (typeof entry === 'string' ? [entry] : Object.values(entry)).map(specifier => resolveEntry(configFilePath, specifier));
|
|
50
52
|
if (!localConfig.test)
|
|
51
|
-
return
|
|
52
|
-
return findConfigDependencies(configFilePath, localConfig, options);
|
|
53
|
+
return dependencies;
|
|
54
|
+
return [...dependencies, ...findConfigDependencies(configFilePath, localConfig, options)];
|
|
53
55
|
};
|
|
54
56
|
const findVitestWorkspaceDependencies = async (configFilePath, options) => {
|
|
55
57
|
const localConfig = await load(configFilePath);
|
|
@@ -12,7 +12,14 @@ interface VitestConfig {
|
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
export interface ViteConfig extends VitestConfig {
|
|
15
|
-
plugins
|
|
15
|
+
plugins?: unknown[];
|
|
16
|
+
build?: {
|
|
17
|
+
lib?: {
|
|
18
|
+
entry: string | string[] | {
|
|
19
|
+
[entryAlias: string]: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
};
|
|
16
23
|
}
|
|
17
24
|
export type COMMAND = 'dev' | 'serve' | 'build';
|
|
18
25
|
export type MODE = 'development' | 'production';
|
package/dist/types/exports.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface BoundSourceFile extends ts.SourceFile {
|
|
|
12
12
|
symbol?: SymbolWithExports;
|
|
13
13
|
resolvedModules?: ts.ModeAwareCache<ts.ResolvedModuleWithFailedLookupLocations>;
|
|
14
14
|
locals?: SymbolTable;
|
|
15
|
+
getNamedDeclarations?(): Map<string, readonly ts.Declaration[]>;
|
|
15
16
|
scriptKind?: ts.ScriptKind;
|
|
16
17
|
pragmas?: Map<string, PragmaMap | PragmaMap[]>;
|
|
17
18
|
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
interface ValidImportTypeNode extends ts.ImportTypeNode {
|
|
3
|
-
argument: ts.LiteralTypeNode & {
|
|
4
|
-
literal: ts.StringLiteral;
|
|
5
|
-
};
|
|
6
|
-
}
|
|
7
|
-
export declare function isValidImportTypeNode(node: ts.Node): node is ValidImportTypeNode;
|
|
8
2
|
export declare function isGetOrSetAccessorDeclaration(node: ts.Node): node is ts.AccessorDeclaration;
|
|
9
3
|
export declare function isPrivateMember(node: ts.MethodDeclaration | ts.PropertyDeclaration | ts.SetAccessorDeclaration | ts.GetAccessorDeclaration): boolean;
|
|
10
4
|
export declare function isDefaultImport(node: ts.ImportDeclaration | ts.ImportEqualsDeclaration | ts.ExportDeclaration): boolean;
|
|
@@ -24,4 +18,3 @@ export declare const getLineAndCharacterOfPosition: (node: ts.Node, pos: number)
|
|
|
24
18
|
col: number;
|
|
25
19
|
pos: number;
|
|
26
20
|
};
|
|
27
|
-
export {};
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
export function isValidImportTypeNode(node) {
|
|
3
|
-
return ts.isImportTypeNode(node);
|
|
4
|
-
}
|
|
5
2
|
export function isGetOrSetAccessorDeclaration(node) {
|
|
6
3
|
return node.kind === ts.SyntaxKind.SetAccessor || node.kind === ts.SyntaxKind.GetAccessor;
|
|
7
4
|
}
|
|
@@ -93,7 +93,7 @@ export const getImportsAndExports = (sourceFile, getResolvedModule, options) =>
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
|
-
const addExport = ({ node, identifier, type, pos, members = [] }) => {
|
|
96
|
+
const addExport = ({ node, identifier, type, pos, posDecl, members = [] }) => {
|
|
97
97
|
if (options.skipExports)
|
|
98
98
|
return;
|
|
99
99
|
const jsDocTags = getJSDocTags(node);
|
|
@@ -104,7 +104,7 @@ export const getImportsAndExports = (sourceFile, getResolvedModule, options) =>
|
|
|
104
104
|
exports.set(identifier, { ...item, members: crew, jsDocTags: tags });
|
|
105
105
|
}
|
|
106
106
|
else {
|
|
107
|
-
exports.set(identifier, { node, type, members, jsDocTags, pos });
|
|
107
|
+
exports.set(identifier, { node, type, members, jsDocTags, pos, posDecl: posDecl ?? pos });
|
|
108
108
|
}
|
|
109
109
|
if (!jsDocTags.has('@alias')) {
|
|
110
110
|
if (ts.isExportAssignment(node))
|
|
@@ -5,12 +5,20 @@ export default visit(() => true, node => {
|
|
|
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;
|
|
8
|
+
const sourceFile = node.getSourceFile();
|
|
9
|
+
const declarations = sourceFile.getNamedDeclarations?.();
|
|
8
10
|
return node.exportClause.elements.map(element => {
|
|
11
|
+
const identifier = String(element.name.escapedText);
|
|
12
|
+
const declaration = declarations?.get(identifier)?.find((d) => d !== element);
|
|
13
|
+
const pos = element.name.pos;
|
|
14
|
+
const name = ts.getNameOfDeclaration(declaration);
|
|
15
|
+
const posDecl = name?.pos ?? declaration?.pos ?? pos;
|
|
9
16
|
return {
|
|
10
17
|
node: element,
|
|
11
|
-
identifier
|
|
18
|
+
identifier,
|
|
12
19
|
type,
|
|
13
|
-
pos
|
|
20
|
+
pos,
|
|
21
|
+
posDecl,
|
|
14
22
|
};
|
|
15
23
|
});
|
|
16
24
|
}
|
|
@@ -1,11 +1,43 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { isValidImportTypeNode } from '../../ast-helpers.js';
|
|
3
2
|
import { importVisitor as visit } from '../index.js';
|
|
3
|
+
const extractImportSpecifiers = (node) => {
|
|
4
|
+
const importSpecifiers = [];
|
|
5
|
+
function visit(node) {
|
|
6
|
+
if (ts.isJSDocTypeExpression(node)) {
|
|
7
|
+
const typeNode = node.type;
|
|
8
|
+
if (ts.isTypeReferenceNode(typeNode) && typeNode.typeArguments) {
|
|
9
|
+
typeNode.typeArguments.forEach(arg => {
|
|
10
|
+
if (ts.isImportTypeNode(arg)) {
|
|
11
|
+
const importClause = arg.argument;
|
|
12
|
+
if (ts.isLiteralTypeNode(importClause) && ts.isStringLiteral(importClause.literal)) {
|
|
13
|
+
importSpecifiers.push(importClause.literal.text);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (ts.isJSDocTypeTag(node)) {
|
|
20
|
+
const typeNode = node.typeExpression?.type;
|
|
21
|
+
if (ts.isImportTypeNode(typeNode)) {
|
|
22
|
+
const importClause = typeNode.argument;
|
|
23
|
+
if (ts.isLiteralTypeNode(importClause) && ts.isStringLiteral(importClause.literal)) {
|
|
24
|
+
importSpecifiers.push(importClause.literal.text);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
ts.forEachChild(node, visit);
|
|
29
|
+
}
|
|
30
|
+
visit(node);
|
|
31
|
+
return importSpecifiers;
|
|
32
|
+
};
|
|
4
33
|
export default visit(() => true, node => {
|
|
5
|
-
if ('jsDoc' in node) {
|
|
6
|
-
const
|
|
7
|
-
if (
|
|
8
|
-
return
|
|
34
|
+
if ('jsDoc' in node && node.jsDoc) {
|
|
35
|
+
const jsDoc = node.jsDoc;
|
|
36
|
+
if (jsDoc.length > 0 && jsDoc[0].parent.parent === node.parent) {
|
|
37
|
+
return jsDoc
|
|
38
|
+
.flatMap(jsDoc => (jsDoc.tags ?? []).flatMap(extractImportSpecifiers))
|
|
39
|
+
.map(specifier => ({ specifier }));
|
|
9
40
|
}
|
|
10
41
|
}
|
|
42
|
+
return [];
|
|
11
43
|
});
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "3.
|
|
1
|
+
export declare const version = "3.3.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '3.
|
|
1
|
+
export const version = '3.3.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.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": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"knip:production": "node ./dist/cli.js --directory ../.. --production --strict",
|
|
26
26
|
"lint": "eslint scripts src test",
|
|
27
27
|
"lint:fix": "eslint scripts src test --fix",
|
|
28
|
-
"format": "prettier scripts src test schema.json --with-node-modules --write",
|
|
28
|
+
"format": "prettier scripts src test schema.json schema-jsonc.json --with-node-modules --write",
|
|
29
29
|
"pretest": "node rmdir.js tmp && swc src -d tmp/src && swc test -d tmp/test",
|
|
30
30
|
"test": "node --no-warnings --test tmp",
|
|
31
31
|
"coverage": "c8 --reporter html node --no-warnings --loader tsx --test test/*.test.ts test/*/*.test.ts",
|
|
@@ -35,11 +35,12 @@
|
|
|
35
35
|
"qa": "npm run lint && npm run build && npm run knip && npm run knip:production && npm test",
|
|
36
36
|
"release": "release-it",
|
|
37
37
|
"create-plugin": "tsx --no-warnings ./scripts/create-new-plugin.ts",
|
|
38
|
-
"postcreate-plugin": "prettier schema.json src/ConfigurationValidator.ts --write --config .prettierrc --log-level silent"
|
|
38
|
+
"postcreate-plugin": "prettier schema.json schema-jsonc.json src/ConfigurationValidator.ts --write --config .prettierrc --log-level silent"
|
|
39
39
|
},
|
|
40
40
|
"files": [
|
|
41
41
|
"dist",
|
|
42
|
-
"schema.json"
|
|
42
|
+
"schema.json",
|
|
43
|
+
"schema-jsonc.json"
|
|
43
44
|
],
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"@ericcornelissen/bash-parser": "0.5.2",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Knip configuration for JSONC",
|
|
4
|
+
"description": "See https://github.com/webpro/knip",
|
|
5
|
+
"allOf": [
|
|
6
|
+
{
|
|
7
|
+
"$ref": "https://unpkg.com/knip@3/schema.json"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"allowTrailingCommas": true
|
|
11
|
+
}
|