knip 5.62.0 → 5.63.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.
Files changed (134) hide show
  1. package/README.md +22 -24
  2. package/dist/CacheConsultant.d.ts +3 -9
  3. package/dist/CacheConsultant.js +5 -5
  4. package/dist/ConfigurationChief.d.ts +588 -38
  5. package/dist/ConfigurationChief.js +43 -124
  6. package/dist/ConsoleStreamer.d.ts +2 -3
  7. package/dist/ConsoleStreamer.js +2 -2
  8. package/dist/DependencyDeputy.d.ts +2 -6
  9. package/dist/IssueCollector.d.ts +4 -12
  10. package/dist/IssueCollector.js +10 -10
  11. package/dist/IssueFixer.d.ts +3 -14
  12. package/dist/IssueFixer.js +11 -21
  13. package/dist/PrincipalFactory.d.ts +3 -2
  14. package/dist/PrincipalFactory.js +11 -11
  15. package/dist/ProjectPrincipal.d.ts +5 -3
  16. package/dist/ProjectPrincipal.js +17 -11
  17. package/dist/WorkspaceWorker.d.ts +4 -9
  18. package/dist/WorkspaceWorker.js +8 -12
  19. package/dist/binaries/bash-parser.js +1 -1
  20. package/dist/binaries/fallback.js +4 -2
  21. package/dist/binaries/package-manager/pnpm.js +6 -1
  22. package/dist/cli.js +43 -60
  23. package/dist/compilers/index.d.ts +34 -4
  24. package/dist/graph/analyze.d.ts +3 -8
  25. package/dist/graph/analyze.js +24 -27
  26. package/dist/graph/build.d.ts +3 -17
  27. package/dist/graph/build.js +60 -47
  28. package/dist/index.d.ts +3 -6
  29. package/dist/index.js +23 -62
  30. package/dist/plugins/astro/index.d.ts +1 -0
  31. package/dist/plugins/astro/index.js +4 -0
  32. package/dist/plugins/index.d.ts +24 -1
  33. package/dist/plugins/index.js +6 -0
  34. package/dist/plugins/lefthook/index.js +2 -0
  35. package/dist/plugins/node-modules-inspector/index.d.ts +12 -0
  36. package/dist/plugins/node-modules-inspector/index.js +17 -0
  37. package/dist/plugins/nuxt/index.js +4 -3
  38. package/dist/plugins/nuxt/types.d.ts +3 -2
  39. package/dist/plugins/playwright/index.js +8 -1
  40. package/dist/plugins/playwright/types.d.ts +20 -14
  41. package/dist/plugins/pnpm/index.d.ts +7 -0
  42. package/dist/plugins/pnpm/index.js +8 -0
  43. package/dist/plugins/preconstruct/index.js +2 -1
  44. package/dist/plugins/react-router/index.js +18 -8
  45. package/dist/plugins/rsbuild/index.js +28 -2
  46. package/dist/plugins/rsbuild/types.d.ts +11 -0
  47. package/dist/plugins/rslib/index.d.ts +10 -0
  48. package/dist/plugins/rslib/index.js +15 -0
  49. package/dist/plugins/rslib/types.d.ts +1 -0
  50. package/dist/plugins/rspack/index.js +1 -1
  51. package/dist/plugins/typescript/index.d.ts +1 -1
  52. package/dist/plugins.js +3 -2
  53. package/dist/reporters/codeclimate.d.ts +1 -1
  54. package/dist/reporters/codeclimate.js +10 -10
  55. package/dist/reporters/codeowners.d.ts +1 -1
  56. package/dist/reporters/codeowners.js +5 -5
  57. package/dist/reporters/compact.d.ts +1 -1
  58. package/dist/reporters/compact.js +7 -7
  59. package/dist/reporters/disclosure.d.ts +1 -1
  60. package/dist/reporters/disclosure.js +2 -2
  61. package/dist/reporters/index.d.ts +6 -6
  62. package/dist/reporters/json.d.ts +1 -1
  63. package/dist/reporters/json.js +3 -3
  64. package/dist/reporters/markdown.d.ts +1 -1
  65. package/dist/reporters/markdown.js +4 -4
  66. package/dist/reporters/symbols.js +4 -2
  67. package/dist/reporters/util/configuration-hints.d.ts +1 -1
  68. package/dist/reporters/util/configuration-hints.js +58 -23
  69. package/dist/reporters/util/util.d.ts +2 -4
  70. package/dist/reporters/util/util.js +6 -6
  71. package/dist/reporters/watch.d.ts +3 -4
  72. package/dist/reporters/watch.js +5 -5
  73. package/dist/schema/configuration.d.ts +176 -8
  74. package/dist/schema/plugins.d.ts +69 -0
  75. package/dist/schema/plugins.js +3 -0
  76. package/dist/types/PluginNames.d.ts +2 -2
  77. package/dist/types/PluginNames.js +3 -0
  78. package/dist/types/config.d.ts +4 -10
  79. package/dist/types/entries.d.ts +3 -0
  80. package/dist/types/entries.js +1 -0
  81. package/dist/types/issues.d.ts +4 -3
  82. package/dist/types/{cli.d.ts → options.d.ts} +2 -2
  83. package/dist/types/options.js +1 -0
  84. package/dist/types/package-json.d.ts +5 -0
  85. package/dist/types/project.d.ts +1 -7
  86. package/dist/types/tsconfig-json.d.ts +14 -0
  87. package/dist/types/tsconfig-json.js +1 -0
  88. package/dist/typescript/ast-helpers.js +1 -1
  89. package/dist/typescript/get-imports-and-exports.d.ts +2 -2
  90. package/dist/typescript/get-imports-and-exports.js +9 -10
  91. package/dist/util/Performance.js +16 -6
  92. package/dist/util/cli-arguments.d.ts +1 -2
  93. package/dist/util/cli-arguments.js +3 -13
  94. package/dist/util/create-options.d.ts +1219 -0
  95. package/dist/util/create-options.js +112 -0
  96. package/dist/util/debug.js +3 -4
  97. package/dist/util/errors.d.ts +1 -1
  98. package/dist/util/file-entry-cache.js +3 -3
  99. package/dist/util/fs.d.ts +1 -1
  100. package/dist/util/get-included-issue-types.d.ts +9 -13
  101. package/dist/util/get-included-issue-types.js +10 -16
  102. package/dist/util/get-referenced-inputs.js +1 -1
  103. package/dist/util/glob-core.d.ts +1 -1
  104. package/dist/util/glob-core.js +8 -7
  105. package/dist/util/glob.d.ts +1 -0
  106. package/dist/util/glob.js +1 -1
  107. package/dist/util/input.d.ts +1 -1
  108. package/dist/util/input.js +1 -1
  109. package/dist/util/is-identifier-referenced.d.ts +1 -1
  110. package/dist/util/is-identifier-referenced.js +19 -19
  111. package/dist/util/load-config.d.ts +1 -0
  112. package/dist/util/load-config.js +24 -0
  113. package/dist/util/package-json.d.ts +2 -1
  114. package/dist/util/package-json.js +24 -12
  115. package/dist/util/parse-and-convert-gitignores.js +2 -0
  116. package/dist/util/path.d.ts +4 -4
  117. package/dist/util/path.js +5 -7
  118. package/dist/util/reporter.js +3 -3
  119. package/dist/util/require.js +1 -2
  120. package/dist/util/table.js +1 -3
  121. package/dist/util/tag.d.ts +1 -1
  122. package/dist/util/to-source-path.d.ts +1 -1
  123. package/dist/util/to-source-path.js +5 -5
  124. package/dist/util/trace.d.ts +6 -6
  125. package/dist/util/trace.js +18 -22
  126. package/dist/util/watch.d.ts +2 -5
  127. package/dist/util/watch.js +3 -3
  128. package/dist/version.d.ts +1 -1
  129. package/dist/version.js +1 -1
  130. package/package.json +10 -15
  131. package/schema.json +12 -0
  132. package/dist/util/unwrap-function.d.ts +0 -1
  133. package/dist/util/unwrap-function.js +0 -13
  134. /package/dist/{types/cli.js → plugins/rslib/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';
13
- import { _dirGlob } from './util/glob.js';
8
+ import { isDirectory, isFile } from './util/fs.js';
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,56 +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
- this.parsedConfig = this.rawConfig ? knipConfigurationSchema.parse(partitionCompilers(this.rawConfig)) : {};
114
- this.config = this.normalize(this.parsedConfig);
115
- 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 ?? {});
116
73
  }
