knip 5.63.0 → 5.64.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.
Files changed (146) hide show
  1. package/dist/CacheConsultant.d.ts +3 -9
  2. package/dist/CacheConsultant.js +5 -5
  3. package/dist/ConfigurationChief.d.ts +597 -38
  4. package/dist/ConfigurationChief.js +33 -122
  5. package/dist/ConsoleStreamer.d.ts +2 -3
  6. package/dist/ConsoleStreamer.js +2 -2
  7. package/dist/DependencyDeputy.d.ts +2 -6
  8. package/dist/DependencyDeputy.js +3 -2
  9. package/dist/IssueCollector.d.ts +4 -12
  10. package/dist/IssueCollector.js +9 -9
  11. package/dist/IssueFixer.d.ts +3 -14
  12. package/dist/IssueFixer.js +14 -22
  13. package/dist/PrincipalFactory.d.ts +3 -2
  14. package/dist/PrincipalFactory.js +11 -11
  15. package/dist/ProjectPrincipal.d.ts +4 -3
  16. package/dist/ProjectPrincipal.js +8 -8
  17. package/dist/WorkspaceWorker.d.ts +4 -9
  18. package/dist/WorkspaceWorker.js +8 -12
  19. package/dist/binaries/bash-parser.d.ts +1 -0
  20. package/dist/binaries/bash-parser.js +4 -1
  21. package/dist/binaries/fallback.js +3 -2
  22. package/dist/binaries/package-manager/bun.js +1 -0
  23. package/dist/binaries/package-manager/pnpm.js +6 -1
  24. package/dist/binaries/plugins.js +3 -1
  25. package/dist/cli.js +43 -61
  26. package/dist/compilers/index.d.ts +34 -4
  27. package/dist/constants.js +2 -0
  28. package/dist/graph/analyze.d.ts +3 -8
  29. package/dist/graph/analyze.js +31 -31
  30. package/dist/graph/build.d.ts +3 -17
  31. package/dist/graph/build.js +49 -46
  32. package/dist/index.d.ts +3 -7
  33. package/dist/index.js +22 -62
  34. package/dist/plugins/angular/index.js +2 -3
  35. package/dist/plugins/bumpp/index.d.ts +8 -0
  36. package/dist/plugins/bumpp/index.js +11 -0
  37. package/dist/plugins/eslint/index.d.ts +7 -0
  38. package/dist/plugins/eslint/index.js +12 -0
  39. package/dist/plugins/glob/index.d.ts +0 -1
  40. package/dist/plugins/glob/index.js +0 -1
  41. package/dist/plugins/index.d.ts +24 -7
  42. package/dist/plugins/index.js +6 -0
  43. package/dist/plugins/karma/helpers.js +1 -1
  44. package/dist/plugins/node-modules-inspector/index.d.ts +0 -1
  45. package/dist/plugins/node-modules-inspector/index.js +0 -1
  46. package/dist/plugins/nuxt/index.js +10 -3
  47. package/dist/plugins/nuxt/types.d.ts +3 -2
  48. package/dist/plugins/oxlint/index.d.ts +0 -1
  49. package/dist/plugins/oxlint/index.js +0 -1
  50. package/dist/plugins/playwright/index.d.ts +0 -1
  51. package/dist/plugins/playwright/index.js +0 -1
  52. package/dist/plugins/playwright-test/index.d.ts +0 -1
  53. package/dist/plugins/playwright-test/index.js +0 -1
  54. package/dist/plugins/pnpm/index.d.ts +8 -0
  55. package/dist/plugins/pnpm/index.js +12 -0
  56. package/dist/plugins/prisma/index.d.ts +0 -1
  57. package/dist/plugins/prisma/index.js +0 -1
  58. package/dist/plugins/rsbuild/index.js +23 -6
  59. package/dist/plugins/rsbuild/types.d.ts +3 -0
  60. package/dist/plugins/rslib/index.js +1 -1
  61. package/dist/plugins/rstest/index.d.ts +10 -0
  62. package/dist/plugins/rstest/index.js +29 -0
  63. package/dist/plugins/rstest/types.d.ts +6 -0
  64. package/dist/plugins/ts-node/index.d.ts +0 -1
  65. package/dist/plugins/ts-node/index.js +0 -1
  66. package/dist/plugins.js +3 -2
  67. package/dist/reporters/codeclimate.d.ts +1 -1
  68. package/dist/reporters/codeclimate.js +10 -10
  69. package/dist/reporters/codeowners.d.ts +1 -1
  70. package/dist/reporters/codeowners.js +5 -5
  71. package/dist/reporters/compact.d.ts +1 -1
  72. package/dist/reporters/compact.js +7 -7
  73. package/dist/reporters/disclosure.d.ts +1 -1
  74. package/dist/reporters/disclosure.js +2 -2
  75. package/dist/reporters/githubActions.d.ts +3 -0
  76. package/dist/reporters/githubActions.js +94 -0
  77. package/dist/reporters/index.d.ts +7 -6
  78. package/dist/reporters/index.js +2 -0
  79. package/dist/reporters/json.d.ts +1 -1
  80. package/dist/reporters/json.js +4 -4
  81. package/dist/reporters/markdown.d.ts +1 -1
  82. package/dist/reporters/markdown.js +4 -4
  83. package/dist/reporters/symbols.js +1 -1
  84. package/dist/reporters/util/configuration-hints.d.ts +14 -2
  85. package/dist/reporters/util/configuration-hints.js +7 -7
  86. package/dist/reporters/util/util.d.ts +2 -2
  87. package/dist/reporters/util/util.js +4 -4
  88. package/dist/reporters/watch.d.ts +3 -4
  89. package/dist/reporters/watch.js +5 -5
  90. package/dist/schema/configuration.d.ts +176 -8
  91. package/dist/schema/plugins.d.ts +69 -0
  92. package/dist/schema/plugins.js +3 -0
  93. package/dist/types/PluginNames.d.ts +2 -2
  94. package/dist/types/PluginNames.js +3 -0
  95. package/dist/types/args.d.ts +2 -0
  96. package/dist/types/config.d.ts +4 -10
  97. package/dist/types/exports.d.ts +1 -1
  98. package/dist/types/imports.d.ts +1 -1
  99. package/dist/types/issues.d.ts +1 -2
  100. package/dist/types/module-graph.d.ts +5 -4
  101. package/dist/types/{cli.d.ts → options.d.ts} +2 -2
  102. package/dist/types/options.js +1 -0
  103. package/dist/types/package-json.d.ts +1 -0
  104. package/dist/types/project.d.ts +1 -7
  105. package/dist/typescript/SourceFile.d.ts +2 -2
  106. package/dist/typescript/ast-helpers.d.ts +4 -0
  107. package/dist/typescript/ast-helpers.js +29 -0
  108. package/dist/typescript/find-internal-references.js +10 -1
  109. package/dist/typescript/get-imports-and-exports.d.ts +2 -2
  110. package/dist/typescript/get-imports-and-exports.js +32 -23
  111. package/dist/typescript/visitors/dynamic-imports/importCall.js +6 -1
  112. package/dist/util/Performance.js +16 -6
  113. package/dist/util/cli-arguments.d.ts +3 -3
  114. package/dist/util/cli-arguments.js +4 -14
  115. package/dist/util/create-options.d.ts +1238 -0
  116. package/dist/util/create-options.js +112 -0
  117. package/dist/util/debug.js +3 -4
  118. package/dist/util/errors.d.ts +1 -1
  119. package/dist/util/file-entry-cache.js +3 -3
  120. package/dist/util/get-included-issue-types.d.ts +9 -13
  121. package/dist/util/get-included-issue-types.js +10 -16
  122. package/dist/util/get-referenced-inputs.js +1 -1
  123. package/dist/util/input.d.ts +1 -1
  124. package/dist/util/input.js +1 -1
  125. package/dist/util/is-identifier-referenced.d.ts +1 -1
  126. package/dist/util/is-identifier-referenced.js +2 -2
  127. package/dist/util/load-config.d.ts +2 -0
  128. package/dist/util/load-config.js +24 -0
  129. package/dist/util/modules.js +18 -7
  130. package/dist/util/path.d.ts +4 -4
  131. package/dist/util/path.js +5 -7
  132. package/dist/util/require.js +1 -2
  133. package/dist/util/tag.d.ts +1 -1
  134. package/dist/util/to-source-path.d.ts +1 -1
  135. package/dist/util/to-source-path.js +5 -5
  136. package/dist/util/trace.d.ts +6 -6
  137. package/dist/util/trace.js +18 -22
  138. package/dist/util/watch.d.ts +2 -5
  139. package/dist/util/watch.js +3 -3
  140. package/dist/version.d.ts +1 -1
  141. package/dist/version.js +1 -1
  142. package/package.json +4 -4
  143. package/schema.json +12 -0
  144. package/dist/util/unwrap-function.d.ts +0 -1
  145. package/dist/util/unwrap-function.js +0 -13
  146. /package/dist/{types/cli.js → plugins/rstest/types.js} +0 -0
