knip 5.23.0 → 5.23.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/dist/index.js +12 -10
- package/dist/plugins/commitlint/index.js +2 -7
- package/dist/plugins/graphql-codegen/index.js +1 -1
- package/dist/plugins/lint-staged/index.js +5 -6
- package/dist/plugins/linthtml/index.js +2 -9
- package/dist/plugins/lockfile-lint/index.js +2 -2
- package/dist/plugins/npm-package-json-lint/index.js +2 -2
- package/dist/plugins/postcss/index.js +6 -2
- package/dist/plugins/prettier/index.js +2 -2
- package/dist/plugins/release-it/index.js +1 -1
- package/dist/plugins/semantic-release/index.js +2 -2
- package/dist/plugins/size-limit/index.js +5 -2
- package/dist/plugins/stylelint/index.js +2 -2
- package/dist/plugins/syncpack/index.d.ts +1 -0
- package/dist/plugins/syncpack/index.js +5 -2
- package/dist/plugins/tsup/index.js +1 -1
- package/dist/plugins/typedoc/index.js +4 -4
- package/dist/plugins/unocss/index.js +2 -2
- package/dist/plugins/xo/index.js +2 -2
- package/dist/typescript/ast-helpers.d.ts +3 -1
- package/dist/typescript/ast-helpers.js +15 -5
- package/dist/typescript/getImportsAndExports.js +16 -7
- package/dist/typescript/visitors/exports/exportKeyword.js +26 -62
- package/dist/util/get-included-issue-types.js +1 -1
- package/dist/util/plugin.d.ts +26 -2
- package/dist/util/plugin.js +34 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -317,8 +317,17 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
317
317
|
if (shouldIgnore(exportedItem.jsDocTags))
|
|
318
318
|
continue;
|
|
319
319
|
const isIgnored = shouldIgnoreTags(exportedItem.jsDocTags);
|
|
320
|
-
if (
|
|
320
|
+
if (importsForExport) {
|
|
321
321
|
const { isReferenced, reExportingEntryFile, traceNode } = isIdentifierReferenced(filePath, identifier, isIncludeEntryExports);
|
|
322
|
+
if ((isReferenced || exportedItem.refs[1]) && isIgnored) {
|
|
323
|
+
for (const tagName of exportedItem.jsDocTags) {
|
|
324
|
+
if (tags[1].includes(tagName.replace(/^\@/, ''))) {
|
|
325
|
+
collector.addTagHint({ type: 'tag', filePath, identifier, tagName });
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (isIgnored)
|
|
330
|
+
continue;
|
|
322
331
|
if (reExportingEntryFile) {
|
|
323
332
|
if (!isIncludeEntryExports) {
|
|
324
333
|
createAndPrintTrace(filePath, { identifier, isEntry, hasRef: isReferenced });
|
|
@@ -339,7 +348,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
339
348
|
continue;
|
|
340
349
|
if (member.refs[0] === 0) {
|
|
341
350
|
const id = `${identifier}.${member.identifier}`;
|
|
342
|
-
const { isReferenced } = isIdentifierReferenced(filePath, id);
|
|
351
|
+
const { isReferenced } = isIdentifierReferenced(filePath, id, true);
|
|
343
352
|
const isIgnored = shouldIgnoreTags(member.jsDocTags);
|
|
344
353
|
if (!isReferenced) {
|
|
345
354
|
if (isIgnored)
|
|
@@ -413,20 +422,13 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
413
422
|
line: exportedItem.line,
|
|
414
423
|
col: exportedItem.col,
|
|
415
424
|
});
|
|
416
|
-
if (isIssueAdded) {
|
|
425
|
+
if (isFix && isIssueAdded) {
|
|
417
426
|
if (isType)
|
|
418
427
|
fixer.addUnusedTypeNode(filePath, exportedItem.fixes);
|
|
419
428
|
else
|
|
420
429
|
fixer.addUnusedExportNode(filePath, exportedItem.fixes);
|
|
421
430
|
}
|
|
422
431
|
}
|
|
423
|
-
else if (isIgnored) {
|
|
424
|
-
for (const tagName of exportedItem.jsDocTags) {
|
|
425
|
-
if (tags[1].includes(tagName.replace(/^\@/, ''))) {
|
|
426
|
-
collector.addTagHint({ type: 'tag', filePath, identifier, tagName });
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
432
|
}
|
|
431
433
|
}
|
|
432
434
|
}
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { hasDependency, toCosmiconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'commitlint';
|
|
3
3
|
const enablers = ['@commitlint/cli'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
|
-
const config = [
|
|
6
|
-
'.commitlintrc',
|
|
7
|
-
'.commitlintrc.{json,yaml,yml,js,cjs,ts,cts}',
|
|
8
|
-
'commitlint.config.{js,cjs,ts,cts}',
|
|
9
|
-
'package.json',
|
|
10
|
-
];
|
|
5
|
+
const config = ['package.json', 'package.yaml', ...toCosmiconfig('commitlint', { additionalExtensions: ['cts'] })];
|
|
11
6
|
const resolveConfig = async (config) => {
|
|
12
7
|
const extendsConfigs = config.extends
|
|
13
8
|
? [config.extends]
|
|
@@ -9,7 +9,7 @@ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
|
9
9
|
const packageJsonPath = manifest => get(manifest, 'codegen') ?? get(manifest, 'graphql');
|
|
10
10
|
const config = [
|
|
11
11
|
'package.json',
|
|
12
|
-
'codegen.{json,yml,yaml,js,ts
|
|
12
|
+
'codegen.{json,yml,yaml,js,ts}',
|
|
13
13
|
'.codegenrc.{json,yml,yaml,js,ts}',
|
|
14
14
|
'codegen.config.js',
|
|
15
15
|
'.graphqlrc',
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { getDependenciesFromScripts, hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { getDependenciesFromScripts, hasDependency, toLilconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'lint-staged';
|
|
3
3
|
const enablers = ['lint-staged'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
5
|
const packageJsonPath = 'lint-staged';
|
|
6
6
|
const config = [
|
|
7
|
-
'.lintstagedrc',
|
|
8
|
-
'.lintstagedrc.json',
|
|
9
|
-
'.lintstagedrc.{yml,yaml}',
|
|
10
|
-
'.lintstagedrc.{js,mjs,cjs}',
|
|
11
|
-
'lint-staged.config.{js,mjs,cjs}',
|
|
12
7
|
'package.json',
|
|
8
|
+
'package.yaml',
|
|
9
|
+
'package.yml',
|
|
10
|
+
...toLilconfig('lint-staged'),
|
|
11
|
+
...toLilconfig('lintstaged'),
|
|
13
12
|
];
|
|
14
13
|
const resolveConfig = async (config, options) => {
|
|
15
14
|
if (typeof config === 'function')
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { isInternal } from '#p/util/path.js';
|
|
2
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
2
|
+
import { hasDependency, toCosmiconfig } from '#p/util/plugin.js';
|
|
3
3
|
import { toEntryPattern } from '#p/util/protocols.js';
|
|
4
4
|
const title = 'LintHTML';
|
|
5
5
|
const packageJsonPath = 'linthtmlConfig';
|
|
6
6
|
const enablers = ['@linthtml/linthtml'];
|
|
7
7
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
8
|
-
const config = [
|
|
9
|
-
'.linthtmlrc',
|
|
10
|
-
'.linthtmlrc.json',
|
|
11
|
-
'.linthtmlrc.yml',
|
|
12
|
-
'.linthtmlrc.{js,cjs}',
|
|
13
|
-
'linthtml.config.js',
|
|
14
|
-
'package.json',
|
|
15
|
-
];
|
|
8
|
+
const config = ['package.json', ...toCosmiconfig('linthtml')];
|
|
16
9
|
const resolveConfig = config => {
|
|
17
10
|
const extensions = [config.extends ?? []]
|
|
18
11
|
.flat()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { hasDependency, toCosmiconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'lockfile-lint';
|
|
3
3
|
const enablers = ['lockfile-lint'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
|
-
const config = ['.
|
|
5
|
+
const config = ['package.json', ...toCosmiconfig('lockfile-lint', { additionalExtensions: ['toml'] })];
|
|
6
6
|
export default {
|
|
7
7
|
title,
|
|
8
8
|
enablers,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { hasDependency, toCosmiconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'npm-package-json-lint';
|
|
3
3
|
const enablers = ['npm-package-json-lint'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
5
|
const packageJsonPath = 'npmpackagejsonlint';
|
|
6
|
-
const config = ['.
|
|
6
|
+
const config = ['package.json', ...toCosmiconfig('npmpackagejsonlint')];
|
|
7
7
|
const resolveConfig = localConfig => {
|
|
8
8
|
return localConfig?.extends ? [localConfig.extends] : [];
|
|
9
9
|
};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { hasDependency, toLilconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'PostCSS';
|
|
3
3
|
const enablers = ['postcss', 'postcss-cli', 'next'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
|
-
const config = [
|
|
5
|
+
const config = [
|
|
6
|
+
'package.json',
|
|
7
|
+
'postcss.config.json',
|
|
8
|
+
...toLilconfig('postcss', { configDir: false, additionalExtensions: ['ts', 'mts', 'cts', 'yaml', 'yml'] }),
|
|
9
|
+
];
|
|
6
10
|
const resolveConfig = config => {
|
|
7
11
|
return config.plugins
|
|
8
12
|
? (Array.isArray(config.plugins) ? config.plugins : Object.keys(config.plugins)).flatMap(plugin => {
|
|
@@ -4,9 +4,9 @@ const enablers = ['prettier'];
|
|
|
4
4
|
const isEnabled = ({ dependencies, config }) => hasDependency(dependencies, enablers) || 'prettier' in config;
|
|
5
5
|
const config = [
|
|
6
6
|
'.prettierrc',
|
|
7
|
-
'.prettierrc.{json,js,cjs,mjs,yml,yaml}',
|
|
7
|
+
'.prettierrc.{json,js,cjs,mjs,yml,yaml,toml,json5}',
|
|
8
8
|
'prettier.config.{js,cjs,mjs}',
|
|
9
|
-
'package.json',
|
|
9
|
+
'package.{json,yaml}',
|
|
10
10
|
];
|
|
11
11
|
const resolveConfig = config => {
|
|
12
12
|
if (typeof config === 'string') {
|
|
@@ -3,7 +3,7 @@ const title = 'Release It';
|
|
|
3
3
|
const enablers = ['release-it'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
5
|
const packageJsonPath = 'release-it';
|
|
6
|
-
const config = ['.release-it.json
|
|
6
|
+
const config = ['.release-it.{json,js,cjs,ts,yml,yaml,toml}', 'package.json'];
|
|
7
7
|
const resolveConfig = (config, options) => {
|
|
8
8
|
const plugins = config.plugins ? Object.keys(config.plugins) : [];
|
|
9
9
|
const scripts = config.hooks ? Object.values(config.hooks).flat() : [];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { hasDependency, toCosmiconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'Semantic Release';
|
|
3
3
|
const enablers = ['semantic-release'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
5
|
const packageJsonPath = 'release';
|
|
6
|
-
const config = ['.
|
|
6
|
+
const config = ['package.json', ...toCosmiconfig('release')];
|
|
7
7
|
const resolveConfig = config => {
|
|
8
8
|
const plugins = (config?.plugins ?? []).map(plugin => (Array.isArray(plugin) ? plugin[0] : plugin));
|
|
9
9
|
return plugins;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { hasDependency, toLilconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'size-limit';
|
|
3
3
|
const enablers = ['size-limit'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
|
-
const config = [
|
|
5
|
+
const config = [
|
|
6
|
+
'package.json',
|
|
7
|
+
...toLilconfig('size-limit', { configDir: false, additionalExtensions: ['ts', 'mts', 'cts'], rcSuffix: '' }),
|
|
8
|
+
];
|
|
6
9
|
export default {
|
|
7
10
|
title,
|
|
8
11
|
enablers,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isInternal } from '#p/util/path.js';
|
|
2
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
2
|
+
import { hasDependency, toCosmiconfig } from '#p/util/plugin.js';
|
|
3
3
|
const title = 'Stylelint';
|
|
4
4
|
const enablers = ['stylelint'];
|
|
5
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
|
-
const config = ['.
|
|
6
|
+
const config = ['package.json', ...toCosmiconfig('stylelint')];
|
|
7
7
|
const resolve = (config) => {
|
|
8
8
|
const extend = config.extends ? [config.extends].flat().filter(id => !isInternal(id)) : [];
|
|
9
9
|
const plugins = config.plugins ? [config.plugins].flat().filter(id => !isInternal(id)) : [];
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { get } from '#p/util/object.js';
|
|
2
|
+
import { hasDependency, toCosmiconfig } from '#p/util/plugin.js';
|
|
2
3
|
const title = 'Syncpack';
|
|
3
4
|
const enablers = ['syncpack'];
|
|
4
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
|
-
const config = ['.
|
|
6
|
+
const config = ['package.json', ...toCosmiconfig('syncpack')];
|
|
7
|
+
const packageJsonPath = manifest => get(manifest, 'syncpack');
|
|
6
8
|
export default {
|
|
7
9
|
title,
|
|
8
10
|
enablers,
|
|
9
11
|
isEnabled,
|
|
10
12
|
config,
|
|
13
|
+
packageJsonPath,
|
|
11
14
|
};
|
|
@@ -3,7 +3,7 @@ import { toProductionEntryPattern } from '#p/util/protocols.js';
|
|
|
3
3
|
const title = 'tsup';
|
|
4
4
|
const enablers = ['tsup'];
|
|
5
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
|
-
const config = ['tsup.config.{js,ts,cjs,json}', 'package.json'];
|
|
6
|
+
const config = ['tsup.config.{js,ts,cjs,mjs,json}', 'package.json'];
|
|
7
7
|
const resolveConfig = async (config) => {
|
|
8
8
|
if (typeof config === 'function')
|
|
9
9
|
config = await config({});
|
|
@@ -4,10 +4,10 @@ const enablers = ['typedoc'];
|
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
5
|
const packageJsonPath = 'typedocOptions';
|
|
6
6
|
const config = [
|
|
7
|
-
'typedoc.{js,cjs,json,jsonc}',
|
|
8
|
-
'typedoc.config.{js,cjs}',
|
|
9
|
-
'.config/typedoc.{js,cjs,json,jsonc}',
|
|
10
|
-
'.config/typedoc.config.{js,cjs}',
|
|
7
|
+
'typedoc.{js,cjs,mjs,json,jsonc}',
|
|
8
|
+
'typedoc.config.{js,cjs,mjs}',
|
|
9
|
+
'.config/typedoc.{js,cjs,mjs,json,jsonc}',
|
|
10
|
+
'.config/typedoc.config.{js,cjs,mjs}',
|
|
11
11
|
'package.json',
|
|
12
12
|
'tsconfig.json',
|
|
13
13
|
];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { hasDependency } from '#p/util/plugin.js';
|
|
1
|
+
import { hasDependency, toUnconfig } from '#p/util/plugin.js';
|
|
2
2
|
const title = 'UnoCSS';
|
|
3
3
|
const enablers = ['unocss'];
|
|
4
4
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
5
|
-
const config = ['uno.config
|
|
5
|
+
const config = [...toUnconfig('uno.config'), ...toUnconfig('unocss.config')];
|
|
6
6
|
export default {
|
|
7
7
|
title,
|
|
8
8
|
enablers,
|
package/dist/plugins/xo/index.js
CHANGED
|
@@ -4,8 +4,8 @@ const title = 'xo';
|
|
|
4
4
|
const enablers = ['xo'];
|
|
5
5
|
const isEnabled = ({ dependencies, config }) => hasDependency(dependencies, enablers) || 'xo' in config;
|
|
6
6
|
const packageJsonPath = 'xo';
|
|
7
|
-
const config = ['
|
|
8
|
-
const entry = ['{
|
|
7
|
+
const config = ['package.json', '.xo-config', '.xo-config.{js,cjs,json}', 'xo.config.{js,cjs}'];
|
|
8
|
+
const entry = ['.xo-config.{js,cjs}', 'xo.config.{js,cjs}'];
|
|
9
9
|
const resolveConfig = async (config, options) => {
|
|
10
10
|
const dependencies = await getDependenciesDeep(config, options);
|
|
11
11
|
return [...dependencies];
|
|
@@ -23,4 +23,6 @@ export declare const isConsiderReferencedNS: (node: ts.Identifier) => boolean;
|
|
|
23
23
|
export declare const isTopLevel: (node: ts.Node) => boolean;
|
|
24
24
|
export declare const getTypeName: (node: ts.Identifier) => ts.QualifiedName | undefined;
|
|
25
25
|
export declare const isImportSpecifier: (node: ts.Node) => boolean;
|
|
26
|
-
export declare const isReferencedInExportedType: (node: ts.Node
|
|
26
|
+
export declare const isReferencedInExportedType: (node: ts.Node) => boolean;
|
|
27
|
+
export declare const getExportKeywordNode: (node: ts.Node) => ts.ExportKeyword | undefined;
|
|
28
|
+
export declare const getDefaultKeywordNode: (node: ts.Node) => ts.DefaultKeyword | undefined;
|
|
@@ -152,11 +152,21 @@ export const isImportSpecifier = (node) => ts.isImportSpecifier(node.parent) ||
|
|
|
152
152
|
ts.isImportClause(node.parent) ||
|
|
153
153
|
ts.isNamespaceImport(node.parent);
|
|
154
154
|
const isExported = (node) => {
|
|
155
|
-
if (node
|
|
155
|
+
if (getExportKeywordNode(node))
|
|
156
156
|
return true;
|
|
157
157
|
return node.parent ? isExported(node.parent) : false;
|
|
158
158
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
const isTypeDeclaration = (node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node);
|
|
160
|
+
const getAncestorTypeDeclaration = (node) => {
|
|
161
|
+
while (node) {
|
|
162
|
+
if (isTypeDeclaration(node))
|
|
163
|
+
return node;
|
|
164
|
+
node = node.parent;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
export const isReferencedInExportedType = (node) => {
|
|
168
|
+
const typeNode = getAncestorTypeDeclaration(node);
|
|
169
|
+
return Boolean(typeNode && isExported(typeNode));
|
|
170
|
+
};
|
|
171
|
+
export const getExportKeywordNode = (node) => node.modifiers?.find(mod => mod.kind === ts.SyntaxKind.ExportKeyword);
|
|
172
|
+
export const getDefaultKeywordNode = (node) => node.modifiers?.find(mod => mod.kind === ts.SyntaxKind.DefaultKeyword);
|
|
@@ -49,14 +49,14 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
49
49
|
const referencedSymbolsInExportedTypes = new Set();
|
|
50
50
|
const visitors = getVisitors(sourceFile);
|
|
51
51
|
const addInternalImport = (options) => {
|
|
52
|
-
const { identifier, symbol, filePath, namespace, specifier, isReExport } = options;
|
|
52
|
+
const { identifier, symbol, filePath, namespace, alias, specifier, isReExport } = options;
|
|
53
53
|
const isStar = identifier === IMPORT_STAR;
|
|
54
54
|
specifiers.add([specifier, filePath]);
|
|
55
55
|
const file = internalImports.get(filePath);
|
|
56
56
|
const imports = file ?? createImports();
|
|
57
57
|
if (!file)
|
|
58
58
|
internalImports.set(filePath, imports);
|
|
59
|
-
const nsOrAlias = symbol ? String(symbol.escapedName) :
|
|
59
|
+
const nsOrAlias = symbol ? String(symbol.escapedName) : alias;
|
|
60
60
|
if (isReExport) {
|
|
61
61
|
if (isStar && namespace) {
|
|
62
62
|
addValue(imports.reExportedNs, namespace, sourceFile.fileName);
|
|
@@ -224,7 +224,10 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
224
224
|
const result = visitor(node, options);
|
|
225
225
|
result && (Array.isArray(result) ? result.forEach(addImportWithNode) : addImportWithNode(result));
|
|
226
226
|
}
|
|
227
|
-
const isTopLevel = node.parent
|
|
227
|
+
const isTopLevel = node.parent &&
|
|
228
|
+
('commonJsModuleIndicator' in sourceFile
|
|
229
|
+
? node.parent.parent === sourceFile || node.parent === sourceFile
|
|
230
|
+
: node.parent === sourceFile);
|
|
228
231
|
if (isTopLevel) {
|
|
229
232
|
for (const visitor of visitors.import) {
|
|
230
233
|
const result = visitor(node, options);
|
|
@@ -285,7 +288,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
285
288
|
}
|
|
286
289
|
}
|
|
287
290
|
}
|
|
288
|
-
if (ignoreExportsUsedInFile && !isTopLevel && isReferencedInExportedType(node
|
|
291
|
+
if (ignoreExportsUsedInFile && !isTopLevel && isReferencedInExportedType(node)) {
|
|
289
292
|
referencedSymbolsInExportedTypes.add(symbol.exportSymbol);
|
|
290
293
|
}
|
|
291
294
|
}
|
|
@@ -308,14 +311,18 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
308
311
|
const setRefs = (item) => {
|
|
309
312
|
if (!item.symbol)
|
|
310
313
|
return;
|
|
314
|
+
if (item.symbol.flags & ts.SymbolFlags.AliasExcludes) {
|
|
315
|
+
item.refs = [1, false];
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
311
318
|
const symbols = new Set();
|
|
312
319
|
let index = 0;
|
|
313
320
|
const text = sourceFile.text;
|
|
314
321
|
const id = item.identifier;
|
|
315
322
|
while (index < text.length && (index = text.indexOf(id, index)) !== -1) {
|
|
316
323
|
if (!isIdChar(text.charAt(index - 1)) && !isIdChar(text.charAt(index + id.length))) {
|
|
317
|
-
const
|
|
318
|
-
if (!
|
|
324
|
+
const isExportDeclaration = index === item.pos || index === item.pos + 1;
|
|
325
|
+
if (!isExportDeclaration) {
|
|
319
326
|
const symbol = typeChecker.getSymbolAtLocation(ts.getTokenAtPosition(sourceFile, index));
|
|
320
327
|
if (symbol) {
|
|
321
328
|
const isInExportedType = referencedSymbolsInExportedTypes.has(symbol);
|
|
@@ -342,9 +349,11 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
342
349
|
index += id.length;
|
|
343
350
|
}
|
|
344
351
|
};
|
|
352
|
+
const isSetRefs = ignoreExportsUsedInFile;
|
|
345
353
|
for (const item of exports.values()) {
|
|
346
|
-
if (
|
|
354
|
+
if (isSetRefs === true || (typeof isSetRefs === 'object' && item.type !== 'unknown' && !!isSetRefs[item.type])) {
|
|
347
355
|
setRefs(item);
|
|
356
|
+
}
|
|
348
357
|
for (const member of item.members) {
|
|
349
358
|
setRefs(member);
|
|
350
359
|
member.symbol = undefined;
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { SymbolType } from '../../../types/issues.js';
|
|
3
3
|
import { compact } from '../../../util/array.js';
|
|
4
|
-
import { isGetOrSetAccessorDeclaration, isPrivateMember, stripQuotes } from '../../ast-helpers.js';
|
|
4
|
+
import { getDefaultKeywordNode, getExportKeywordNode, isGetOrSetAccessorDeclaration, isPrivateMember, stripQuotes, } from '../../ast-helpers.js';
|
|
5
5
|
import { exportVisitor as visit } from '../index.js';
|
|
6
6
|
export default visit(() => true, (node, { isFixExports, isFixTypes, isReportClassMembers }) => {
|
|
7
|
-
const exportKeyword = node
|
|
7
|
+
const exportKeyword = getExportKeywordNode(node);
|
|
8
8
|
if (exportKeyword) {
|
|
9
|
+
const getFix = (node, defaultKeyword) => isFixExports ? [node.getStart(), (defaultKeyword ?? node).getEnd() + 1] : undefined;
|
|
10
|
+
const getElementFix = (node) => (isFixExports ? [node.getStart(), node.getEnd()] : undefined);
|
|
11
|
+
const getTypeFix = (node) => (isFixTypes ? [node.getStart(), node.getEnd() + 1] : undefined);
|
|
9
12
|
if (ts.isVariableStatement(node)) {
|
|
10
13
|
return node.declarationList.declarations.flatMap(declaration => {
|
|
11
14
|
if (ts.isObjectBindingPattern(declaration.name)) {
|
|
12
15
|
return compact(declaration.name.elements.map(element => {
|
|
13
16
|
if (ts.isIdentifier(element.name)) {
|
|
14
|
-
const fix =
|
|
17
|
+
const fix = getElementFix(element);
|
|
15
18
|
return {
|
|
16
19
|
node: element,
|
|
17
20
|
identifier: element.name.escapedText.toString(),
|
|
@@ -25,7 +28,7 @@ export default visit(() => true, (node, { isFixExports, isFixTypes, isReportClas
|
|
|
25
28
|
if (ts.isArrayBindingPattern(declaration.name)) {
|
|
26
29
|
return compact(declaration.name.elements.map(element => {
|
|
27
30
|
if (ts.isBindingElement(element)) {
|
|
28
|
-
const fix =
|
|
31
|
+
const fix = getElementFix(element);
|
|
29
32
|
return {
|
|
30
33
|
node: element,
|
|
31
34
|
identifier: element.getText(),
|
|
@@ -37,34 +40,22 @@ export default visit(() => true, (node, { isFixExports, isFixTypes, isReportClas
|
|
|
37
40
|
}));
|
|
38
41
|
}
|
|
39
42
|
const identifier = declaration.name.getText();
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
identifier,
|
|
44
|
-
type: SymbolType.UNKNOWN,
|
|
45
|
-
pos: declaration.name.getStart(),
|
|
46
|
-
fix,
|
|
47
|
-
};
|
|
43
|
+
const pos = declaration.name.getStart();
|
|
44
|
+
const fix = getFix(exportKeyword);
|
|
45
|
+
return { node: declaration, identifier, type: SymbolType.UNKNOWN, pos, fix };
|
|
48
46
|
});
|
|
49
47
|
}
|
|
50
|
-
const defaultKeyword = node
|
|
48
|
+
const defaultKeyword = getDefaultKeywordNode(node);
|
|
51
49
|
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
52
50
|
const identifier = defaultKeyword ? 'default' : node.name.getText();
|
|
53
51
|
const pos = (node.name ?? node.body ?? node).getStart();
|
|
54
|
-
const fix =
|
|
55
|
-
|
|
56
|
-
: undefined;
|
|
57
|
-
return {
|
|
58
|
-
node,
|
|
59
|
-
identifier,
|
|
60
|
-
pos,
|
|
61
|
-
type: SymbolType.FUNCTION,
|
|
62
|
-
fix,
|
|
63
|
-
};
|
|
52
|
+
const fix = getFix(exportKeyword, defaultKeyword);
|
|
53
|
+
return { node, identifier, pos, type: SymbolType.FUNCTION, fix };
|
|
64
54
|
}
|
|
65
55
|
if (ts.isClassDeclaration(node) && node.name) {
|
|
66
56
|
const identifier = defaultKeyword ? 'default' : node.name.getText();
|
|
67
57
|
const pos = (node.name ?? node).getStart();
|
|
58
|
+
const fix = getFix(exportKeyword, defaultKeyword);
|
|
68
59
|
const members = isReportClassMembers
|
|
69
60
|
? node.members
|
|
70
61
|
.filter((member) => (ts.isPropertyDeclaration(member) ||
|
|
@@ -79,43 +70,24 @@ export default visit(() => true, (node, { isFixExports, isFixTypes, isReportClas
|
|
|
79
70
|
fix: undefined,
|
|
80
71
|
}))
|
|
81
72
|
: [];
|
|
82
|
-
|
|
83
|
-
? [exportKeyword.getStart(), (defaultKeyword ?? exportKeyword).getEnd() + 1]
|
|
84
|
-
: undefined;
|
|
85
|
-
return {
|
|
86
|
-
node,
|
|
87
|
-
identifier,
|
|
88
|
-
type: SymbolType.CLASS,
|
|
89
|
-
pos,
|
|
90
|
-
members,
|
|
91
|
-
fix,
|
|
92
|
-
};
|
|
73
|
+
return { node, identifier, type: SymbolType.CLASS, pos, members, fix };
|
|
93
74
|
}
|
|
94
75
|
if (ts.isTypeAliasDeclaration(node)) {
|
|
95
|
-
const identifier =
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
identifier,
|
|
100
|
-
type: SymbolType.TYPE,
|
|
101
|
-
pos: node.name.getStart(),
|
|
102
|
-
fix,
|
|
103
|
-
};
|
|
76
|
+
const identifier = node.name.getText();
|
|
77
|
+
const pos = node.name.getStart();
|
|
78
|
+
const fix = getTypeFix(exportKeyword);
|
|
79
|
+
return { node, identifier, type: SymbolType.TYPE, pos, fix };
|
|
104
80
|
}
|
|
105
81
|
if (ts.isInterfaceDeclaration(node)) {
|
|
106
|
-
const identifier =
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
identifier,
|
|
111
|
-
type: SymbolType.INTERFACE,
|
|
112
|
-
pos: node.name.getStart(),
|
|
113
|
-
fix,
|
|
114
|
-
};
|
|
82
|
+
const identifier = node.name.getText();
|
|
83
|
+
const pos = node.name.getStart();
|
|
84
|
+
const fix = getTypeFix(exportKeyword);
|
|
85
|
+
return { node, identifier, type: SymbolType.INTERFACE, pos, fix };
|
|
115
86
|
}
|
|
116
87
|
if (ts.isEnumDeclaration(node)) {
|
|
117
|
-
const identifier =
|
|
88
|
+
const identifier = node.name.getText();
|
|
118
89
|
const pos = node.name.getStart();
|
|
90
|
+
const fix = getTypeFix(exportKeyword);
|
|
119
91
|
const members = node.members.map(member => ({
|
|
120
92
|
node: member,
|
|
121
93
|
identifier: stripQuotes(member.name.getText()),
|
|
@@ -123,15 +95,7 @@ export default visit(() => true, (node, { isFixExports, isFixTypes, isReportClas
|
|
|
123
95
|
type: SymbolType.MEMBER,
|
|
124
96
|
fix: undefined,
|
|
125
97
|
}));
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
node,
|
|
129
|
-
identifier,
|
|
130
|
-
type: SymbolType.ENUM,
|
|
131
|
-
pos,
|
|
132
|
-
members,
|
|
133
|
-
fix,
|
|
134
|
-
};
|
|
98
|
+
return { node, identifier, type: SymbolType.ENUM, pos, members, fix };
|
|
135
99
|
}
|
|
136
100
|
}
|
|
137
101
|
});
|
|
@@ -16,7 +16,7 @@ export const getIncludedIssueTypes = (cliArgs, { include = [], exclude = [], isP
|
|
|
16
16
|
incl = [...incl, 'dependencies', 'optionalPeerDependencies', 'unlisted', 'binaries', 'unresolved'];
|
|
17
17
|
}
|
|
18
18
|
if (cliArgs.exports) {
|
|
19
|
-
incl = [...incl, 'exports', '
|
|
19
|
+
incl = [...incl, 'exports', 'types', 'enumMembers', 'duplicates'];
|
|
20
20
|
}
|
|
21
21
|
if (cliArgs.files) {
|
|
22
22
|
incl = [...incl, 'files'];
|
package/dist/util/plugin.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { _getDependenciesFromScripts as getDependenciesFromScripts } from '../binaries/index.js';
|
|
2
2
|
export { _loadJSON as loadJSON } from './fs.js';
|
|
3
|
+
export { _load as load } from './loader.js';
|
|
3
4
|
export { _tryResolve as tryResolve } from './require.js';
|
|
4
|
-
export { _getDependenciesFromScripts as getDependenciesFromScripts } from '../binaries/index.js';
|
|
5
5
|
import type { RawPluginConfiguration } from '../types/config.js';
|
|
6
6
|
import type { Plugin, PluginOptions } from '../types/plugins.js';
|
|
7
7
|
export declare const toCamelCase: (name: string) => string;
|
|
@@ -13,3 +13,27 @@ export declare const normalizePluginConfig: (pluginConfig: RawPluginConfiguratio
|
|
|
13
13
|
};
|
|
14
14
|
export declare const loadConfigForPlugin: (configFilePath: string, plugin: Plugin, options: PluginOptions, pluginName: string) => Promise<any>;
|
|
15
15
|
export declare const getFinalEntryPaths: (plugin: Plugin, options: PluginOptions, configEntryPaths: string[]) => string[];
|
|
16
|
+
export declare const toCosmiconfig: (moduleName: string, options?: {
|
|
17
|
+
rcPrefix?: string;
|
|
18
|
+
rcSuffix?: string;
|
|
19
|
+
configDir?: boolean;
|
|
20
|
+
configFiles?: boolean;
|
|
21
|
+
configFilesAllExtensions?: boolean;
|
|
22
|
+
additionalExtensions?: string[];
|
|
23
|
+
}) => string[];
|
|
24
|
+
export declare const toLilconfig: (moduleName: string, options?: {
|
|
25
|
+
rcPrefix?: string;
|
|
26
|
+
rcSuffix?: string;
|
|
27
|
+
configDir?: boolean;
|
|
28
|
+
configFiles?: boolean;
|
|
29
|
+
configFilesAllExtensions?: boolean;
|
|
30
|
+
additionalExtensions?: string[];
|
|
31
|
+
}) => string[];
|
|
32
|
+
export declare const toUnconfig: (moduleName: string, options?: {
|
|
33
|
+
rcPrefix?: string;
|
|
34
|
+
rcSuffix?: string;
|
|
35
|
+
configDir?: boolean;
|
|
36
|
+
configFiles?: boolean;
|
|
37
|
+
configFilesAllExtensions?: boolean;
|
|
38
|
+
additionalExtensions?: string[];
|
|
39
|
+
}) => string[];
|
package/dist/util/plugin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { _getDependenciesFromScripts as getDependenciesFromScripts } from '../binaries/index.js';
|
|
2
2
|
export { _loadJSON as loadJSON } from './fs.js';
|
|
3
|
+
export { _load as load } from './loader.js';
|
|
3
4
|
export { _tryResolve as tryResolve } from './require.js';
|
|
4
|
-
export { _getDependenciesFromScripts as getDependenciesFromScripts } from '../binaries/index.js';
|
|
5
5
|
import { arrayify } from './array.js';
|
|
6
6
|
import { _load as load } from './loader.js';
|
|
7
7
|
import { get } from './object.js';
|
|
@@ -61,3 +61,35 @@ export const getFinalEntryPaths = (plugin, options, configEntryPaths) => {
|
|
|
61
61
|
? configEntryPaths
|
|
62
62
|
: [...(plugin.entry ?? []).map(toEntryPattern), ...(plugin.production ?? []).map(toProductionEntryPattern)];
|
|
63
63
|
};
|
|
64
|
+
const toConfigMap = (defaultExtensions, builderConfig) => (moduleName, options) => {
|
|
65
|
+
const config = {
|
|
66
|
+
rcPrefix: '.',
|
|
67
|
+
rcSuffix: 'rc',
|
|
68
|
+
configDir: true,
|
|
69
|
+
configFiles: true,
|
|
70
|
+
configFilesAllExtensions: false,
|
|
71
|
+
additionalExtensions: [],
|
|
72
|
+
...builderConfig,
|
|
73
|
+
...options,
|
|
74
|
+
};
|
|
75
|
+
const { rcPrefix, rcSuffix } = config;
|
|
76
|
+
const jsTypeExtensions = ['js', 'ts', 'cjs', 'mjs', 'cts', 'mts'];
|
|
77
|
+
const extensions = [...defaultExtensions, ...config.additionalExtensions];
|
|
78
|
+
const baseFiles = [
|
|
79
|
+
`${rcPrefix}${moduleName}${rcSuffix}`,
|
|
80
|
+
...(config.configDir ? [`.config/${moduleName}${rcSuffix}`] : []),
|
|
81
|
+
];
|
|
82
|
+
const rcFiles = `${rcPrefix}${moduleName}${rcSuffix}.{${extensions.join(',')}}`;
|
|
83
|
+
const configExtensions = extensions.filter(ext => config.configFilesAllExtensions || jsTypeExtensions.includes(ext));
|
|
84
|
+
const configFiles = !!config.configFiles && `${moduleName}.config.{${configExtensions.join(',')}}`;
|
|
85
|
+
const configDirFiles = !!config.configDir && `.config/${moduleName}${rcSuffix}.{${extensions.join(',')}}`;
|
|
86
|
+
return [...baseFiles, rcFiles, configFiles, configDirFiles].filter(item => item !== false);
|
|
87
|
+
};
|
|
88
|
+
export const toCosmiconfig = toConfigMap(['json', 'yaml', 'yml', 'js', 'ts', 'cjs', 'mjs'], { configDir: true });
|
|
89
|
+
export const toLilconfig = toConfigMap(['json', 'js', 'cjs', 'mjs'], { configDir: true });
|
|
90
|
+
export const toUnconfig = toConfigMap(['json', 'ts', 'mts', 'cts', 'js', 'mjs', 'cjs'], {
|
|
91
|
+
configDir: false,
|
|
92
|
+
rcPrefix: '',
|
|
93
|
+
rcSuffix: '',
|
|
94
|
+
configFiles: false,
|
|
95
|
+
});
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.23.
|
|
1
|
+
export declare const version = "5.23.2";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.23.
|
|
1
|
+
export const version = '5.23.2';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "5.23.
|
|
3
|
+
"version": "5.23.2",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
|
|
5
5
|
"homepage": "https://knip.dev",
|
|
6
6
|
"repository": {
|
|
@@ -21,7 +21,11 @@
|
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"type": "opencollective",
|
|
24
|
-
"url": "https://opencollective.com/
|
|
24
|
+
"url": "https://opencollective.com/knip"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "polar",
|
|
28
|
+
"url": "https://polar.sh/webpro-nl"
|
|
25
29
|
}
|
|
26
30
|
],
|
|
27
31
|
"main": "./dist/index.js",
|