knip 2.17.1 → 2.17.2

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.
@@ -1,6 +1,6 @@
1
1
  /// <reference types="npmcli__package-json" />
2
2
  import type { SyncCompilers, AsyncCompilers } from './types/compilers.js';
3
- import type { RawConfiguration, Configuration, WorkspaceConfiguration } from './types/config.js';
3
+ import type { Configuration, WorkspaceConfiguration } from './types/config.js';
4
4
  import type { PackageJson } from '@npmcli/package-json';
5
5
  type ConfigurationManagerOptions = {
6
6
  cwd: string;
@@ -19,56 +19,32 @@ export declare class ConfigurationChief {
19
19
  config: Configuration;
20
20
  manifestPath?: string;
21
21
  manifest?: PackageJson;
22
- ignoreWorkspaces: string[];
22
+ ignoredWorkspacePatterns: string[];
23
23
  manifestWorkspaces: Map<string, string>;
24
- additionalWorkspaces: Set<string>;
25
- workspaceDirs: string[];
26
- workspaces: Workspace[];
24
+ additionalWorkspaceNames: Set<string>;
25
+ enabledWorkspaceNames: string[];
26
+ enabledWorkspaceDirs: string[];
27
+ enabledWorkspaces: Workspace[];
27
28
  localWorkspaces: Set<string>;
28
29
  resolvedConfigFilePath?: string;
29
30
  constructor({ cwd, isProduction }: ConfigurationManagerOptions);
30
31
  init(): Promise<void>;
31
32
  getCompilers(): [SyncCompilers, AsyncCompilers];
32
33
  getRules(): import("./types/issues.js").Rules;
33
- normalize(rawLocalConfig: RawConfiguration): {
34
- rules: {
35
- files: import("./types/issues.js").IssueSeverity;
36
- dependencies: import("./types/issues.js").IssueSeverity;
37
- devDependencies: import("./types/issues.js").IssueSeverity;
38
- unlisted: import("./types/issues.js").IssueSeverity;
39
- binaries: import("./types/issues.js").IssueSeverity;
40
- unresolved: import("./types/issues.js").IssueSeverity;
41
- exports: import("./types/issues.js").IssueSeverity;
42
- types: import("./types/issues.js").IssueSeverity;
43
- nsExports: import("./types/issues.js").IssueSeverity;
44
- nsTypes: import("./types/issues.js").IssueSeverity;
45
- duplicates: import("./types/issues.js").IssueSeverity;
46
- enumMembers: import("./types/issues.js").IssueSeverity;
47
- classMembers: import("./types/issues.js").IssueSeverity;
48
- };
49
- include: string[];
50
- exclude: string[];
51
- ignore: string[];
52
- ignoreBinaries: string[];
53
- ignoreDependencies: string[];
54
- ignoreExportsUsedInFile: boolean | Partial<Record<"function" | "type" | "enum" | "class" | "interface" | "member", boolean>>;
55
- ignoreWorkspaces: string[];
56
- syncCompilers: Map<string, (args_0: string, ...args_1: unknown[]) => string>;
57
- asyncCompilers: Map<string, (args_0: string, ...args_1: unknown[]) => Promise<string>>;
58
- workspaces: Record<string, WorkspaceConfiguration>;
59
- };
60
- setWorkspaces(): Promise<void>;
34
+ private normalize;
35
+ private setWorkspaces;
36
+ private getListedWorkspaces;
37
+ private getIgnoredWorkspacePatterns;
61
38
  private getManifestWorkspaces;
62
- private getAdditionalWorkspaces;
63
- private getAllWorkspaceNames;
64
- private getAllWorkspaces;
65
- getEnabledWorkspaces(): Workspace[];
66
- getDescendentWorkspaces(name: string): string[];
67
- getIgnoredWorkspaces(): string[];
68
- getIgnoredWorkspacesFor(name: string): string[];
39
+ private getAdditionalWorkspaceNames;
40
+ private getEnabledWorkspaceNames;
41
+ private getEnabledWorkspaces;
42
+ getWorkspaces(): Workspace[];
43
+ private getDescendentWorkspaces;
44
+ private getIgnoredWorkspacesFor;
69
45
  getNegatedWorkspacePatterns(name: string): string[];
70
46
  private getConfigKeyForWorkspace;
71
- getConfigForWorkspace(workspaceName: string): WorkspaceConfiguration;
47
+ private getConfigForWorkspace;
72
48
  getIssueTypesToReport(): import("./types/issues.js").Report;
73
49
  findWorkspaceByFilePath(filePath: string): Workspace | undefined;
74
50
  findWorkspaceByPackageName(packageName: string): Workspace | undefined;
@@ -51,11 +51,12 @@ export class ConfigurationChief {
51
51
  config;
52
52
  manifestPath;
53
53
  manifest;
54
- ignoreWorkspaces = [];
54
+ ignoredWorkspacePatterns = [];
55
55
  manifestWorkspaces = new Map();
56
- additionalWorkspaces = new Set();
57
- workspaceDirs = [];
58
- workspaces = [];
56
+ additionalWorkspaceNames = new Set();
57
+ enabledWorkspaceNames = [];
58
+ enabledWorkspaceDirs = [];
59
+ enabledWorkspaces = [];
59
60
  localWorkspaces = new Set();
60
61
  resolvedConfigFilePath;
61
62
  constructor({ cwd, isProduction }) {
@@ -165,15 +166,29 @@ export class ConfigurationChief {
165
166
  };
166
167
  }
167
168
  async setWorkspaces() {
168
- this.ignoreWorkspaces = this.getIgnoredWorkspaces();
169
+ this.ignoredWorkspacePatterns = this.getIgnoredWorkspacePatterns();
169
170
  this.manifestWorkspaces = await this.getManifestWorkspaces();
170
- this.additionalWorkspaces = await this.getAdditionalWorkspaces();
171
- this.localWorkspaces = new Set(compact(this.getAllWorkspaces().map(w => w.pkgName)));
172
- this.workspaces = this.getEnabledWorkspaces();
173
- this.workspaceDirs = this.getAllWorkspaceNames()
171
+ this.additionalWorkspaceNames = await this.getAdditionalWorkspaceNames();
172
+ this.enabledWorkspaceNames = this.getEnabledWorkspaceNames();
173
+ this.enabledWorkspaces = this.getEnabledWorkspaces();
174
+ this.enabledWorkspaceDirs = this.enabledWorkspaceNames
174
175
  .sort(byPathDepth)
175
176
  .reverse()
176
177
  .map(dir => join(this.cwd, dir));
178
+ this.localWorkspaces = new Set(compact(this.enabledWorkspaces.map(w => w.pkgName)));
179
+ }
180
+ getListedWorkspaces() {
181
+ return this.manifest?.workspaces
182
+ ? Array.isArray(this.manifest.workspaces)
183
+ ? this.manifest.workspaces
184
+ : this.manifest.workspaces.packages ?? []
185
+ : [];
186
+ }
187
+ getIgnoredWorkspacePatterns() {
188
+ const ignoredWorkspaces = this.getListedWorkspaces()
189
+ .filter(name => name.startsWith('!'))
190
+ .map(name => name.replace(/^!/, ''));
191
+ return [...ignoredWorkspaces, ...this.config.ignoreWorkspaces];
177
192
  }
178
193
  async getManifestWorkspaces() {
179
194
  const workspaces = await mapWorkspaces({
@@ -186,18 +201,22 @@ export class ConfigurationChief {
186
201
  }
187
202
  return manifestWorkspaces;
188
203
  }
189
- async getAdditionalWorkspaces() {
204
+ async getAdditionalWorkspaceNames() {
190
205
  const additionalWorkspaceKeys = Object.keys(this.config.workspaces);
191
206
  const patterns = additionalWorkspaceKeys.filter(key => key.includes('*'));
192
207
  const dirs = additionalWorkspaceKeys.filter(key => !key.includes('*'));
193
208
  const globbedDirs = await _dirGlob({ patterns, cwd: this.cwd });
194
- return new Set([...dirs, ...globbedDirs].filter(name => name !== ROOT_WORKSPACE_NAME && !this.manifestWorkspaces.has(name) && !this.ignoreWorkspaces.includes(name)));
209
+ return new Set([...dirs, ...globbedDirs].filter(name => name !== ROOT_WORKSPACE_NAME &&
210
+ !this.manifestWorkspaces.has(name) &&
211
+ !micromatch.isMatch(name, this.ignoredWorkspacePatterns)));
195
212
  }
196
- getAllWorkspaceNames() {
197
- return compact([ROOT_WORKSPACE_NAME, ...this.manifestWorkspaces.keys(), ...this.additionalWorkspaces]);
213
+ getEnabledWorkspaceNames() {
214
+ return [ROOT_WORKSPACE_NAME, ...this.manifestWorkspaces.keys(), ...this.additionalWorkspaceNames].filter(name => !micromatch.isMatch(name, this.ignoredWorkspacePatterns));
198
215
  }
199
- getAllWorkspaces() {
200
- const workspaceDirs = this.getAllWorkspaceNames();
216
+ getEnabledWorkspaces() {
217
+ const workspaceNames = workspaceArg
218
+ ? this.enabledWorkspaceNames.filter(name => name === workspaceArg)
219
+ : this.enabledWorkspaceNames;
201
220
  const getAncestors = (name) => (ancestors, ancestorName) => {
202
221
  if (name === ancestorName)
203
222
  return ancestors;
@@ -205,36 +224,24 @@ export class ConfigurationChief {
205
224
  ancestors.push(ancestorName);
206
225
  return ancestors;
207
226
  };
208
- return workspaceDirs.sort(byPathDepth).map((name) => ({
227
+ return workspaceNames.sort(byPathDepth).map((name) => ({
209
228
  name,
210
229
  pkgName: this.manifestWorkspaces.get(name) ?? this.manifest?.name,
211
230
  dir: join(this.cwd, name),
212
231
  config: this.getConfigForWorkspace(name),
213
- ancestors: workspaceDirs.reduce(getAncestors(name), []),
232
+ ancestors: workspaceNames.reduce(getAncestors(name), []),
214
233
  }));
215
234
  }
216
- getEnabledWorkspaces() {
217
- const allWorkspaces = this.getAllWorkspaces();
218
- const ignoredWorkspaces = this.getIgnoredWorkspaces();
219
- const workspaces = workspaceArg ? allWorkspaces.filter(w => w.name === workspaceArg) : allWorkspaces;
220
- return workspaces.filter(w => !ignoredWorkspaces.includes(w.name));
235
+ getWorkspaces() {
236
+ return this.enabledWorkspaces;
221
237
  }
222
238
  getDescendentWorkspaces(name) {
223
- return this.getAllWorkspaceNames()
239
+ return this.enabledWorkspaceNames
224
240
  .filter(workspaceName => workspaceName !== name)
225
241
  .filter(workspaceName => name === ROOT_WORKSPACE_NAME || workspaceName.startsWith(name + '/'));
226
242
  }
227
- getIgnoredWorkspaces() {
228
- const ignored = this.config.ignoreWorkspaces;
229
- const workspaces = this.manifest?.workspaces
230
- ? Array.isArray(this.manifest.workspaces)
231
- ? this.manifest.workspaces
232
- : this.manifest.workspaces.packages ?? []
233
- : [];
234
- return [...ignored, ...workspaces.filter(name => name.startsWith('!'))].map(name => name.replace(/^!/, ''));
235
- }
236
243
  getIgnoredWorkspacesFor(name) {
237
- return this.getIgnoredWorkspaces()
244
+ return this.ignoredWorkspacePatterns
238
245
  .filter(workspaceName => workspaceName !== name)
239
246
  .filter(workspaceName => name === ROOT_WORKSPACE_NAME || workspaceName.startsWith(name));
240
247
  }
@@ -269,15 +276,15 @@ export class ConfigurationChief {
269
276
  return getIncludedIssueTypes(cliArgs, config);
270
277
  }
271
278
  findWorkspaceByFilePath(filePath) {
272
- const workspaceDir = this.workspaceDirs.find(workspaceDir => filePath.startsWith(workspaceDir + '/'));
273
- return this.workspaces.find(workspace => workspace.dir === workspaceDir);
279
+ const workspaceDir = this.enabledWorkspaceDirs.find(workspaceDir => filePath.startsWith(workspaceDir + '/'));
280
+ return this.enabledWorkspaces.find(workspace => workspace.dir === workspaceDir);
274
281
  }
275
282
  findWorkspaceByPackageName(packageName) {
276
- return this.workspaces.find(workspace => workspace.pkgName === packageName);
283
+ return this.enabledWorkspaces.find(workspace => workspace.pkgName === packageName);
277
284
  }
278
285
  getUnusedIgnoredWorkspaces() {
279
286
  const ignoredWorkspaceNames = this.config.ignoreWorkspaces;
280
- const workspaceNames = this.getAllWorkspaceNames();
281
- return ignoredWorkspaceNames.filter(workspaceName => !workspaceNames.includes(workspaceName));
287
+ const workspaceNames = [...this.manifestWorkspaces.keys(), ...this.additionalWorkspaceNames];
288
+ return ignoredWorkspaceNames.filter(ignoredWorkspaceName => !workspaceNames.some(name => micromatch.isMatch(name, ignoredWorkspaceName)));
282
289
  }
283
290
  }
@@ -13,7 +13,7 @@ const argFilters = {
13
13
  tsx: parsed => parsed._.filter(p => p !== 'watch'),
14
14
  default: withoutPositional,
15
15
  };
16
- const spawningBinaries = ['cross-env'];
16
+ const spawningBinaries = ['cross-env', 'retry-cli'];
17
17
  export const resolve = (binary, args, { cwd, fromArgs }) => {
18
18
  const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader'] }, boolean: ['quiet', 'verbose'] });
19
19
  const bin = binary.startsWith('.') ? tryResolveFilePath(cwd, binary) : toBinary(binary);
@@ -1,24 +1,20 @@
1
1
  import parseArgs from 'minimist';
2
2
  import { isInternal } from '../../util/path.js';
3
- import { fromBinary, toBinary } from '../util.js';
4
- export const resolve = (binary, args, { fromArgs, manifest }) => {
3
+ import { getBinariesFromScript } from '../bash-parser.js';
4
+ import { argsFrom, stripVersionFromSpecifier, toBinary } from '../util.js';
5
+ export const resolve = (binary, args, { cwd, fromArgs, manifest }) => {
5
6
  const parsed = parseArgs(args, {
6
- '--': true,
7
- stopEarly: true,
8
7
  boolean: ['yes', 'no'],
9
- alias: { yes: 'y', no: 'no-install' },
8
+ alias: { yes: 'y', no: 'no-install', package: 'p', call: 'c' },
10
9
  });
11
- const leftParsed = fromArgs(parsed._);
12
- const leftHandCommand = parsed.yes ? leftParsed.slice(1) : leftParsed;
13
- const rightHandCommand = parsed['--'] ? fromArgs(parsed['--']) : [];
14
- const binaryOrPackageName = fromBinary(leftHandCommand[0] ?? rightHandCommand[0]);
15
- const dependencies = manifest
16
- ? [...Object.keys(manifest.dependencies ?? {}), ...Object.keys(manifest.devDependencies ?? {})]
17
- : [];
18
- const dependency = !binaryOrPackageName.startsWith('@') &&
19
- !isInternal(binaryOrPackageName) &&
20
- !dependencies.includes(binaryOrPackageName)
21
- ? toBinary(binaryOrPackageName)
22
- : binaryOrPackageName;
23
- return [dependency, ...leftHandCommand.slice(1), ...rightHandCommand];
10
+ const packageSpecifier = parsed._[0];
11
+ const specifier = packageSpecifier ? stripVersionFromSpecifier(packageSpecifier) : '';
12
+ const packages = parsed.package ? [parsed.package].flat().map(stripVersionFromSpecifier) : [];
13
+ const command = parsed.call ? getBinariesFromScript(parsed.call, { cwd, manifest }) : [];
14
+ const restArgs = argsFrom(args, packageSpecifier);
15
+ const dependencies = manifest ? Object.keys({ ...manifest.dependencies, ...manifest.devDependencies }) : [];
16
+ const isBinary = specifier && !packageSpecifier.includes('@') && !isInternal(specifier) && !dependencies.includes(specifier);
17
+ const dependency = isBinary ? toBinary(specifier) : specifier;
18
+ const specifiers = dependency && !parsed.yes ? [dependency] : [];
19
+ return [...specifiers, ...packages, ...command, ...fromArgs(restArgs).slice(1)];
24
20
  };
@@ -3,5 +3,6 @@ export declare const tryResolveSpecifiers: (cwd: string, specifiers: string[]) =
3
3
  export declare const toBinary: (specifier: string) => string;
4
4
  export declare const fromBinary: (specifier: string) => string;
5
5
  export declare const isBinary: (specifier: string) => boolean;
6
+ export declare const stripVersionFromSpecifier: (specifier: string) => string;
6
7
  export declare const stripBinaryPath: (command: string) => string;
7
8
  export declare const argsFrom: (args: string[], from: string) => string[];
@@ -25,9 +25,9 @@ export const tryResolveSpecifiers = (cwd, specifiers) => specifiers.map(specifie
25
25
  export const toBinary = (specifier) => specifier.replace(/^(bin:)?/, 'bin:');
26
26
  export const fromBinary = (specifier) => specifier.replace(/^(bin:)?/, '');
27
27
  export const isBinary = (specifier) => specifier.startsWith('bin:');
28
+ export const stripVersionFromSpecifier = (specifier) => specifier.replace(/(\S+)@.*/, '$1');
28
29
  const stripNodeModulesFromPath = (command) => command.replace(/^(\.\/)?node_modules\//, '');
29
- export const stripBinaryPath = (command) => stripNodeModulesFromPath(command)
30
+ export const stripBinaryPath = (command) => stripVersionFromSpecifier(stripNodeModulesFromPath(command)
30
31
  .replace(/^(\.bin\/)/, '')
31
- .replace(/\$\(npm bin\)\/(\w+)/, '$1')
32
- .replace(/(\S+)@.*/, '$1');
32
+ .replace(/\$\(npm bin\)\/(\w+)/, '$1'));
33
33
  export const argsFrom = (args, from) => args.slice(args.indexOf(from));
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ export const main = async (unresolvedConfiguration) => {
28
28
  streamer.cast('Reading workspace configuration(s)...');
29
29
  await chief.init();
30
30
  const compilers = chief.getCompilers();
31
- const workspaces = chief.getEnabledWorkspaces();
31
+ const workspaces = chief.getWorkspaces();
32
32
  const report = chief.getIssueTypesToReport();
33
33
  const rules = chief.getRules();
34
34
  const isReportDependencies = report.dependencies || report.unlisted || report.unresolved;
@@ -1,5 +1,6 @@
1
+ import type { VitestConfig } from './types.js';
1
2
  type BuiltinEnvironment = 'node' | 'jsdom' | 'happy-dom' | 'edge-runtime';
2
3
  type VitestEnvironment = BuiltinEnvironment | (string & Record<never, never>);
3
4
  export declare const getEnvPackageName: (env: VitestEnvironment) => any;
4
- export declare const getExternalReporters: (reporters?: string | string[]) => string[];
5
+ export declare const getExternalReporters: (reporters?: VitestConfig['test']['reporters']) => unknown[];
5
6
  export {};
@@ -17,4 +17,6 @@ export const getEnvPackageName = (env) => {
17
17
  return `vitest-environment-${env}`;
18
18
  };
19
19
  const builtInReporters = ['default', 'verbose', 'dot', 'json', 'tap', 'tap-flat', 'junit', 'hanging-process'];
20
- export const getExternalReporters = (reporters) => reporters ? [reporters].flat().filter(reporter => !builtInReporters.includes(reporter)) : [];
20
+ export const getExternalReporters = (reporters) => reporters
21
+ ? [reporters].flat().filter(reporter => typeof reporter === 'string' && !builtInReporters.includes(reporter))
22
+ : [];
@@ -5,7 +5,7 @@ export type VitestConfig = {
5
5
  };
6
6
  environment?: string;
7
7
  globalSetup?: string | string[];
8
- reporters?: string[];
8
+ reporters?: (string | unknown)[];
9
9
  setupFiles?: string | string[];
10
10
  };
11
11
  };
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.17.1";
1
+ export declare const version = "2.17.2";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.17.1';
1
+ export const version = '2.17.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.17.1",
3
+ "version": "2.17.2",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",