@@ -1,29 +1,19 @@
1
1
  import path from 'node:path';
2
2
  import picomatch from 'picomatch';
3
- import { partitionCompilers } from './compilers/index.js';
4
- import { DEFAULT_EXTENSIONS, KNIP_CONFIG_LOCATIONS, ROOT_WORKSPACE_NAME } from './constants.js';
5
- import { knipConfigurationSchema } from './schema/configuration.js';
3
+ import { DEFAULT_EXTENSIONS, ROOT_WORKSPACE_NAME } from './constants.js';
6
4
  import { pluginNames } from './types/PluginNames.js';
7
5
  import { arrayify, compact, partition } from './util/array.js';
8
- import parsedArgValues from './util/cli-arguments.js';
9
6
  import { createWorkspaceGraph } from './util/create-workspace-graph.js';
10
7
  import { ConfigurationError } from './util/errors.js';
11
- import { findFile, isDirectory, isFile, loadJSON } from './util/fs.js';
12
- import { getIncludedIssueTypes } from './util/get-included-issue-types.js';
8
+ import { isDirectory, isFile } from './util/fs.js';
13
9
  import { _dirGlob, removeProductionSuffix } from './util/glob.js';
14
10
  import { graphSequencer } from './util/graph-sequencer.js';
15
- import { defaultRules } from './util/issue-initializers.js';
16
- import { _load } from './util/loader.js';
17
11
  import mapWorkspaces from './util/map-workspaces.js';
18
- import { getKeysByValue } from './util/object.js';
19
- import { isAbsolute, join, relative } from './util/path.js';
12
+ import { join, relative } from './util/path.js';
20
13
  import { normalizePluginConfig } from './util/plugin.js';
21
14
  import { toRegexOrString } from './util/regex.js';
22
15
  import { ELLIPSIS } from './util/string.js';
23
- import { splitTags } from './util/tag.js';
24
- import { unwrapFunction } from './util/unwrap-function.js';
25
16
  import { byPathDepth } from './util/workspace.js';
26
- const { config: rawConfigArg } = parsedArgValues;
27
17
  const defaultBaseFilenamePattern = '{index,cli,main}';
