knip 5.36.6 → 5.37.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.
@@ -10,6 +10,7 @@ const commands = [
10
10
  'dedupe',
11
11
  'dlx',
12
12
  'explain',
13
+ 'global',
13
14
  'info',
14
15
  'init',
15
16
  'install',
@@ -0,0 +1,4 @@
1
+ import type { PluginOptions } from '../../types/config.js';
2
+ import type { JestInitialOptions } from './types.js';
3
+ export declare const resolveExtensibleConfig: (configFilePath: string) => Promise<any>;
4
+ export declare const getReportersDependencies: (config: JestInitialOptions, options: PluginOptions) => string[];
@@ -0,0 +1,39 @@
1
+ import { dirname, isInternal, join, toAbsolute } from '../../util/path.js';
2
+ import { load } from '../../util/plugin.js';
3
+ export const resolveExtensibleConfig = async (configFilePath) => {
4
+ let config = await load(configFilePath);
5
+ if (config?.preset) {
6
+ const { preset } = config;
7
+ if (isInternal(preset)) {
8
+ const presetConfigPath = toAbsolute(preset, dirname(configFilePath));
9
+ const presetConfig = await resolveExtensibleConfig(presetConfigPath);
10
+ config = Object.assign({}, presetConfig, config);
11
+ }
12
+ }
13
+ return config;
14
+ };
15
+ const getStringPropOrFallback = (prop, fallback) => {
16
+ return typeof prop === 'string' ? prop : fallback;
17
+ };
18
+ export const getReportersDependencies = (config, options) => {
19
+ const jUnitReporterDeps = [];
20
+ for (const reporter of config.reporters ?? []) {
21
+ if (typeof reporter !== 'string' && reporter[0] === 'jest-junit') {
22
+ const { testCasePropertiesFile, testCasePropertiesDirectory, testSuitePropertiesFile, testSuitePropertiesDirectory, } = reporter[1];
23
+ const testCaseFileName = getStringPropOrFallback(testCasePropertiesFile, 'junitProperties.js');
24
+ const testCaseDirectory = getStringPropOrFallback(testCasePropertiesDirectory, options.rootCwd);
25
+ const testCaseFilePath = join(testCaseDirectory, testCaseFileName);
26
+ const testSuiteFileName = getStringPropOrFallback(testSuitePropertiesFile, 'junitTestCaseProperties.js');
27
+ const testSuiteDirectory = getStringPropOrFallback(testSuitePropertiesDirectory, options.rootCwd);
28
+ const testSuiteFilePath = join(testSuiteDirectory, testSuiteFileName);
29
+ jUnitReporterDeps.push(testCaseFilePath);
30
+ jUnitReporterDeps.push(testSuiteFilePath);
31
+ }
32
+ }
33
+ const reporters = config.reporters
34
+ ? config.reporters
35
+ .map(reporter => (typeof reporter === 'string' ? reporter : reporter[0]))
36
+ .filter(reporter => !['default', 'github-actions', 'summary'].includes(reporter))
37
+ : [];
38
+ return [...reporters, ...jUnitReporterDeps];
39
+ };
@@ -1,23 +1,12 @@
1
1
  import { toDeferResolve, toEntry } from '../../util/input.js';
2
- import { dirname, isInternal, join, toAbsolute } from '../../util/path.js';
3
- import { hasDependency, load } from '../../util/plugin.js';
2
+ import { isInternal, join, toAbsolute } from '../../util/path.js';
3
+ import { hasDependency } from '../../util/plugin.js';
4
+ import { getReportersDependencies, resolveExtensibleConfig } from './helpers.js';
4
5
  const title = 'Jest';
5
6
  const enablers = ['jest'];
6
7
  const isEnabled = ({ dependencies, manifest }) => hasDependency(dependencies, enablers) || Boolean(manifest.name?.startsWith('jest-presets'));
7
8
  const config = ['jest.config.{js,ts,mjs,cjs,json}', 'package.json'];
8
9
  const entry = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'];
9
- const resolveExtensibleConfig = async (configFilePath) => {
10
- let config = await load(configFilePath);
11
- if (config?.preset) {
12
- const { preset } = config;
13
- if (isInternal(preset)) {
14
- const presetConfigPath = toAbsolute(preset, dirname(configFilePath));
15
- const presetConfig = await resolveExtensibleConfig(presetConfigPath);
16
- config = Object.assign({}, presetConfig, config);
17
- }
18
- }
19
- return config;
20
- };
21
10
  const resolveDependencies = async (config, options) => {
22
11
  const { configFileDir } = options;
23
12
  if (config?.preset) {
@@ -42,13 +31,13 @@ const resolveDependencies = async (config, options) => {
42
31
  }
43
32
  const runner = config.runner ? [config.runner] : [];
44
33
  const runtime = config.runtime && config.runtime !== 'jest-circus' ? [config.runtime] : [];
45
- const environments = config.testEnvironment === 'jsdom' ? ['jest-environment-jsdom'] : [];
34
+ const environments = config.testEnvironment === 'jsdom'
35
+ ? ['jest-environment-jsdom']
36
+ : config.testEnvironment
37
+ ? [config.testEnvironment]
38
+ : [];
46
39
  const resolvers = config.resolver ? [config.resolver] : [];
47
- const reporters = config.reporters
48
- ? config.reporters
49
- .map(reporter => (typeof reporter === 'string' ? reporter : reporter[0]))
50
- .filter(reporter => !['default', 'github-actions', 'summary'].includes(reporter))
51
- : [];
40
+ const reporters = getReportersDependencies(config, options);
52
41
  const watchPlugins = config.watchPlugins?.map(watchPlugin => (typeof watchPlugin === 'string' ? watchPlugin : watchPlugin[0])) ?? [];
53
42
  const transform = config.transform
54
43
  ? Object.values(config.transform).map(transform => (typeof transform === 'string' ? transform : transform[0]))
@@ -89,7 +78,7 @@ const resolveEntryPaths = async (localConfig, options) => {
89
78
  const { configFileDir } = options;
90
79
  if (typeof localConfig === 'function')
91
80
  localConfig = await localConfig();
92
- const rootDir = localConfig.rootDir ? join(configFileDir, localConfig.rootDir) : configFileDir;
81
+ const rootDir = localConfig.rootDir ?? configFileDir;
93
82
  const replaceRootDir = (name) => name.replace(/<rootDir>/, rootDir);
94
83
  return (localConfig.testMatch ?? []).map(replaceRootDir).map(toEntry);
95
84
  };
@@ -97,7 +86,7 @@ const resolveConfig = async (localConfig, options) => {
97
86
  const { configFileDir } = options;
98
87
  if (typeof localConfig === 'function')
99
88
  localConfig = await localConfig();
100
- const rootDir = localConfig.rootDir ? join(configFileDir, localConfig.rootDir) : configFileDir;
89
+ const rootDir = localConfig.rootDir ?? configFileDir;
101
90
  const replaceRootDir = (name) => name.replace(/<rootDir>/, rootDir);
102
91
  const inputs = await resolveDependencies(localConfig, options);
103
92
  const result = inputs.map(dependency => {
@@ -9,88 +9,90 @@ export const pluginSchema = z.union([
9
9
  project: globSchema.optional(),
10
10
  }),
11
11
  ]);
12
- export const pluginsSchema = z.object({ 'angular': pluginSchema,
13
- 'astro': pluginSchema,
14
- 'ava': pluginSchema,
15
- 'babel': pluginSchema,
16
- 'c8': pluginSchema,
17
- 'capacitor': pluginSchema,
18
- 'changesets': pluginSchema,
19
- 'commitizen': pluginSchema,
20
- 'commitlint': pluginSchema,
21
- 'cspell': pluginSchema,
22
- 'cucumber': pluginSchema,
23
- 'cypress': pluginSchema,
24
- 'dotenv': pluginSchema,
25
- 'drizzle': pluginSchema,
26
- 'eleventy': pluginSchema,
27
- 'eslint': pluginSchema,
28
- 'gatsby': pluginSchema,
12
+ export const pluginsSchema = z.object({
13
+ angular: pluginSchema,
14
+ astro: pluginSchema,
15
+ ava: pluginSchema,
16
+ babel: pluginSchema,
17
+ c8: pluginSchema,
18
+ capacitor: pluginSchema,
19
+ changesets: pluginSchema,
20
+ commitizen: pluginSchema,
21
+ commitlint: pluginSchema,
22
+ cspell: pluginSchema,
23
+ cucumber: pluginSchema,
24
+ cypress: pluginSchema,
25
+ dotenv: pluginSchema,
26
+ drizzle: pluginSchema,
27
+ eleventy: pluginSchema,
28
+ eslint: pluginSchema,
29
+ gatsby: pluginSchema,
29
30
  'github-actions': pluginSchema,
30
- 'glob': pluginSchema,
31
+ glob: pluginSchema,
31
32
  'graphql-codegen': pluginSchema,
32
- 'husky': pluginSchema,
33
- 'jest': pluginSchema,
34
- 'ladle': pluginSchema,
35
- 'lefthook': pluginSchema,
33
+ husky: pluginSchema,
34
+ jest: pluginSchema,
35
+ ladle: pluginSchema,
36
+ lefthook: pluginSchema,
36
37
  'lint-staged': pluginSchema,
37
- 'linthtml': pluginSchema,
38
+ linthtml: pluginSchema,
38
39
  'lockfile-lint': pluginSchema,
39
40
  'lost-pixel': pluginSchema,
40
- 'markdownlint': pluginSchema,
41
- 'mocha': pluginSchema,
42
- 'moonrepo': pluginSchema,
43
- 'msw': pluginSchema,
44
- 'nest': pluginSchema,
45
- 'netlify': pluginSchema,
46
- 'next': pluginSchema,
47
- 'node': pluginSchema,
41
+ markdownlint: pluginSchema,
42
+ mocha: pluginSchema,
43
+ moonrepo: pluginSchema,
44
+ msw: pluginSchema,
45
+ nest: pluginSchema,
46
+ netlify: pluginSchema,
47
+ next: pluginSchema,
48
+ node: pluginSchema,
48
49
  'node-test-runner': pluginSchema,
49
- 'nodemon': pluginSchema,
50
+ nodemon: pluginSchema,
50
51
  'npm-package-json-lint': pluginSchema,
51
- 'nuxt': pluginSchema,
52
- 'nx': pluginSchema,
53
- 'nyc': pluginSchema,
54
- 'oclif': pluginSchema,
55
- 'playwright': pluginSchema,
52
+ nuxt: pluginSchema,
53
+ nx: pluginSchema,
54
+ nyc: pluginSchema,
55
+ oclif: pluginSchema,
56
+ playwright: pluginSchema,
56
57
  'playwright-ct': pluginSchema,
57
58
  'playwright-test': pluginSchema,
58
- 'postcss': pluginSchema,
59
- 'preconstruct': pluginSchema,
60
- 'prettier': pluginSchema,
59
+ postcss: pluginSchema,
60
+ preconstruct: pluginSchema,
61
+ prettier: pluginSchema,
61
62
  'react-cosmos': pluginSchema,
62
63
  'release-it': pluginSchema,
63
- 'remark': pluginSchema,
64
- 'remix': pluginSchema,
65
- 'rollup': pluginSchema,
66
- 'rsbuild': pluginSchema,
67
- 'rspack': pluginSchema,
64
+ remark: pluginSchema,
65
+ remix: pluginSchema,
66
+ rollup: pluginSchema,
67
+ rsbuild: pluginSchema,
68
+ rspack: pluginSchema,
68
69
  'semantic-release': pluginSchema,
69
- 'sentry': pluginSchema,
70
+ sentry: pluginSchema,
70
71
  'simple-git-hooks': pluginSchema,
71
72
  'size-limit': pluginSchema,
72
- 'storybook': pluginSchema,
73
- 'stryker': pluginSchema,
74
- 'stylelint': pluginSchema,
75
- 'svelte': pluginSchema,
76
- 'syncpack': pluginSchema,
77
- 'tailwind': pluginSchema,
78
- 'travis': pluginSchema,
73
+ storybook: pluginSchema,
74
+ stryker: pluginSchema,
75
+ stylelint: pluginSchema,
76
+ svelte: pluginSchema,
77
+ syncpack: pluginSchema,
78
+ tailwind: pluginSchema,
79
+ travis: pluginSchema,
79
80
  'ts-node': pluginSchema,
80
- 'tsup': pluginSchema,
81
- 'tsx': pluginSchema,
82
- 'typedoc': pluginSchema,
83
- 'typescript': pluginSchema,
84
- 'unbuild': pluginSchema,
85
- 'unocss': pluginSchema,
81
+ tsup: pluginSchema,
82
+ tsx: pluginSchema,
83
+ typedoc: pluginSchema,
84
+ typescript: pluginSchema,
85
+ unbuild: pluginSchema,
86
+ unocss: pluginSchema,
86
87
  'vercel-og': pluginSchema,
87
- 'vike': pluginSchema,
88
- 'vite': pluginSchema,
89
- 'vitest': pluginSchema,
90
- 'vue': pluginSchema,
88
+ vike: pluginSchema,
89
+ vite: pluginSchema,
90
+ vitest: pluginSchema,
91
+ vue: pluginSchema,
91
92
  'webdriver-io': pluginSchema,
92
- 'webpack': pluginSchema,
93
- 'wireit': pluginSchema,
94
- 'wrangler': pluginSchema,
95
- 'xo': pluginSchema,
96
- 'yorkie': pluginSchema });
93
+ webpack: pluginSchema,
94
+ wireit: pluginSchema,
95
+ wrangler: pluginSchema,
96
+ xo: pluginSchema,
97
+ yorkie: pluginSchema,
98
+ });
@@ -23,7 +23,7 @@ export type RawConfiguration = z.infer<typeof ConfigurationValidator>;
23
23
  export type RawPluginConfiguration = z.infer<typeof pluginSchema>;
24
24
  export type IgnorePatterns = (string | RegExp)[];
25
25
  type IgnorableExport = 'class' | 'enum' | 'function' | 'interface' | 'member' | 'type';
26
- export type IgnoreExportsUsedInFile = boolean | Partial<Record<IgnorableExport, boolean>>;
26
+ type IgnoreExportsUsedInFile = boolean | Partial<Record<IgnorableExport, boolean>>;
27
27
  export type GetImportsAndExportsOptions = {
28
28
  skipTypeOnly: boolean;
29
29
  skipExports: boolean;
@@ -48,7 +48,7 @@ export interface Configuration {
48
48
  asyncCompilers: AsyncCompilers;
49
49
  rootPluginConfigs: Partial<PluginsConfiguration>;
50
50
  }
51
- export type NormalizedGlob = string[];
51
+ type NormalizedGlob = string[];
52
52
  export type EnsuredPluginConfiguration = {
53
53
  config: NormalizedGlob | null;
54
54
  entry: NormalizedGlob | null;
@@ -159,26 +159,17 @@ export const isImportSpecifier = (node) => ts.isImportSpecifier(node.parent) ||
159
159
  ts.isImportEqualsDeclaration(node.parent) ||
160
160
  ts.isImportClause(node.parent) ||
161
161
  ts.isNamespaceImport(node.parent);
162
- const isExported = (node) => {
162
+ const isInExportedNode = (node) => {
163
163
  if (getExportKeywordNode(node))
164
164
  return true;
165
- return node.parent ? isExported(node.parent) : false;
166
- };
167
- const isTypeDeclaration = (node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node);
168
- const getAncestorTypeDeclaration = (node) => {
169
- while (node) {
170
- if (isTypeDeclaration(node))
171
- return node;
172
- node = node.parent;
173
- }
165
+ return node.parent ? isInExportedNode(node.parent) : false;
174
166
  };
175
167
  export const isReferencedInExport = (node) => {
176
- if (ts.isTypeQueryNode(node.parent) && isExported(node.parent.parent))
168
+ if (ts.isTypeQueryNode(node.parent) && isInExportedNode(node.parent.parent))
177
169
  return true;
178
- if (ts.isTypeReferenceNode(node.parent) && isExported(node.parent.parent))
170
+ if (ts.isTypeReferenceNode(node.parent) && isInExportedNode(node.parent.parent))
179
171
  return true;
180
- const typeNode = getAncestorTypeDeclaration(node);
181
- return Boolean(typeNode && isExported(typeNode));
172
+ return false;
182
173
  };
183
174
  export const getExportKeywordNode = (node) => node.modifiers?.find(mod => mod.kind === ts.SyntaxKind.ExportKeyword);
184
175
  export const getDefaultKeywordNode = (node) => node.modifiers?.find(mod => mod.kind === ts.SyntaxKind.DefaultKeyword);
@@ -25,8 +25,6 @@ export const findInternalReferences = (item, sourceFile, typeChecker, referenced
25
25
  isSymbolInExport = true;
26
26
  if (item.symbol === symbol) {
27
27
  refCount++;
28
- if (isInExport || isType(item))
29
- return [refCount, isSymbolInExport];
30
28
  if (isBindingElement)
31
29
  return [refCount, true];
32
30
  }
@@ -308,7 +308,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
308
308
  for (const node of pragmaImports)
309
309
  addImport(node, sourceFile);
310
310
  for (const item of exports.values()) {
311
- if (item.symbol && referencedSymbolsInExport.has(item.symbol)) {
311
+ if (!isType(item) && item.symbol && referencedSymbolsInExport.has(item.symbol)) {
312
312
  item.refs = [1, true];
313
313
  }
314
314
  else {
@@ -317,7 +317,6 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
317
317
  (typeof ignoreExportsUsedInFile === 'object' &&
318
318
  item.type !== 'unknown' &&
319
319
  ignoreExportsUsedInFile[item.type]) ||
320
- isType(item) ||
321
320
  isBindingElement) {
322
321
  item.refs = findInternalReferences(item, sourceFile, typeChecker, referencedSymbolsInExport, isBindingElement);
323
322
  }
@@ -3,8 +3,9 @@ import picocolors from 'picocolors';
3
3
  import parsedArgValues from './cli-arguments.js';
4
4
  const { debug } = parsedArgValues;
5
5
  const IS_DEBUG_ENABLED = debug ?? false;
6
+ const IS_COLORS = !process.env.NO_COLOR;
6
7
  const noop = () => { };
7
- const inspectOptions = { maxArrayLength: null, depth: null, colors: true };
8
+ const inspectOptions = { maxArrayLength: null, depth: null, colors: IS_COLORS };
8
9
  export const inspect = (obj) => console.log(util.inspect(obj, inspectOptions));
9
10
  const ctx = (text) => typeof text === 'string'
10
11
  ? picocolors.yellow(`[${text}]`)
@@ -56,7 +56,8 @@ export const getWatchHandler = async ({ analyzedFiles, analyzeSourceFile, chief,
56
56
  else {
57
57
  graph.delete(filePath);
58
58
  analyzedFiles.delete(filePath);
59
- cachedUnusedFiles.add(filePath);
59
+ if (filePath.startsWith(cwd))
60
+ cachedUnusedFiles.add(filePath);
60
61
  }
61
62
  }
62
63
  for (const filePath of filePaths)
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.36.6";
1
+ export declare const version = "5.37.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.36.6';
1
+ export const version = '5.37.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.36.6",
3
+ "version": "5.37.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": {
@@ -49,7 +49,7 @@
49
49
  "release": "release-it",
50
50
  "create-plugin": "bun ./scripts/create-new-plugin.ts",
51
51
  "postcreate-plugin": "biome format --write schema.json schema-jsonc.json src/ConfigurationValidator.ts",
52
- "generate-plugin-defs": "node ./scripts/generate-plugin-defs.js && biome check --write src/plugins/index.ts src/types/PluginNames.ts"
52
+ "generate-plugin-defs": "node ./scripts/generate-plugin-defs.js && biome check --write src/plugins/index.ts src/types/PluginNames.ts src/schema/plugins.ts"
53
53
  },
54
54
  "files": [
55
55
  "dist",