knip 2.23.0 → 2.24.1

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 CHANGED
@@ -799,7 +799,7 @@ Special thanks to the wonderful people who have contributed to this project:
799
799
  [7]: #jsdoc-tags
800
800
  [8]: https://labs.openai.com/s/xZQACaLepaKya0PRUPtIN5dC
801
801
  [9]: ./assets/cow-with-orange-scissors-van-gogh-style.webp
802
- [10]: https://discord.gg/ya5yktTq
802
+ [10]: https://discord.gg/r5uXTtbTpc
803
803
  [11]: https://twitter.com/webprolific
804
804
  [12]: https://fosstodon.org/@webpro
805
805
  [13]: https://github.com/webpro/knip/issues
@@ -3,9 +3,17 @@ export const NAME = 'Next.js';
3
3
  export const ENABLERS = ['next'];
4
4
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
5
5
  export const ENTRY_FILE_PATTERNS = ['next.config.{js,ts,cjs,mjs}'];
6
- export const PRODUCTION_ENTRY_FILE_PATTERNS = [
7
- '{app,pages}/**/*.{js,jsx,ts,tsx}',
8
- 'src/{app,pages}/**/*.{js,jsx,ts,tsx}',
6
+ const productionEntryFilePatternsWithoutSrc = [
9
7
  'middleware.{js,ts}',
10
- 'src/middleware.{js,ts}',
8
+ 'app/**/route.{js,ts}',
9
+ 'app/**/{error,layout,loading,not-found,page,template}.{js,jsx,tsx}',
10
+ 'instrumentation.{js,ts}',
11
+ 'app/{manifest,sitemap,robots}.{js,ts}',
12
+ 'app/**/{icon,apple-icon}-image.{js,ts,tsx}',
13
+ 'app/**/{opengraph,twitter}-image.{js,ts,tsx}',
14
+ 'pages/**/*.{js,jsx,ts,tsx}',
15
+ ];
16
+ export const PRODUCTION_ENTRY_FILE_PATTERNS = [
17
+ ...productionEntryFilePatternsWithoutSrc,
18
+ ...productionEntryFilePatternsWithoutSrc.map(pattern => `src/${pattern}`),
11
19
  ];
@@ -27,6 +27,7 @@ const findTypeScriptDependencies = async (configFilePath) => {
27
27
  if (!compilerOptions || !config)
28
28
  return [];
29
29
  const extend = config.extends ? [config.extends].flat().filter(extend => !isInternal(extend)) : [];
30
+ const types = compilerOptions.types ?? [];
30
31
  const plugins = Array.isArray(compilerOptions?.plugins)
31
32
  ? compilerOptions.plugins.map(plugin => (typeof plugin === 'object' && 'name' in plugin ? plugin.name : ''))
32
33
  : [];
@@ -36,6 +37,6 @@ const findTypeScriptDependencies = async (configFilePath) => {
36
37
  : compilerOptions?.jsx
37
38
  ? ['react']
38
39
  : [];
39
- return compact([...extend, ...plugins, ...importHelpers, ...jsx]);
40
+ return compact([...extend, ...types, ...plugins, ...importHelpers, ...jsx]);
40
41
  };
41
42
  export const findDependencies = timerify(findTypeScriptDependencies);
@@ -1,5 +1,6 @@
1
- import type { IsPluginEnabledCallback } from '../../types/plugins.js';
1
+ import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
2
2
  export declare const NAME = "Vite";
3
3
  export declare const ENABLERS: string[];
4
4
  export declare const isEnabled: IsPluginEnabledCallback;
5
- export declare const ENTRY_FILE_PATTERNS: string[];
5
+ export declare const CONFIG_FILE_PATTERNS: string[];
6
+ export declare const findDependencies: GenericPluginCallback;
@@ -1,5 +1,12 @@
1
- import { hasDependency } from '../../util/plugin.js';
1
+ import { timerify } from '../../util/Performance.js';
2
+ import { hasDependency, load } from '../../util/plugin.js';
3
+ import { findVitestDeps } from '../vitest/index.js';
2
4
  export const NAME = 'Vite';
3
5
  export const ENABLERS = ['vite'];
4
6
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
5
- export const ENTRY_FILE_PATTERNS = ['vite.config.{js,ts}'];
7
+ export const CONFIG_FILE_PATTERNS = ['vite.config.{js,ts}'];
8
+ const findViteDependencies = async (configFilePath) => {
9
+ const config = await load(configFilePath);
10
+ return findVitestDeps(config);
11
+ };
12
+ export const findDependencies = timerify(findViteDependencies);
@@ -0,0 +1,4 @@
1
+ import type { VitestConfig } from '../vitest/types.js';
2
+ export interface ViteConfig extends VitestConfig {
3
+ plugins: unknown[];
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,7 +1,9 @@
1
+ import type { VitestConfig } from './types.js';
1
2
  import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
2
3
  export declare const NAME = "Vitest";
3
4
  export declare const ENABLERS: string[];
4
5
  export declare const isEnabled: IsPluginEnabledCallback;
5
6
  export declare const CONFIG_FILE_PATTERNS: string[];
6
- export declare const ENTRY_FILE_PATTERNS: string[];
7
+ export declare const ENTRY_FILE_PATTERNS: never[];
8
+ export declare const findVitestDeps: (config: VitestConfig) => any[];
7
9
  export declare const findDependencies: GenericPluginCallback;
@@ -6,9 +6,8 @@ export const NAME = 'Vitest';
6
6
  export const ENABLERS = ['vitest'];
7
7
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
8
8
  export const CONFIG_FILE_PATTERNS = ['vitest.config.ts'];
9
- export const ENTRY_FILE_PATTERNS = ['vite.config.ts'];
10
- const findVitestDependencies = async (configFilePath) => {
11
- const config = await load(configFilePath);
9
+ export const ENTRY_FILE_PATTERNS = [];
10
+ export const findVitestDeps = (config) => {
12
11
  if (!config || !config.test)
13
12
  return [];
14
13
  const cfg = config.test;
@@ -19,4 +18,8 @@ const findVitestDependencies = async (configFilePath) => {
19
18
  const globalSetup = cfg.globalSetup ? [cfg.globalSetup].flat() : [];
20
19
  return compact([...environments, ...reporters, ...coverage, ...setupFiles, ...globalSetup]);
21
20
  };
21
+ const findVitestDependencies = async (configFilePath) => {
22
+ const config = await load(configFilePath);
23
+ return findVitestDeps(config);
24
+ };
22
25
  export const findDependencies = timerify(findVitestDependencies);
@@ -1,4 +1,4 @@
1
- export type VitestConfig = {
1
+ export interface VitestConfig {
2
2
  test: {
3
3
  coverage?: {
4
4
  provider: string;
@@ -8,4 +8,4 @@ export type VitestConfig = {
8
8
  reporters?: (string | unknown)[];
9
9
  setupFiles?: string | string[];
10
10
  };
11
- };
11
+ }
@@ -10,7 +10,7 @@ export declare function isDefaultImport(node: ts.ImportDeclaration | ts.ImportEq
10
10
  export declare function isAccessExpression(node: ts.Node): node is ts.PropertyAccessExpression | ts.ElementAccessExpression;
11
11
  export declare function isImportCall(node: ts.Node): node is ts.ImportCall;
12
12
  export declare function isRequireCall(callExpression: ts.Node): callExpression is ts.CallExpression;
13
- export declare function isRequireResolveCall(node: ts.Node): node is ts.CallExpression;
13
+ export declare function isPropertyAccessCall(node: ts.Node, identifier: string): node is ts.CallExpression;
14
14
  export declare function getAccessExpressionName(node: ts.PropertyAccessExpression | ts.ElementAccessExpression): string;
15
15
  type LiteralLikeElementAccessExpression = ts.ElementAccessExpression & ts.Declaration & {
16
16
  readonly argumentExpression: ts.StringLiteralLike | ts.NumericLiteral;
@@ -25,10 +25,10 @@ export function isRequireCall(callExpression) {
25
25
  }
26
26
  return args.length === 1;
27
27
  }
28
- export function isRequireResolveCall(node) {
28
+ export function isPropertyAccessCall(node, identifier) {
29
29
  return (ts.isCallExpression(node) &&
30
30
  ts.isPropertyAccessExpression(node.expression) &&
31
- node.expression.getText() === 'require.resolve');
31
+ node.expression.getText() === identifier);
32
32
  }
33
33
  export function getAccessExpressionName(node) {
34
34
  return 'argumentExpression' in node ? stripQuotes(node.argumentExpression.getText()) : node.name.getText();
@@ -1,4 +1,6 @@
1
+ import { existsSync } from 'node:fs';
1
2
  import { isBuiltin } from 'node:module';
3
+ import { resolve, dirname } from 'node:path';
2
4
  import ts from 'typescript';
3
5
  import { getOrSet } from '../util/map.js';
4
6
  import { isMaybePackageName } from '../util/modules.js';
@@ -73,7 +75,13 @@ export const getImportsAndExports = (sourceFile, options) => {
73
75
  }
74
76
  }
75
77
  else {
76
- unresolvedImports.add(specifier);
78
+ const filePath = resolve(dirname(sourceFile.fileName), specifier);
79
+ if (existsSync(filePath)) {
80
+ unresolvedImports.add(filePath);
81
+ }
82
+ else {
83
+ unresolvedImports.add(specifier);
84
+ }
77
85
  }
78
86
  };
79
87
  const maybeAddNamespaceAccessAsImport = ({ namespace, member }) => {
@@ -3,16 +3,16 @@ import importCall from './importCall.js';
3
3
  import importDeclaration from './importDeclaration.js';
4
4
  import importEqualsDeclaration from './importEqualsDeclaration.js';
5
5
  import jsDocType from './jsDocType.js';
6
+ import propertyAccessCall from './propertyAccessCall.js';
6
7
  import reExportDeclaration from './reExportDeclaration.js';
7
8
  import requireCall from './requireCall.js';
8
- import requireResolveCall from './requireResolveCall.js';
9
9
  const visitors = [
10
10
  importCall,
11
11
  importDeclaration,
12
12
  importEqualsDeclaration,
13
13
  jsDocType,
14
+ propertyAccessCall,
14
15
  reExportDeclaration,
15
16
  requireCall,
16
- requireResolveCall,
17
17
  ];
18
18
  export default (sourceFile) => visitors.map(v => v(sourceFile));
@@ -1,8 +1,8 @@
1
1
  import ts from 'typescript';
2
- import { isRequireResolveCall } from '../../ast-helpers.js';
2
+ import { isPropertyAccessCall } from '../../ast-helpers.js';
3
3
  import { importVisitor as visit } from '../index.js';
4
4
  export default visit(() => true, node => {
5
- if (isRequireResolveCall(node)) {
5
+ if (isPropertyAccessCall(node, 'require.resolve')) {
6
6
  if (node.arguments[0] && ts.isStringLiteralLike(node.arguments[0])) {
7
7
  const specifier = node.arguments[0].text;
8
8
  if (specifier)
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.23.0";
1
+ export declare const version = "2.24.1";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.23.0';
1
+ export const version = '2.24.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.23.0",
3
+ "version": "2.24.1",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",
@@ -35,7 +35,7 @@
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 --loglevel silent"
38
+ "postcreate-plugin": "prettier schema.json src/ConfigurationValidator.ts --write --config .prettierrc --log-level silent"
39
39
  },
40
40
  "files": [
41
41
  "dist",