28
18
  export const isDefaultPattern = (type, id) => {
29
19
  if (type === 'project')
@@ -40,31 +30,27 @@ const getDefaultWorkspaceConfig = (extensions = []) => {
40
30
  };
41
31
  const isPluginName = (name) => pluginNames.includes(name);
42
32
  const defaultConfig = {
43
- rules: defaultRules,
44
- include: [],
45
- exclude: [],
46
33
  ignore: [],
47
34
  ignoreBinaries: [],
48
35
  ignoreDependencies: [],
49
36
  ignoreMembers: [],
50
- ignoreExportsUsedInFile: false,
37
+ ignoreUnresolved: [],
51
38
  ignoreWorkspaces: [],
39
+ ignoreExportsUsedInFile: false,
52
40
  isIncludeEntryExports: false,
53
- isTreatConfigHintsAsErrors: false,
54
41
  syncCompilers: new Map(),
55
42
  asyncCompilers: new Map(),
56
43
  rootPluginConfigs: {},
57
- tags: [],
58
44
  };
59
45
  export class ConfigurationChief {
60
46
  cwd;
61
- isProduction = false;
62
- isStrict = false;
63
- isIncludeEntryExports = false;
47
+ rawConfig;
48
+ isProduction;
49
+ isStrict;
50
+ isIncludeEntryExports;
64
51
  config;
65
52
  workspace;
66
- manifestPath;
67
- manifest;
53
+ workspaces;
68
54
  ignoredWorkspacePatterns = [];
69
55
  workspacePackages = new Map();
70
56
  workspacesByPkgName = new Map();
@@ -75,58 +61,26 @@ export class ConfigurationChief {
75
61
  availableWorkspaceDirs = [];
76
62
  workspaceGraph = new Map();
77
63
  includedWorkspaces = [];
78
- resolvedConfigFilePath;
79
- rawConfig;
80
- parsedConfig;
81
- constructor({ cwd, isProduction, isStrict, isIncludeEntryExports, workspace }) {
82
- this.cwd = cwd;
83
- this.isProduction = isProduction;
84
- this.isStrict = isStrict;
85
- this.isIncludeEntryExports = isIncludeEntryExports;
86
- this.config = defaultConfig;
87
- this.workspace = workspace;
88
- }
89
- async init() {
90
- const manifestPath = findFile(this.cwd, 'package.json');
91
- const manifest = manifestPath && (await loadJSON(manifestPath));
92
- if (!(manifestPath && manifest)) {
93
- throw new ConfigurationError('Unable to find package.json');
94
- }
95
- this.manifestPath = manifestPath;
96
- this.manifest = manifest;
97
- const pnpmWorkspacesPath = findFile(this.cwd, 'pnpm-workspace.yaml');
98
- const pnpmWorkspaces = pnpmWorkspacesPath && (await _load(pnpmWorkspacesPath));
99
- if (this.manifest && pnpmWorkspaces) {
100
- this.manifest.workspaces = pnpmWorkspaces;
101
- }
102
- for (const configPath of rawConfigArg ? [rawConfigArg] : KNIP_CONFIG_LOCATIONS) {
103
- this.resolvedConfigFilePath = isAbsolute(configPath) ? configPath : findFile(this.cwd, configPath);
104
- if (this.resolvedConfigFilePath)
105
- break;
106
- }
107
- if (rawConfigArg && !this.resolvedConfigFilePath && !manifest.knip) {
108
- throw new ConfigurationError(`Unable to find ${rawConfigArg} or package.json#knip`);
109
- }
110
- this.rawConfig = this.resolvedConfigFilePath
111
- ? await this.loadResolvedConfigurationFile(this.resolvedConfigFilePath)
112
- : manifest.knip;
113
- if (manifest.knip)
114
- this.resolvedConfigFilePath = manifestPath;
115
- this.parsedConfig = this.rawConfig ? knipConfigurationSchema.parse(partitionCompilers(this.rawConfig)) : {};
116
- this.config = this.normalize(this.parsedConfig);
117
- await this.setWorkspaces();
64
+ constructor(options) {
65
+ this.cwd = options.cwd;
66
+ this.isProduction = options.isProduction;
67
+ this.isStrict = options.isStrict;
68
+ this.isIncludeEntryExports = options.isIncludeEntryExports;
69
+ this.workspace = options.workspace;
70
+ this.workspaces = options.workspaces;
71
+ this.rawConfig = options.parsedConfig;
72
+ this.config = this.normalize(options.parsedConfig ?? {});
118
73
  }
119
74
  getConfigurationHints() {
120
75
  const hints = new Set();
121
- const config = this.parsedConfig;
122
- if (config) {
76
+ if (this.rawConfig) {
123
77
  if (this.workspacePackages.size > 1) {
124
- const entry = arrayify(config.entry);
78
+ const entry = arrayify(this.rawConfig.entry);
125
79
  if (entry.length > 0) {
126
80
  const identifier = `[${entry[0]}${entry.length > 1 ? `, ${ELLIPSIS}` : ''}]`;
127
81
  hints.add({ type: 'entry-top-level', identifier });
128
82
  }
129
- const project = arrayify(config.project);
83
+ const project = arrayify(this.rawConfig.project);
130
84
  if (project.length > 0) {
131
85
  const identifier = `[${project[0]}${project.length > 1 ? `, ${ELLIPSIS}` : ''}]`;
132
86
  hints.add({ type: 'project-top-level', identifier });
@@ -135,35 +89,15 @@ export class ConfigurationChief {
135
89
  }
136
90
  return hints;
137
91
  }
138
- async loadResolvedConfigurationFile(configPath) {
139
- const loadedValue = await _load(configPath);
140
- try {
141
- return await unwrapFunction(loadedValue);
142
- }
143
- catch (_error) {
144
- throw new ConfigurationError(`Error running the function from ${configPath}`);
145
- }
146
- }
147
- getRules() {
148
- return this.config.rules;
149
- }
150
- getFilters() {
151
- if (this.workspaceGraph && this.workspace)
152
- return { dir: join(this.cwd, this.workspace) };
153
- return {};
154
- }
155
92
  normalize(rawConfig) {
156
- const rules = { ...defaultRules, ...rawConfig.rules };
157
- const include = rawConfig.include ?? defaultConfig.include;
158
- const exclude = rawConfig.exclude ?? defaultConfig.exclude;
159
93
  const ignore = arrayify(rawConfig.ignore ?? defaultConfig.ignore);
160
94
  const ignoreBinaries = rawConfig.ignoreBinaries ?? [];
161
95
  const ignoreDependencies = rawConfig.ignoreDependencies ?? [];
162
96
  const ignoreMembers = rawConfig.ignoreMembers ?? [];
97
+ const ignoreUnresolved = rawConfig.ignoreUnresolved ?? [];
163
98
  const ignoreExportsUsedInFile = rawConfig.ignoreExportsUsedInFile ?? false;
164
99
  const ignoreWorkspaces = rawConfig.ignoreWorkspaces ?? defaultConfig.ignoreWorkspaces;
165
100
  const isIncludeEntryExports = rawConfig.includeEntryExports ?? this.isIncludeEntryExports;
166
- const isTreatConfigHintsAsErrors = rawConfig.treatConfigHintsAsErrors ?? defaultConfig.isTreatConfigHintsAsErrors;
167
101
  const { syncCompilers, asyncCompilers } = rawConfig;
168
102
  const rootPluginConfigs = {};
169
103
  for (const [pluginName, pluginConfig] of Object.entries(rawConfig)) {
@@ -172,24 +106,20 @@ export class ConfigurationChief {
172
106
  }
173
107
  }
174
108
  return {
175
- rules,
176
- include,
177
- exclude,
178
109
  ignore,
179
110
  ignoreBinaries,
180
111
  ignoreDependencies,
181
112
  ignoreMembers,
113
+ ignoreUnresolved,
182
114
  ignoreExportsUsedInFile,
183
115
  ignoreWorkspaces,
184
116
  isIncludeEntryExports,
185
117
  syncCompilers: new Map(Object.entries(syncCompilers ?? {})),
186
118
  asyncCompilers: new Map(Object.entries(asyncCompilers ?? {})),
187
119
  rootPluginConfigs,
188
- tags: rawConfig.tags ?? [],
189
- isTreatConfigHintsAsErrors,
190
120
  };
191
121
  }
192
- async setWorkspaces() {
122
+ async getWorkspaces() {
193
123
  this.ignoredWorkspacePatterns = this.getIgnoredWorkspacePatterns();
194
124
  this.additionalWorkspaceNames = await this.getAdditionalWorkspaceNames();
195
125
  const workspaceNames = compact([...this.getListedWorkspaces(), ...this.additionalWorkspaceNames]);
@@ -207,14 +137,12 @@ export class ConfigurationChief {
207
137
  this.workspacesByPkgName.set(workspace.pkgName, workspace);
208
138
  this.workspacesByName.set(workspace.name, workspace);
209
139
  }
140
+ const sorted = graphSequencer(this.workspaceGraph, this.includedWorkspaces.map(workspace => workspace.dir));
141
+ const [root, rest] = partition(sorted.chunks.flat(), dir => dir === this.cwd);
142
+ return [...root, ...rest.reverse()].map(dir => this.includedWorkspaces.find(w => w.dir === dir));
210
143
  }
211
144
  getListedWorkspaces() {
212
- const workspaces = this.manifest?.workspaces
213
- ? Array.isArray(this.manifest.workspaces)
214
- ? this.manifest.workspaces
215
- : (this.manifest.workspaces.packages ?? [])
216
- : [];
217
- return workspaces.map(pattern => pattern.replace(/(?<=!?)\.\//, ''));
145
+ return this.workspaces.map(pattern => pattern.replace(/(?<=!?)\.\//, ''));
218
146
  }
219
147
  getIgnoredWorkspaces() {
220
148
  const ignoreWorkspaces = this.config.ignoreWorkspaces;
@@ -309,7 +237,7 @@ export class ConfigurationChief {
309
237
  const manifestPath = pkg?.manifestPath ?? join(dir, 'package.json');
310
238
  const manifestStr = pkg?.manifestStr ?? '';
311
239
  const workspaceConfig = this.getWorkspaceConfig(name);
312
- const ignoreMembers = arrayify(workspaceConfig.ignoreMembers).map(toRegexOrString);
240
+ const ignoreMembers = workspaceConfig.ignoreMembers?.map(toRegexOrString) ?? [];
313
241
  return {
314
242
  name,
315
243
  pkgName,
@@ -325,11 +253,6 @@ export class ConfigurationChief {
325
253
  getManifestForWorkspace(name) {
326
254
  return this.workspacePackages.get(name)?.manifest;
327
255
  }
328
- getWorkspaces() {
329
- const sorted = graphSequencer(this.workspaceGraph, this.includedWorkspaces.map(workspace => workspace.dir));
330
- const [root, rest] = partition(sorted.chunks.flat(), dir => dir === this.cwd);
331
- return [...root, ...rest.reverse()].map(dir => this.includedWorkspaces.find(w => w.dir === dir));
332
- }
333
256
  getDescendentWorkspaces(name) {
334
257
  return this.availableWorkspaceNames
335
258
  .filter(workspaceName => workspaceName !== name)
@@ -366,9 +289,9 @@ export class ConfigurationChief {
366
289
  }
367
290
  getIgnores(workspaceName) {
368
291
  const workspaceConfig = this.getWorkspaceConfig(workspaceName);
369
- const ignoreBinaries = arrayify(workspaceConfig.ignoreBinaries);
370
- const ignoreDependencies = arrayify(workspaceConfig.ignoreDependencies);
371
- const ignoreUnresolved = arrayify(workspaceConfig.ignoreUnresolved);
292
+ const ignoreBinaries = workspaceConfig.ignoreBinaries ?? [];
293
+ const ignoreDependencies = workspaceConfig.ignoreDependencies ?? [];
294
+ const ignoreUnresolved = workspaceConfig.ignoreUnresolved ?? [];
372
295
  if (workspaceName === ROOT_WORKSPACE_NAME) {
373
296
  const { ignoreBinaries: rootIgnoreBinaries, ignoreDependencies: rootIgnoreDependencies, ignoreUnresolved: rootIgnoreUnresolved, } = this.rawConfig ?? {};
374
297
  return {
@@ -399,15 +322,6 @@ export class ConfigurationChief {
399
322
  }
400
323
  return { entry, project, paths, ignore, isIncludeEntryExports, ...plugins };
401
324
  }
402
- getIncludedIssueTypes(cliArgs) {
403
- const excludesFromRules = getKeysByValue(this.config.rules, 'off');
404
- const config = {
405
- include: this.config.include ?? [],
406
- exclude: [...excludesFromRules, ...this.config.exclude],
407
- isProduction: this.isProduction,
408
- };
409
- return getIncludedIssueTypes(cliArgs, config);
410
- }
411
325
  findWorkspaceByFilePath(filePath) {
412
326
  const workspaceDir = this.availableWorkspaceDirs.find(workspaceDir => filePath.startsWith(`${workspaceDir}/`));
413
327
  return this.includedWorkspaces.find(workspace => workspace.dir === workspaceDir);
@@ -422,7 +336,4 @@ export class ConfigurationChief {
422
336
  return !isDirectory(dir) || isFile(join(dir, 'package.json'));
423
337
  });
424
338
  }
425
- getTags() {
426
- return splitTags(this.config.tags);
427
- }
428
339
  }
@@ -1,9 +1,8 @@
1
+ import type { MainOptions } from './util/create-options.js';
1
2
  export declare class ConsoleStreamer {
2
3
  isEnabled: boolean;
3
4
  private lines;
4
- constructor({ isEnabled }: {
5
- isEnabled?: boolean | undefined;
6
- });
5
+ constructor(options: MainOptions);
7
6
  private clearLines;
8
7
  private resetLines;
9
8
  private update;
@@ -1,8 +1,8 @@
1
1
  export class ConsoleStreamer {
2
2
  isEnabled = false;
3
3
  lines = 0;
4
- constructor({ isEnabled = false }) {
5
- this.isEnabled = isEnabled;
4
+ constructor(options) {
5
+ this.isEnabled = options.isShowProgress;
6
6
  }
7
7
  clearLines(count) {
8
8
  if (count > 0) {
@@ -2,10 +2,7 @@ import type { Workspace } from './ConfigurationChief.js';
2
2
  import type { ConfigurationHints, Counters, Issue, Issues, SymbolIssueType } from './types/issues.js';
3
3
  import type { PackageJson } from './types/package-json.js';
4
4
  import type { DependencyArray, DependencySet, HostDependencies, InstalledBinaries, WorkspaceManifests } from './types/workspace.js';
5
- type Options = {
6
- isProduction: boolean;
7
- isStrict: boolean;
8
- };
5
+ import type { MainOptions } from './util/create-options.js';
9
6
  export declare class DependencyDeputy {
10
7
  isProduction: boolean;
11
8
  isStrict: boolean;
@@ -15,7 +12,7 @@ export declare class DependencyDeputy {
15
12
  hostDependencies: Map<string, HostDependencies>;
16
13
  installedBinaries: Map<string, InstalledBinaries>;
17
14
  hasTypesIncluded: Map<string, Set<string>>;
18
- constructor({ isProduction, isStrict }: Options);
15
+ constructor({ isProduction, isStrict }: MainOptions);
19
16
  addWorkspace({ name, cwd, dir, manifestPath, manifestStr, manifest, ignoreDependencies: id, ignoreBinaries: ib, ignoreUnresolved: iu, }: {
20
17
  name: string;
21
18
  cwd: string;
@@ -77,4 +74,3 @@ export declare class DependencyDeputy {
77
74
  addIgnoredDependencies(workspaceName: string, identifier: string): void;
78
75
  addIgnoredBinaries(workspaceName: string, identifier: string): void;
79
76
  }
80
- export {};
@@ -4,6 +4,7 @@ import { DT_SCOPE, IGNORED_DEPENDENCIES, IGNORED_GLOBAL_BINARIES, IGNORED_RUNTIM
4
4
  import { getDependencyMetaData } from './manifest/index.js';
5
5
  import { getDefinitelyTypedFor, getPackageFromDefinitelyTyped, getPackageNameFromModuleSpecifier, isDefinitelyTyped, } from './util/modules.js';
6
6
  import { findMatch, toRegexOrString } from './util/regex.js';
7
+ const filterIsProduction = (id, isProduction) => typeof id === 'string' ? (isProduction || !id.endsWith('!') ? id.replace(/!$/, '') : []) : id;
7
8
  export class DependencyDeputy {
8
9
  isProduction;
9
10
  isStrict;
@@ -46,8 +47,8 @@ export class DependencyDeputy {
46
47
  this.setHostDependencies(name, hostDependencies);
47
48
  this.setInstalledBinaries(name, installedBinaries);
48
49
  this.setHasTypesIncluded(name, hasTypesIncluded);
49
- const ignoreDependencies = id.map(toRegexOrString);
50
- const ignoreBinaries = ib.map(toRegexOrString);
50
+ const ignoreDependencies = id.flatMap(id => filterIsProduction(id, this.isProduction)).map(toRegexOrString);
51
+ const ignoreBinaries = ib.flatMap(ib => filterIsProduction(ib, this.isProduction)).map(toRegexOrString);
51
52
  const ignoreUnresolved = iu.map(toRegexOrString);
52
53
  this._manifests.set(name, {
53
54
  workspaceDir: dir,
@@ -1,16 +1,9 @@
1
- import type { ConfigurationHint, Issue, Rules, TagHint } from './types/issues.js';
2
- type Filters = Partial<{
3
- dir: string;
4
- }>;
5
- type IssueCollectorOptions = {
6
- cwd: string;
7
- rules: Rules;
8
- filters: Filters;
9
- };
1
+ import type { ConfigurationHint, Issue, TagHint } from './types/issues.js';
2
+ import type { MainOptions } from './util/create-options.js';
10
3
  export declare class IssueCollector {
11
4
  private cwd;
12
5
  private rules;
13
- private filters;
6
+ private filter;
14
7
  private issues;
15
8
  private counters;
16
9
  private referencedFiles;
@@ -18,7 +11,7 @@ export declare class IssueCollector {
18
11
  private tagHints;
19
12
  private ignorePatterns;
20
13
  private isMatch;
21
- constructor({ cwd, rules, filters }: IssueCollectorOptions);
14
+ constructor(options: MainOptions);
22
15
  addIgnorePatterns(patterns: string[]): void;
23
16
  addFileCounts({ processed, unused }: {
24
17
  processed: number;
@@ -36,4 +29,3 @@ export declare class IssueCollector {
36
29
  configurationHints: Set<ConfigurationHint>;
37
30
  };
38
31
  }
39
- export {};
@@ -1,13 +1,13 @@
1
1
  import picomatch from 'picomatch';
2
2
  import { timerify } from './util/Performance.js';
3
3
  import { initCounters, initIssues } from './util/issue-initializers.js';
4
- import { relative } from './util/path.js';
4
+ import { join, relative } from './util/path.js';
5
5
  const hasConfigurationHint = (hints, hint) => Array.from(hints).some(item => item.identifier === hint.identifier && item.type === hint.type && item.workspaceName === hint.workspaceName);
6
6
  const isMatch = timerify(picomatch.isMatch, 'isMatch');
7
7
  export class IssueCollector {
8
8
  cwd;
9
9
  rules;
10
- filters;
10
+ filter;
11
11
  issues = initIssues();
12
12
  counters = initCounters();
13
13
  referencedFiles = new Set();
@@ -15,10 +15,10 @@ export class IssueCollector {
15
15
  tagHints = new Set();
16
16
  ignorePatterns = new Set();
17
17
  isMatch;
18
- constructor({ cwd, rules, filters }) {
19
- this.cwd = cwd;
20
- this.rules = rules;
21
- this.filters = filters;
18
+ constructor(options) {
19
+ this.cwd = options.cwd;
20
+ this.rules = options.rules;
21
+ this.filter = options.workspace ? join(options.cwd, options.workspace) : undefined;
22
22
  this.isMatch = () => false;
23
23
  }
24
24
  addIgnorePatterns(patterns) {
@@ -33,21 +33,21 @@ export class IssueCollector {
33
33
  }
34
34
  addFilesIssues(filePaths) {
35
35
  for (const filePath of filePaths) {
36
- if (this.filters.dir && !filePath.startsWith(`${this.filters.dir}/`))
36
+ if (this.filter && !filePath.startsWith(`${this.filter}/`))
37
37
  continue;
38
38
  if (this.referencedFiles.has(filePath))
39
39
  continue;
40
40
  if (this.isMatch(filePath))
41
41
  continue;
42
42
  this.issues.files.add(filePath);
43
- const symbol = relative(filePath);
43
+ const symbol = relative(this.cwd, filePath);
44
44
  this.issues._files[symbol] = [{ type: 'files', filePath, symbol, severity: this.rules.files }];
45
45
  this.counters.files++;
46
46
  this.counters.processed++;
47
47
  }
48
48
  }
49
49
  addIssue(issue) {
50
- if (this.filters.dir && !issue.filePath.startsWith(`${this.filters.dir}/`))
50
+ if (this.filter && !issue.filePath.startsWith(`${this.filter}/`))
51
51
  return;
52
52
  if (this.isMatch(issue.filePath))
53
53
  return;
@@ -1,21 +1,11 @@
1
1
  import type { Fix, Fixes } from './types/exports.js';
2
2
  import type { Issues } from './types/issues.js';
3
- interface Fixer {
4
- isEnabled: boolean;
5
- cwd: string;
6
- fixTypes: string[];
7
- isRemoveFiles: boolean;
8
- }
3
+ import type { MainOptions } from './util/create-options.js';
9
4
  export declare class IssueFixer {
10
- isEnabled: boolean;
11
- cwd: string;
12
- isFixFiles: boolean;
13
- isFixDependencies: boolean;
14
- isFixUnusedTypes: boolean;
15
- isFixUnusedExports: boolean;
5
+ options: MainOptions;
16
6
  unusedTypeNodes: Map<string, Set<Fix>>;
17
7
  unusedExportNodes: Map<string, Set<Fix>>;
18
- constructor({ isEnabled, cwd, fixTypes, isRemoveFiles }: Fixer);
8
+ constructor(options: MainOptions);
19
9
  addUnusedTypeNode(filePath: string, fixes: Fixes | undefined): void;
20
10
  addUnusedExportNode(filePath: string, fixes: Fixes | undefined): void;
21
11
  fixIssues(issues: Issues): Promise<Set<string>>;
@@ -24,4 +14,3 @@ export declare class IssueFixer {
24
14
  private removeUnusedExports;
25
15
  private removeUnusedDependencies;
26
16
  }
27
- export {};
@@ -3,21 +3,11 @@ import { load, save } from './util/package-json.js';
3
3
  import { join, relative } from './util/path.js';
4
4
  import { removeExport } from './util/remove-export.js';
5
5
  export class IssueFixer {
6
- isEnabled = false;
7
- cwd = process.cwd();
8
- isFixFiles = true;
9
- isFixDependencies = true;
10
- isFixUnusedTypes = true;
11
- isFixUnusedExports = true;
6
+ options;
12
7
  unusedTypeNodes = new Map();
13
8
  unusedExportNodes = new Map();
14
- constructor({ isEnabled, cwd, fixTypes = [], isRemoveFiles }) {
15
- this.isEnabled = isEnabled;
16
- this.cwd = cwd;
17
- this.isFixFiles = isRemoveFiles && (fixTypes.length === 0 || fixTypes.includes('files'));
18
- this.isFixDependencies = fixTypes.length === 0 || fixTypes.includes('dependencies');
19
- this.isFixUnusedTypes = fixTypes.length === 0 || fixTypes.includes('types');
20
- this.isFixUnusedExports = fixTypes.length === 0 || fixTypes.includes('exports');
9
+ constructor(options) {
10
+ this.options = options;
21
11
  }
22
12
  addUnusedTypeNode(filePath, fixes) {
23
13
  if (!fixes || fixes.length === 0)
@@ -47,10 +37,10 @@ export class IssueFixer {
47
37
  return touchedFiles;
48
38
  }
49
39
  markExportFixed(issues, filePath) {
50
- const relPath = relative(filePath);
40
+ const relPath = relative(this.options.cwd, filePath);
51
41
  const types = [
52
- ...(this.isFixUnusedTypes ? ['types', 'nsTypes', 'classMembers', 'enumMembers'] : []),
53
- ...(this.isFixUnusedExports ? ['exports', 'nsExports'] : []),
42
+ ...(this.options.isFixUnusedTypes ? ['types', 'nsTypes', 'classMembers', 'enumMembers'] : []),
43
+ ...(this.options.isFixUnusedExports ? ['exports', 'nsExports'] : []),
54
44
  ];
55
45
  for (const type of types) {
56
46
  for (const id in issues[type][relPath]) {
@@ -59,7 +49,7 @@ export class IssueFixer {
59
49
  }
60
50
  }
61
51
  async removeUnusedFiles(issues) {
62
- if (!this.isFixFiles)
52
+ if (!this.options.isFixFiles)
63
53
  return;
64
54
  for (const issue of Object.values(issues._files).flatMap(Object.values)) {
65
55
  await rm(issue.filePath);
@@ -70,9 +60,11 @@ export class IssueFixer {
70
60
  const touchedFiles = new Set();
71
61
  const filePaths = new Set([...this.unusedTypeNodes.keys(), ...this.unusedExportNodes.keys()]);
72
62
  for (const filePath of filePaths) {
73
- const types = (this.isFixUnusedTypes && this.unusedTypeNodes.get(filePath)) || [];
74
- const exports = (this.isFixUnusedExports && this.unusedExportNodes.get(filePath)) || [];
75
- const exportPositions = [...types, ...exports].filter(fix => fix !== undefined).sort((a, b) => b[0] - a[0]);
63
+ const types = (this.options.isFixUnusedTypes && this.unusedTypeNodes.get(filePath)) || [];
64
+ const exports = (this.options.isFixUnusedExports && this.unusedExportNodes.get(filePath)) || [];
65
+ const exportPositions = [...types, ...exports]
66
+ .filter((fix) => fix !== undefined)
67
+ .sort((a, b) => b[0] - a[0]);
76
68
  if (exportPositions.length > 0) {
77
69
  const sourceFileText = exportPositions.reduce((text, [start, end, flags]) => removeExport({ text, start, end, flags }), await readFile(filePath, 'utf-8'));
78
70
  await writeFile(filePath, sourceFileText);
@@ -84,11 +76,11 @@ export class IssueFixer {
84
76
  }
85
77
  async removeUnusedDependencies(issues) {
86
78
  const touchedFiles = new Set();
87
- if (!this.isFixDependencies)
79
+ if (!this.options.isFixDependencies)
88
80
  return touchedFiles;
89
81
  const filePaths = new Set([...Object.keys(issues.dependencies), ...Object.keys(issues.devDependencies)]);
90
82
  for (const filePath of filePaths) {
91
- const absFilePath = join(this.cwd, filePath);
83
+ const absFilePath = join(this.options.cwd, filePath);
92
84
  const pkg = await load(absFilePath);
93
85
  if (filePath in issues.dependencies) {
94
86
  for (const dependency of Object.keys(issues.dependencies[filePath])) {
@@ -1,13 +1,14 @@
1
1
  import { ProjectPrincipal } from './ProjectPrincipal.js';
2
2
  import type { PrincipalOptions } from './types/project.js';
3
+ import type { MainOptions } from './util/create-options.js';
3
4
  export declare class PrincipalFactory {
4
5
  private principals;
5
6
  getPrincipalCount(): number;
6
- createPrincipal(options: PrincipalOptions): ProjectPrincipal;
7
+ createPrincipal(options: MainOptions, opts: PrincipalOptions): ProjectPrincipal;
7
8
  private findReusablePrincipal;
8
9
  private linkPrincipal;
9
10
  private addNewPrincipal;
10
11
  getPrincipals(): ProjectPrincipal[];
11
12
  getPrincipalByPackageName(packageName: string): ProjectPrincipal | undefined;
12
- deletePrincipal(principal: ProjectPrincipal): void;
13
+ deletePrincipal(principal: ProjectPrincipal, cwd: string): void;
13
14
  }
@@ -7,18 +7,18 @@ export class PrincipalFactory {
7
7
  getPrincipalCount() {
8
8
  return this.principals.size;
9
9
  }
10
- createPrincipal(options) {
11
- const { cwd, compilerOptions, isFile, pkgName, isIsolateWorkspaces, compilers } = options;
10
+ createPrincipal(options, opts) {
11
+ const { dir, compilerOptions, isFile, pkgName, compilers } = opts;
12
12
  if (isFile && compilerOptions.module !== ts.ModuleKind.CommonJS)
13
13
  compilerOptions.moduleResolution ??= ts.ModuleResolutionKind.Bundler;
14
- if (!isIsolateWorkspaces) {
14
+ if (!options.isIsolateWorkspaces) {
15
15
  const principal = this.findReusablePrincipal(compilerOptions);
16
16
  if (principal) {
17
- this.linkPrincipal(principal, cwd, compilerOptions, pkgName, compilers);
17
+ this.linkPrincipal(principal, dir, compilerOptions, pkgName, compilers);
18
18
  return principal.principal;
19
19
  }
20
20
  }
21
- return this.addNewPrincipal(options);
21
+ return this.addNewPrincipal(options, opts);
22
22
  }
23
23
  findReusablePrincipal(compilerOptions) {
24
24
  const workspacePaths = compilerOptions?.paths ? Object.keys(compilerOptions.paths) : [];
@@ -43,11 +43,11 @@ export class PrincipalFactory {
43
43
  principal.wsDirs.add(cwd);
44
44
  principal.pkgNames.add(pkgName);
45
45
  }
46
- addNewPrincipal(options) {
47
- const { cwd, compilerOptions, pkgName } = options;
46
+ addNewPrincipal(options, opts) {
47
+ const { dir, compilerOptions, pkgName } = opts;
48
48
  const pathKeys = new Set(Object.keys(compilerOptions?.paths ?? {}));
49
- const principal = new ProjectPrincipal(options);
50
- this.principals.add({ principal, wsDirs: new Set([cwd]), pathKeys, pkgNames: new Set([pkgName]) });
49
+ const principal = new ProjectPrincipal(options, opts);
50
+ this.principals.add({ principal, wsDirs: new Set([dir]), pathKeys, pkgNames: new Set([pkgName]) });
51
51
  return principal;
52
52
  }
53
53
  getPrincipals() {
@@ -56,10 +56,10 @@ export class PrincipalFactory {
56
56
  getPrincipalByPackageName(packageName) {
57
57
  return Array.from(this.principals).find(principal => principal.pkgNames.has(packageName))?.principal;
58
58
  }
59
- deletePrincipal(principal) {
59
+ deletePrincipal(principal, cwd) {
60
60
  const p = Array.from(this.principals).find(p => p.principal === principal);
61
61
  if (p) {
62
- debugLog('*', `Deleting principal at ${[...p.wsDirs].map(cwd => toRelative(cwd) || '.')} (${[...p.pkgNames]})`);
62
+ debugLog('*', `Deleting principal at ${[...p.wsDirs].map(dir => toRelative(dir, cwd) || '.')} (${[...p.pkgNames]})`);
63
63
  this.principals.delete(p);
64
64
  }
65
65
  }
@@ -1,11 +1,12 @@
1
1
  import ts from 'typescript';
2
2
  import { CacheConsultant } from './CacheConsultant.js';
3
3
  import type { AsyncCompilers, SyncCompilers } from './compilers/types.js';
4
- import type { GetImportsAndExportsOptions } from './types/config.js';
4
+ import type { GetImportsAndExportsOptions, IgnoreExportsUsedInFile } from './types/config.js';
5
5
  import type { Export, ExportMember, FileNode, ModuleGraph } from './types/module-graph.js';
6
6
  import type { Paths, PrincipalOptions } from './types/project.js';
7
7
  import { SourceFileManager } from './typescript/SourceFileManager.js';
8
8
  import type { ResolveModuleNames } from './typescript/resolve-module-names.js';
9
+ import type { MainOptions } from './util/create-options.js';
9
10
  import type { ToSourceFilePath } from './util/to-source-path.js';
10
11
  export declare class ProjectPrincipal {
11
12
  entryPaths: Set<string>;
@@ -31,7 +32,7 @@ export declare class ProjectPrincipal {
31
32
  };
32
33
  findReferences?: ts.LanguageService['findReferences'];
33
34
  getImplementationAtPosition?: ts.LanguageService['getImplementationAtPosition'];
34
- constructor({ compilerOptions, cwd, compilers, isSkipLibs, isWatch, pkgName, toSourceFilePath, isCache, cacheLocation, isProduction, }: PrincipalOptions);
35
+ constructor(options: MainOptions, { compilerOptions, compilers, pkgName, toSourceFilePath }: PrincipalOptions);
35
36
  init(): void;
36
37
  addPaths(paths: Paths, basePath: string): void;
37
38
  addCompilers(compilers: [SyncCompilers, AsyncCompilers]): void;
@@ -51,7 +52,7 @@ export declare class ProjectPrincipal {
51
52
  getUsedResolvedFiles(): string[];
52
53
  private getProgramSourceFiles;
53
54
  getUnreferencedFiles(): string[];
54
- analyzeSourceFile(filePath: string, options: Omit<GetImportsAndExportsOptions, 'skipExports'>): FileNode;
55
+ analyzeSourceFile(filePath: string, options: GetImportsAndExportsOptions, ignoreExportsUsedInFile: IgnoreExportsUsedInFile): FileNode;
55
56
  invalidateFile(filePath: string): void;
56
57
  findUnusedMembers(filePath: string, members: ExportMember[]): ExportMember[];
57
58
  hasExternalReferences(filePath: string, exportedItem: Export): boolean;