117
74
  getConfigurationHints() {
118
75
  const hints = new Set();
119
- const config = this.parsedConfig;
120
- if (config) {
76
+ if (this.rawConfig) {
121
77
  if (this.workspacePackages.size > 1) {
122
- const entry = arrayify(config.entry);
78
+ const entry = arrayify(this.rawConfig.entry);
123
79
  if (entry.length > 0) {
124
80
  const identifier = `[${entry[0]}${entry.length > 1 ? `, ${ELLIPSIS}` : ''}]`;
125
81
  hints.add({ type: 'entry-top-level', identifier });
126
82
  }
127
- const project = arrayify(config.project);
83
+ const project = arrayify(this.rawConfig.project);
128
84
  if (project.length > 0) {
129
85
  const identifier = `[${project[0]}${project.length > 1 ? `, ${ELLIPSIS}` : ''}]`;
130
86
  hints.add({ type: 'project-top-level', identifier });
@@ -133,35 +89,15 @@ export class ConfigurationChief {
133
89
  }
134
90
  return hints;
135
91
  }
136
- async loadResolvedConfigurationFile(configPath) {
137
- const loadedValue = await _load(configPath);
138
- try {
139
- return await unwrapFunction(loadedValue);
140
- }
141
- catch (_error) {
142
- throw new ConfigurationError(`Error running the function from ${configPath}`);
143
- }
144
- }
145
- getRules() {
146
- return this.config.rules;
147
- }
148
- getFilters() {
149
- if (this.workspaceGraph && this.workspace)
150
- return { dir: join(this.cwd, this.workspace) };
151
- return {};
152
- }
153
92
  normalize(rawConfig) {
154
- const rules = { ...defaultRules, ...rawConfig.rules };
155
- const include = rawConfig.include ?? defaultConfig.include;
156
- const exclude = rawConfig.exclude ?? defaultConfig.exclude;
157
93
  const ignore = arrayify(rawConfig.ignore ?? defaultConfig.ignore);
158
94
  const ignoreBinaries = rawConfig.ignoreBinaries ?? [];
159
95
  const ignoreDependencies = rawConfig.ignoreDependencies ?? [];
160
96
  const ignoreMembers = rawConfig.ignoreMembers ?? [];
97
+ const ignoreUnresolved = rawConfig.ignoreUnresolved ?? [];
161
98
  const ignoreExportsUsedInFile = rawConfig.ignoreExportsUsedInFile ?? false;
162
99
  const ignoreWorkspaces = rawConfig.ignoreWorkspaces ?? defaultConfig.ignoreWorkspaces;
163
100
  const isIncludeEntryExports = rawConfig.includeEntryExports ?? this.isIncludeEntryExports;
164
- const isTreatConfigHintsAsErrors = rawConfig.treatConfigHintsAsErrors ?? defaultConfig.isTreatConfigHintsAsErrors;
165
101
  const { syncCompilers, asyncCompilers } = rawConfig;
166
102
  const rootPluginConfigs = {};
167
103
  for (const [pluginName, pluginConfig] of Object.entries(rawConfig)) {
@@ -170,24 +106,20 @@ export class ConfigurationChief {
170
106
  }
171
107
  }
172
108
  return {
173
- rules,
174
- include,
175
- exclude,
176
109
  ignore,
177
110
  ignoreBinaries,
178
111
  ignoreDependencies,
179
112
  ignoreMembers,
113
+ ignoreUnresolved,
180
114
  ignoreExportsUsedInFile,
181
115
  ignoreWorkspaces,
182
116
  isIncludeEntryExports,
183
117
  syncCompilers: new Map(Object.entries(syncCompilers ?? {})),
184
118
  asyncCompilers: new Map(Object.entries(asyncCompilers ?? {})),
185
119
  rootPluginConfigs,
186
- tags: rawConfig.tags ?? [],
187
- isTreatConfigHintsAsErrors,
188
120
  };
189
121
  }
190
- async setWorkspaces() {
122
+ async getWorkspaces() {
191
123
  this.ignoredWorkspacePatterns = this.getIgnoredWorkspacePatterns();
192
124
  this.additionalWorkspaceNames = await this.getAdditionalWorkspaceNames();
193
125
  const workspaceNames = compact([...this.getListedWorkspaces(), ...this.additionalWorkspaceNames]);
@@ -205,26 +137,30 @@ export class ConfigurationChief {
205
137
  this.workspacesByPkgName.set(workspace.pkgName, workspace);
206
138
  this.workspacesByName.set(workspace.name, workspace);
207
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));
208
143
  }
209
144
  getListedWorkspaces() {
210
- const workspaces = this.manifest?.workspaces
211
- ? Array.isArray(this.manifest.workspaces)
212
- ? this.manifest.workspaces
213
- : (this.manifest.workspaces.packages ?? [])
214
- : [];
215
- return workspaces.map(pattern => pattern.replace(/(?<=!?)\.\//, ''));
145
+ return this.workspaces.map(pattern => pattern.replace(/(?<=!?)\.\//, ''));
146
+ }
147
+ getIgnoredWorkspaces() {
148
+ const ignoreWorkspaces = this.config.ignoreWorkspaces;
149
+ if (this.isProduction)
150
+ return ignoreWorkspaces.map(removeProductionSuffix);
151
+ return ignoreWorkspaces.filter(pattern => !pattern.endsWith('!'));
216
152
  }
217
153
  getIgnoredWorkspacePatterns() {
218
154
  const ignoredWorkspacesManifest = this.getListedWorkspaces()
219
155
  .filter(name => name.startsWith('!'))
220
156
  .map(name => name.replace(/^!/, ''));
221
- return [...ignoredWorkspacesManifest, ...this.config.ignoreWorkspaces];
157
+ return [...ignoredWorkspacesManifest, ...this.getIgnoredWorkspaces()];
222
158
  }
223
159
  getConfiguredWorkspaceKeys() {
224
160
  const initialWorkspaces = this.rawConfig?.workspaces
225
161
  ? Object.keys(this.rawConfig.workspaces)
226
162
  : [ROOT_WORKSPACE_NAME];
227
- const ignoreWorkspaces = this.rawConfig?.ignoreWorkspaces ?? defaultConfig.ignoreWorkspaces;
163
+ const ignoreWorkspaces = this.getIgnoredWorkspaces();
228
164
  return initialWorkspaces.filter(workspaceName => !ignoreWorkspaces.includes(workspaceName));
229
165
  }
230
166
  async getAdditionalWorkspaceNames() {
@@ -301,7 +237,7 @@ export class ConfigurationChief {
301
237
  const manifestPath = pkg?.manifestPath ?? join(dir, 'package.json');
302
238
  const manifestStr = pkg?.manifestStr ?? '';
303
239
  const workspaceConfig = this.getWorkspaceConfig(name);
304
- const ignoreMembers = arrayify(workspaceConfig.ignoreMembers).map(toRegexOrString);
240
+ const ignoreMembers = workspaceConfig.ignoreMembers?.map(toRegexOrString) ?? [];
305
241
  return {
306
242
  name,
307
243
  pkgName,
@@ -317,11 +253,6 @@ export class ConfigurationChief {
317
253
  getManifestForWorkspace(name) {
318
254
  return this.workspacePackages.get(name)?.manifest;
319
255
  }
320
- getWorkspaces() {
321
- const sorted = graphSequencer(this.workspaceGraph, this.includedWorkspaces.map(workspace => workspace.dir));
322
- const [root, rest] = partition(sorted.chunks.flat(), dir => dir === this.cwd);
323
- return [...root, ...rest.reverse()].map(dir => this.includedWorkspaces.find(w => w.dir === dir));
324
- }
325
256
  getDescendentWorkspaces(name) {
326
257
  return this.availableWorkspaceNames
327
258
  .filter(workspaceName => workspaceName !== name)
@@ -358,9 +289,9 @@ export class ConfigurationChief {
358
289
  }
359
290
  getIgnores(workspaceName) {
360
291
  const workspaceConfig = this.getWorkspaceConfig(workspaceName);
361
- const ignoreBinaries = arrayify(workspaceConfig.ignoreBinaries);
362
- const ignoreDependencies = arrayify(workspaceConfig.ignoreDependencies);
363
- const ignoreUnresolved = arrayify(workspaceConfig.ignoreUnresolved);
292
+ const ignoreBinaries = workspaceConfig.ignoreBinaries ?? [];
293
+ const ignoreDependencies = workspaceConfig.ignoreDependencies ?? [];
294
+ const ignoreUnresolved = workspaceConfig.ignoreUnresolved ?? [];
364
295
  if (workspaceName === ROOT_WORKSPACE_NAME) {
365
296
  const { ignoreBinaries: rootIgnoreBinaries, ignoreDependencies: rootIgnoreDependencies, ignoreUnresolved: rootIgnoreUnresolved, } = this.rawConfig ?? {};
366
297
  return {
@@ -391,21 +322,12 @@ export class ConfigurationChief {
391
322
  }
392
323
  return { entry, project, paths, ignore, isIncludeEntryExports, ...plugins };
393
324
  }
394
- getIncludedIssueTypes(cliArgs) {
395
- const excludesFromRules = getKeysByValue(this.config.rules, 'off');
396
- const config = {
397
- include: this.config.include ?? [],
398
- exclude: [...excludesFromRules, ...this.config.exclude],
399
- isProduction: this.isProduction,
400
- };
401
- return getIncludedIssueTypes(cliArgs, config);
402
- }
403
325
  findWorkspaceByFilePath(filePath) {
404
326
  const workspaceDir = this.availableWorkspaceDirs.find(workspaceDir => filePath.startsWith(`${workspaceDir}/`));
405
327
  return this.includedWorkspaces.find(workspace => workspace.dir === workspaceDir);
406
328
  }
407
329
  getUnusedIgnoredWorkspaces() {
408
- const ignoredWorkspaceNames = this.config.ignoreWorkspaces;
330
+ const ignoredWorkspaceNames = this.config.ignoreWorkspaces.map(removeProductionSuffix);
409
331
  const workspaceNames = [...this.workspacePackages.keys(), ...this.additionalWorkspaceNames];
410
332
  return ignoredWorkspaceNames
411
333
  .filter(ignoredWorkspaceName => !workspaceNames.some(name => picomatch.isMatch(name, ignoredWorkspaceName)))
@@ -414,7 +336,4 @@ export class ConfigurationChief {
414
336
  return !isDirectory(dir) || isFile(join(dir, 'package.json'));
415
337
  });
416
338
  }
417
- getTags() {
418
- return splitTags(this.config.tags);
419
- }
420
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 {};
@@ -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;
@@ -56,7 +56,7 @@ export class IssueCollector {
56
56
  issue.severity = this.rules[type];
57
57
  const issues = this.issues[type];
58
58
  issues[key] = issues[key] ?? {};
59
- const symbol = type.endsWith('Members') && issue.parentSymbol ? `${issue.parentSymbol}.${issue.symbol}` : issue.symbol;
59
+ const symbol = issue.parentSymbol ? `${issue.parentSymbol}.${issue.symbol}` : issue.symbol;
60
60
  if (!issues[key][symbol]) {
61
61
  issues[key][symbol] = issue;
62
62
  this.counters[issue.type]++;
@@ -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,8 +60,8 @@ 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)) || [];
63
+ const types = (this.options.isFixUnusedTypes && this.unusedTypeNodes.get(filePath)) || [];
64
+ const exports = (this.options.isFixUnusedExports && this.unusedExportNodes.get(filePath)) || [];
75
65
  const exportPositions = [...types, ...exports].filter(fix => fix !== undefined).sort((a, b) => b[0] - a[0]);
76
66
  if (exportPositions.length > 0) {
77
67
  const sourceFileText = exportPositions.reduce((text, [start, end, flags]) => removeExport({ text, start, end, flags }), await readFile(filePath, 'utf-8'));
@@ -84,11 +74,11 @@ export class IssueFixer {
84
74
  }
85
75
  async removeUnusedDependencies(issues) {
86
76
  const touchedFiles = new Set();
87
- if (!this.isFixDependencies)
77
+ if (!this.options.isFixDependencies)
88
78
  return touchedFiles;
89
79
  const filePaths = new Set([...Object.keys(issues.dependencies), ...Object.keys(issues.devDependencies)]);
90
80
  for (const filePath of filePaths) {
91
- const absFilePath = join(this.cwd, filePath);
81
+ const absFilePath = join(this.options.cwd, filePath);
92
82
  const pkg = await load(absFilePath);
93
83
  if (filePath in issues.dependencies) {
94
84
  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
  }