knip 5.57.2 → 5.58.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.
@@ -307,10 +307,11 @@ export class ConfigurationChief {
307
307
  getNegatedWorkspacePatterns(name) {
308
308
  const descendentWorkspaces = this.getDescendentWorkspaces(name);
309
309
  const matchName = new RegExp(`^${name}/`);
310
- const ignoredWorkspaces = this.getIgnoredWorkspacesFor(name).map(p => p.replace(/\/\*$/, '/**'));
310
+ const ignoredWorkspaces = this.getIgnoredWorkspacesFor(name);
311
+ const endMatch = /\/\*{1,2}$|\/$|$/;
311
312
  return [...ignoredWorkspaces, ...descendentWorkspaces]
312
313
  .map(workspaceName => workspaceName.replace(matchName, ''))
313
- .map(workspaceName => `!${workspaceName}`);
314
+ .map(workspaceName => `!${workspaceName.replace(endMatch, '/**')}`);
314
315
  }
315
316
  getConfigKeyForWorkspace(workspaceName) {
316
317
  return this.getConfiguredWorkspaceKeys()
@@ -269,6 +269,8 @@ export class WorkspaceWorker {
269
269
  const cache = {};
270
270
  const key = `${wsName}:${pluginName}`;
271
271
  if (plugin.resolveConfig && !seen.get(key)?.has(configFilePath)) {
272
+ if (typeof plugin.setup === 'function')
273
+ await plugin.setup(resolveOpts);
272
274
  const localConfig = await loadConfigForPlugin(configFilePath, plugin, resolveOpts, pluginName);
273
275
  if (localConfig) {
274
276
  const inputs = await plugin.resolveConfig(localConfig, resolveOpts);
@@ -276,6 +278,8 @@ export class WorkspaceWorker {
276
278
  addInput(input, configFilePath);
277
279
  cache.resolveConfig = inputs;
278
280
  }
281
+ if (typeof plugin.teardown === 'function')
282
+ await plugin.teardown(resolveOpts);
279
283
  }
280
284
  if (plugin.resolveFromAST) {
281
285
  const sourceFile = this.getSourceFile(configFilePath);
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import { splitTags } from './util/tag.js';
10
10
  import { isTrace } from './util/trace.js';
11
11
  import { version } from './version.js';
12
12
  const defaultCacheLocation = join(cwd, 'node_modules', '.cache', 'knip');
13
- const { 'allow-remove-files': isRemoveFiles = false, cache: isCache = false, 'cache-location': cacheLocation = defaultCacheLocation, debug: isDebug = false, dependencies: isDependenciesShorthand = false, exclude: excludedIssueTypes = [], 'experimental-tags': experimentalTags = [], exports: isExportsShorthand = false, files: isFilesShorthand = false, fix: isFix = false, format: isFormat = false, 'fix-type': fixTypes = [], help: isHelp, include: includedIssueTypes = [], 'include-entry-exports': isIncludeEntryExports = false, 'include-libs': isIncludeLibs = false, 'isolate-workspaces': isIsolateWorkspaces = false, 'max-issues': maxIssues = '0', 'memory-realtime': memoryRealtime = false, 'no-config-hints': isDisableConfigHints = false, 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = isDebug || isTrace || memoryRealtime, preprocessor = [], 'preprocessor-options': preprocessorOptions = '', production: isProduction = false, reporter = ['symbols'], 'reporter-options': reporterOptions = '', strict: isStrict = false, tags = [], 'treat-config-hints-as-errors': treatConfigHintsAsErrors = false, tsConfig, version: isVersion, watch: isWatch = false, workspace: rawWorkspaceArg, } = parsedArgValues;
13
+ const { 'allow-remove-files': isRemoveFiles = false, cache: isCache = false, 'cache-location': cacheLocation = defaultCacheLocation, debug: isDebug = false, dependencies: isDependenciesShorthand = false, exclude: excludedIssueTypes = [], 'experimental-tags': experimentalTags = [], exports: isExportsShorthand = false, files: isFilesShorthand = false, fix: isFix = false, format: isFormat = false, 'fix-type': fixTypes = [], help: isHelp, include: includedIssueTypes = [], 'include-entry-exports': isIncludeEntryExports = false, 'include-libs': isIncludeLibs = false, 'isolate-workspaces': isIsolateWorkspaces = false, 'max-issues': maxIssues = '0', 'memory-realtime': memoryRealtime = false, 'no-config-hints': isNoConfigHints = false, 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = isDebug || isTrace || memoryRealtime, preprocessor = [], 'preprocessor-options': preprocessorOptions = '', production: isProduction = false, reporter = ['symbols'], 'reporter-options': reporterOptions = '', strict: isStrict = false, tags = [], 'treat-config-hints-as-errors': treatConfigHintsAsErrors = false, tsConfig, version: isVersion, watch: isWatch = false, workspace: rawWorkspaceArg, } = parsedArgValues;
14
14
  if (isHelp) {
15
15
  console.log(helpText);
16
16
  process.exit(0);
@@ -37,7 +37,6 @@ const run = async () => {
37
37
  isFilesShorthand,
38
38
  isFix: isFix || fixTypes.length > 0,
39
39
  isFormat,
40
- isDisableConfigHints,
41
40
  isIncludeEntryExports,
42
41
  isIncludeLibs,
43
42
  isIsolateWorkspaces,
@@ -50,6 +49,7 @@ const run = async () => {
50
49
  tsConfigFile: tsConfig,
51
50
  workspace,
52
51
  });
52
+ const isDisableConfigHints = isNoConfigHints || isProduction || Boolean(workspace);
53
53
  if (isWatch || isTrace)
54
54
  return;
55
55
  const initialData = {
@@ -17,14 +17,12 @@ interface AnalyzeOptions {
17
17
  fixer: IssueFixer;
18
18
  graph: ModuleGraph;
19
19
  isFix: boolean;
20
- isDisableConfigHints: boolean;
21
20
  isIncludeLibs: boolean;
22
21
  isProduction: boolean;
23
22
  report: Report;
24
23
  streamer: ConsoleStreamer;
25
24
  tags: Tags;
26
25
  unreferencedFiles: Set<string>;
27
- workspace?: string;
28
26
  }
29
27
  export declare const analyze: (options: AnalyzeOptions) => Promise<() => Promise<void>>;
30
28
  export {};
@@ -5,13 +5,12 @@ import { findMatch } from '../util/regex.js';
5
5
  import { getShouldIgnoreHandler, getShouldIgnoreTagHandler } from '../util/tag.js';
6
6
  import { createAndPrintTrace, printTrace } from '../util/trace.js';
7
7
  export const analyze = async (options) => {
8
- const { analyzedFiles, chief, collector, deputy, entryPaths, factory, fixer, graph, isFix, isDisableConfigHints, isIncludeLibs, isProduction, report, streamer, tags, unreferencedFiles, workspace, } = options;
8
+ const { analyzedFiles, chief, collector, deputy, entryPaths, factory, fixer, graph, isFix, isIncludeLibs, isProduction, report, streamer, tags, unreferencedFiles, } = options;
9
9
  const isReportDependencies = report.dependencies || report.unlisted || report.unresolved;
10
10
  const isReportValues = report.exports || report.nsExports || report.classMembers;
11
11
  const isReportTypes = report.types || report.nsTypes || report.enumMembers;
12
12
  const isReportClassMembers = report.classMembers;
13
13
  const isSkipLibs = !(isIncludeLibs || isReportClassMembers);
14
- const isShowConfigHints = !workspace && !isProduction && !isDisableConfigHints;
15
14
  const shouldIgnore = getShouldIgnoreHandler(isProduction);
16
15
  const shouldIgnoreTags = getShouldIgnoreTagHandler(tags);
17
16
  const isIdentifierReferenced = getIsIdentifierReferencedHandler(graph, entryPaths);
@@ -212,17 +211,13 @@ export const analyze = async (options) => {
212
211
  for (const issue of optionalPeerDependencyIssues)
213
212
  collector.addIssue(issue);
214
213
  deputy.removeIgnoredIssues(collector.getIssues());
215
- if (isShowConfigHints) {
216
- const configurationHints = deputy.getConfigurationHints();
217
- for (const hint of configurationHints)
218
- collector.addConfigurationHint(hint);
219
- }
214
+ const configurationHints = deputy.getConfigurationHints();
215
+ for (const hint of configurationHints)
216
+ collector.addConfigurationHint(hint);
220
217
  }
221
- if (isShowConfigHints) {
222
- const unusedIgnoredWorkspaces = chief.getUnusedIgnoredWorkspaces();
223
- for (const identifier of unusedIgnoredWorkspaces) {
224
- collector.addConfigurationHint({ type: 'ignoreWorkspaces', identifier });
225
- }
218
+ const unusedIgnoredWorkspaces = chief.getUnusedIgnoredWorkspaces();
219
+ for (const identifier of unusedIgnoredWorkspaces) {
220
+ collector.addConfigurationHint({ type: 'ignoreWorkspaces', identifier });
226
221
  }
227
222
  };
228
223
  await analyzeGraph();
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import { debugLogArray, debugLogObject } from './util/debug.js';
12
12
  import { getGitIgnoredHandler } from './util/glob-core.js';
13
13
  import { getWatchHandler } from './util/watch.js';
14
14
  export const main = async (unresolvedConfiguration) => {
15
- const { cacheLocation, cwd, excludedIssueTypes, fixTypes, gitignore, includedIssueTypes, isCache, isDebug, isDependenciesShorthand, isExportsShorthand, isFilesShorthand, isFix, isFormat, isDisableConfigHints, isIncludeEntryExports, isIncludeLibs, isIsolateWorkspaces, isProduction, isRemoveFiles, isShowProgress, isStrict, isWatch, tags, tsConfigFile, workspace, } = unresolvedConfiguration;
15
+ const { cacheLocation, cwd, excludedIssueTypes, fixTypes, gitignore, includedIssueTypes, isCache, isDebug, isDependenciesShorthand, isExportsShorthand, isFilesShorthand, isFix, isFormat, isIncludeEntryExports, isIncludeLibs, isIsolateWorkspaces, isProduction, isRemoveFiles, isShowProgress, isStrict, isWatch, tags, tsConfigFile, workspace, } = unresolvedConfiguration;
16
16
  debugLogObject('*', 'Unresolved configuration (from CLI arguments)', unresolvedConfiguration);
17
17
  const chief = new ConfigurationChief({ cwd, isProduction, isStrict, isIncludeEntryExports, workspace });
18
18
  const deputy = new DependencyDeputy({ isProduction, isStrict });
@@ -73,14 +73,12 @@ export const main = async (unresolvedConfiguration) => {
73
73
  fixer,
74
74
  graph,
75
75
  isFix,
76
- isDisableConfigHints,
77
76
  isIncludeLibs,
78
77
  isProduction,
79
78
  report,
80
79
  streamer,
81
80
  tags: finalTags,
82
81
  unreferencedFiles,
83
- workspace,
84
82
  });
85
83
  const { issues, counters, tagHints, configurationHints } = collector.getIssues();
86
84
  if (isWatch) {
@@ -420,6 +420,7 @@ export declare const Plugins: {
420
420
  isEnabled: import("../types/config.js").IsPluginEnabled;
421
421
  config: string[];
422
422
  production: string[];
423
+ setup: () => Promise<void>;
423
424
  resolveConfig: import("../types/config.js").ResolveConfig<import("./nuxt/types.js").NuxtConfig>;
424
425
  };
425
426
  nx: {
@@ -610,7 +611,7 @@ export declare const Plugins: {
610
611
  title: string;
611
612
  enablers: RegExp[];
612
613
  isEnabled: import("../types/config.js").IsPluginEnabled;
613
- entry: string[];
614
+ production: string[];
614
615
  };
615
616
  'simple-git-hooks': {
616
617
  title: string;
@@ -9,6 +9,7 @@ declare const _default: {
9
9
  isEnabled: IsPluginEnabled;
10
10
  config: string[];
11
11
  production: string[];
12
+ setup: () => Promise<void>;
12
13
  resolveConfig: ResolveConfig<NuxtConfig>;
13
14
  };
14
15
  export default _default;
@@ -3,12 +3,7 @@ import { join } from '../../util/path.js';
3
3
  import { hasDependency } from '../../util/plugin.js';
4
4
  const title = 'Nuxt';
5
5
  const enablers = ['nuxt'];
6
- const isEnabled = ({ dependencies }) => {
7
- const isEnabled = hasDependency(dependencies, enablers);
8
- if (isEnabled && !('defineNuxtConfig' in globalThis))
9
- globalThis.defineNuxtConfig = (c) => c;
10
- return isEnabled;
11
- };
6
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
12
7
  const config = ['nuxt.config.{js,mjs,ts}'];
13
8
  const production = [
14
9
  'app.{vue,jsx,tsx}',
@@ -21,6 +16,11 @@ const production = [
21
16
  'server/middleware/**/*.ts',
22
17
  'server/plugins/**/*.ts',
23
18
  ];
19
+ const setup = async () => {
20
+ if (globalThis && !('defineNuxtConfig' in globalThis)) {
21
+ Object.defineProperty(globalThis, 'defineNuxtConfig', { value: (id) => id });
22
+ }
23
+ };
24
24
  const resolveConfig = async (localConfig) => {
25
25
  const srcDir = localConfig.srcDir ?? '.';
26
26
  const patterns = [
@@ -45,5 +45,6 @@ export default {
45
45
  isEnabled,
46
46
  config,
47
47
  production,
48
+ setup,
48
49
  resolveConfig,
49
50
  };
@@ -3,6 +3,6 @@ declare const _default: {
3
3
  title: string;
4
4
  enablers: RegExp[];
5
5
  isEnabled: IsPluginEnabled;
6
- entry: string[];
6
+ production: string[];
7
7
  };
8
8
  export default _default;
@@ -2,10 +2,10 @@ import { hasDependency } from '../../util/plugin.js';
2
2
  const title = 'Sentry';
3
3
  const enablers = [/^@sentry\//];
4
4
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
5
- const entry = ['sentry.{client,server,edge}.config.{js,ts}'];
5
+ const production = ['sentry.{client,server,edge}.config.{js,ts}'];
6
6
  export default {
7
7
  title,
8
8
  enablers,
9
9
  isEnabled,
10
- entry,
10
+ production,
11
11
  };
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_EXTENSIONS } from '../../constants.js';
1
2
  import { toAlias, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
2
3
  import { join, toPosix } from '../../util/path.js';
3
4
  import { hasDependency } from '../../util/plugin.js';
@@ -98,6 +99,12 @@ export const resolveConfig = async (localConfig, options) => {
98
99
  }
99
100
  if (cfg.resolve?.alias)
100
101
  addAliases(cfg.resolve.alias);
102
+ if (cfg.resolve?.extensions) {
103
+ const customExtensions = cfg.resolve.extensions.filter(ext => ext.startsWith('.') && !DEFAULT_EXTENSIONS.includes(ext));
104
+ for (const ext of customExtensions) {
105
+ inputs.add(toEntry(`src/**/*${ext}`));
106
+ }
107
+ }
101
108
  for (const dependency of findConfigDependencies(cfg, options))
102
109
  inputs.add(dependency);
103
110
  const _entry = cfg.build?.lib?.entry ?? [];
@@ -37,6 +37,7 @@ export interface ViteConfig extends VitestConfig {
37
37
  };
38
38
  resolve?: {
39
39
  alias?: AliasOptions;
40
+ extensions?: string[];
40
41
  };
41
42
  }
42
43
  export type COMMAND = 'dev' | 'serve' | 'build';
@@ -109,9 +109,9 @@ export const findWebpackDependenciesFromConfig = async (config, options) => {
109
109
  inputs.add(toDeferResolve(entry));
110
110
  }
111
111
  }
112
- if (opts.resolve?.alias) {
112
+ const processAlias = (aliases) => {
113
113
  const addStar = (value) => (value.endsWith('*') ? value : join(value, '*').replace(/\/\*\*$/, '/*'));
114
- for (const [alias, value] of Object.entries(opts.resolve.alias)) {
114
+ for (const [alias, value] of Object.entries(aliases)) {
115
115
  if (!value)
116
116
  continue;
117
117
  const prefixes = Array.isArray(value) ? value : [value];
@@ -126,6 +126,12 @@ export const findWebpackDependenciesFromConfig = async (config, options) => {
126
126
  }
127
127
  }
128
128
  }
129
+ };
130
+ if (opts.resolve?.alias) {
131
+ processAlias(opts.resolve.alias);
132
+ }
133
+ if (opts.resolveLoader?.alias) {
134
+ processAlias(opts.resolveLoader.alias);
129
135
  }
130
136
  }
131
137
  }
@@ -5,7 +5,7 @@ export declare const plain: (text: string) => string;
5
5
  export declare const dim: import("picocolors/types.js").Formatter;
6
6
  export declare const getIssueTypeTitle: (reportType: keyof typeof ISSUE_TYPE_TITLE) => string;
7
7
  export declare const getColoredTitle: (title: string, count: number) => string;
8
- export declare const getDimmedTitle: (title: string) => string;
8
+ export declare const getDimmedTitle: (title: string, count: number) => string;
9
9
  type LogIssueLine = {
10
10
  owner?: string;
11
11
  filePath: string;
@@ -8,7 +8,7 @@ export const dim = picocolors.gray;
8
8
  const bright = picocolors.whiteBright;
9
9
  export const getIssueTypeTitle = (reportType) => ISSUE_TYPE_TITLE[reportType];
10
10
  export const getColoredTitle = (title, count) => `${picocolors.yellowBright(picocolors.underline(title))} (${count})`;
11
- export const getDimmedTitle = (title) => `${picocolors.yellow(picocolors.underline(`${title}`))}`;
11
+ export const getDimmedTitle = (title, count) => `${picocolors.yellow(`${picocolors.underline(title)} (${count})`)}`;
12
12
  export const getIssueLine = ({ owner, filePath, symbols, parentSymbol, severity }) => {
13
13
  const symbol = symbols ? `: ${symbols.map(s => s.symbol).join(', ')}` : '';
14
14
  const parent = parentSymbol ? ` (${parentSymbol})` : '';
@@ -12,7 +12,6 @@ export interface CommandLineOptions {
12
12
  isFilesShorthand: boolean;
13
13
  isFix: boolean;
14
14
  isFormat: boolean;
15
- isDisableConfigHints: boolean;
16
15
  isIncludeEntryExports: boolean;
17
16
  isIncludeLibs: boolean;
18
17
  isIsolateWorkspaces: boolean;
@@ -90,6 +90,8 @@ export interface PluginOptions extends BaseOptions {
90
90
  enabledPlugins: string[];
91
91
  getInputsFromScripts: GetInputsFromScriptsPartial;
92
92
  }
93
+ type PluginSetup = (options: PluginOptions) => Promise<void> | void;
94
+ type PluginTeardown = (options: PluginOptions) => Promise<void> | void;
93
95
  export type ResolveConfig<T = any> = (config: T, options: PluginOptions) => Promise<Input[]> | Input[];
94
96
  export type Resolve = (options: PluginOptions) => Promise<Input[]> | Input[];
95
97
  export type GetSourceFile = (filePath: string) => ts.SourceFile | undefined;
@@ -109,6 +111,8 @@ export interface Plugin {
109
111
  entry?: string[];
110
112
  production?: string[];
111
113
  project?: string[];
114
+ setup?: PluginSetup;
115
+ teardown?: PluginTeardown;
112
116
  resolveConfig?: ResolveConfig;
113
117
  resolve?: Resolve;
114
118
  resolveFromAST?: ResolveFromAST;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.57.2";
1
+ export declare const version = "5.58.1";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.57.2';
1
+ export const version = '5.58.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.57.2",
3
+ "version": "5.58.1",
4
4
  "description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://knip.dev",
6
6
  "repository": {