knip 2.12.1 → 2.12.3

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.
package/README.md CHANGED
@@ -181,21 +181,21 @@ This example shows more output related to unused and unlisted dependencies:
181
181
 
182
182
  The report contains the following types of issues:
183
183
 
184
- | Key | Title | Description |
185
- | :------------- | :---------------------------------- | :---------------------------------------------------- |
186
- | `files` | Unused files | unable to find references to this file |
187
- | `dependencies` | Unused dependencies | unable to find references to this dependency |
188
- | `dependencies` | Unused devDependencies | unable to find references to this dependency |
189
- | `unlisted` | Unlisted dependencies | used dependencies not listed in package.json |
190
- | `binaries` | Unlisted binaries | binaries from dependencies not in package.json |
191
- | `unresolved` | Unresolved imports | unable to resolve this (import) specifier |
192
- | `exports` | Unused exports | unable to find references to this export |
193
- | `nsExports` | Unused exports in namespaces | unable to find direct references to this export _(1)_ |
194
- | `types` | Unused exported types | unable to find references to this exported type |
195
- | `nsTypes` | Unused exported types in namespaces | unable to find direct references to this export _(1)_ |
196
- | `enumMembers` | Unused exported enum members | unable to find references to this enum member |
197
- | `classMembers` | Unused exported class members | unable to find references to this class member |
198
- | `duplicates` | Duplicate exports | the same thing is exported more than once |
184
+ | Key | Title | Description |
185
+ | :---------------- | :---------------------------------- | :---------------------------------------------------- |
186
+ | `files` | Unused files | unable to find references to this file |
187
+ | `dependencies` | Unused dependencies | unable to find references to this dependency |
188
+ | `devDependencies` | Unused devDependencies | unable to find references to this devDependency |
189
+ | `unlisted` | Unlisted dependencies | used dependencies not listed in package.json |
190
+ | `binaries` | Unlisted binaries | binaries from dependencies not in package.json |
191
+ | `unresolved` | Unresolved imports | unable to resolve this (import) specifier |
192
+ | `exports` | Unused exports | unable to find references to this export |
193
+ | `nsExports` | Unused exports in namespaces | unable to find direct references to this export _(1)_ |
194
+ | `types` | Unused exported types | unable to find references to this exported type |
195
+ | `nsTypes` | Unused exported types in namespaces | unable to find direct references to this export _(1)_ |
196
+ | `enumMembers` | Unused exported enum members | unable to find references to this enum member |
197
+ | `classMembers` | Unused exported class members | unable to find references to this class member |
198
+ | `duplicates` | Duplicate exports | the same thing is exported more than once |
199
199
 
200
200
  When an issue type has zero issues, it is not shown.
201
201
 
@@ -36,6 +36,7 @@ export declare class ConfigurationChief {
36
36
  dependencies: import("./types/issues.js").IssueSeverity;
37
37
  devDependencies: import("./types/issues.js").IssueSeverity;
38
38
  unlisted: import("./types/issues.js").IssueSeverity;
39
+ binaries: import("./types/issues.js").IssueSeverity;
39
40
  unresolved: import("./types/issues.js").IssueSeverity;
40
41
  exports: import("./types/issues.js").IssueSeverity;
41
42
  types: import("./types/issues.js").IssueSeverity;
@@ -44,7 +45,6 @@ export declare class ConfigurationChief {
44
45
  duplicates: import("./types/issues.js").IssueSeverity;
45
46
  enumMembers: import("./types/issues.js").IssueSeverity;
46
47
  classMembers: import("./types/issues.js").IssueSeverity;
47
- binaries: import("./types/issues.js").IssueSeverity;
48
48
  };
49
49
  include: string[];
50
50
  exclude: string[];
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  export declare const ConfigurationValidator: z.ZodObject<{
3
3
  exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
4
- rules: z.ZodOptional<z.ZodRecord<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, z.ZodEnum<["error", "warn", "off"]>>>;
4
+ rules: z.ZodOptional<z.ZodRecord<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"binaries">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, z.ZodEnum<["error", "warn", "off"]>>>;
5
5
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
6
6
  project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
7
7
  paths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
@@ -1405,7 +1405,7 @@ export declare const ConfigurationValidator: z.ZodObject<{
1405
1405
  }>]>>;
1406
1406
  }, "strip", z.ZodTypeAny, {
1407
1407
  exclude?: string[] | undefined;
1408
- rules?: Partial<Record<"files" | "dependencies" | "devDependencies" | "unlisted" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers", "error" | "warn" | "off">> | undefined;
1408
+ rules?: Partial<Record<"files" | "dependencies" | "devDependencies" | "unlisted" | "binaries" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers", "error" | "warn" | "off">> | undefined;
1409
1409
  entry?: string | string[] | undefined;
1410
1410
  project?: string | string[] | undefined;
1411
1411
  paths?: Record<string, string[]> | undefined;
@@ -1807,7 +1807,7 @@ export declare const ConfigurationValidator: z.ZodObject<{
1807
1807
  } | undefined;
1808
1808
  }, {
1809
1809
  exclude?: string[] | undefined;
1810
- rules?: Partial<Record<"files" | "dependencies" | "devDependencies" | "unlisted" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers", "error" | "warn" | "off">> | undefined;
1810
+ rules?: Partial<Record<"files" | "dependencies" | "devDependencies" | "unlisted" | "binaries" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers", "error" | "warn" | "off">> | undefined;
1811
1811
  entry?: string | string[] | undefined;
1812
1812
  project?: string | string[] | undefined;
1813
1813
  paths?: Record<string, string[]> | undefined;
@@ -10,6 +10,7 @@ const issueTypeSchema = z.union([
10
10
  z.literal('dependencies'),
11
11
  z.literal('devDependencies'),
12
12
  z.literal('unlisted'),
13
+ z.literal('binaries'),
13
14
  z.literal('unresolved'),
14
15
  z.literal('exports'),
15
16
  z.literal('types'),
@@ -12,9 +12,7 @@ const getDependenciesFromScripts = (npmScripts, options = {}) => {
12
12
  return compact(results.map(identifier => {
13
13
  if (isBinary(identifier) || isInternal(identifier))
14
14
  return identifier;
15
- const packageName = getPackageNameFromModuleSpecifier(identifier);
16
- if (!packageName.startsWith('.'))
17
- return packageName;
15
+ return getPackageNameFromModuleSpecifier(identifier);
18
16
  }));
19
17
  };
20
18
  export const _getDependenciesFromScripts = timerify(getDependenciesFromScripts);
@@ -6,10 +6,13 @@ export const tryResolveFilePath = (cwd, specifier, acceptModuleSpecifier) => {
6
6
  const filePath = join(cwd, specifier);
7
7
  if (!isInNodeModules(filePath)) {
8
8
  const resolvedFilePath = _tryResolve(filePath, cwd);
9
- if (resolvedFilePath)
9
+ if (resolvedFilePath) {
10
10
  return [resolvedFilePath];
11
- else if (acceptModuleSpecifier)
12
- return [getPackageNameFromModuleSpecifier(specifier)];
11
+ }
12
+ else if (acceptModuleSpecifier) {
13
+ const packageName = getPackageNameFromModuleSpecifier(specifier);
14
+ return packageName ? [packageName] : [];
15
+ }
13
16
  }
14
17
  else {
15
18
  return [getPackageNameFromFilePath(specifier)];
package/dist/index.js CHANGED
@@ -63,10 +63,10 @@ export const main = async (unresolvedConfiguration) => {
63
63
  const packageName = isInNodeModules(specifier)
64
64
  ? getPackageNameFromFilePath(specifier)
65
65
  : getPackageNameFromModuleSpecifier(specifier);
66
- const isHandled = deputy.maybeAddReferencedExternalDependency(workspace, packageName);
66
+ const isHandled = packageName && deputy.maybeAddReferencedExternalDependency(workspace, packageName);
67
67
  if (!isHandled)
68
68
  collector.addIssue({ type: 'unlisted', filePath: containingFilePath, symbol: specifier });
69
- if (specifier !== packageName) {
69
+ if (packageName && specifier !== packageName) {
70
70
  const otherWorkspace = chief.findWorkspaceByPackageName(packageName);
71
71
  if (otherWorkspace) {
72
72
  const filePath = _resolveSpecifier(otherWorkspace.dir, specifier);
@@ -194,7 +194,7 @@ export const main = async (unresolvedConfiguration) => {
194
194
  exportedSymbols.set(filePath, exported);
195
195
  for (const [specifierFilePath, importItems] of internal.entries()) {
196
196
  const packageName = getPackageNameFromModuleSpecifier(importItems.specifier);
197
- if (chief.localWorkspaces.has(packageName))
197
+ if (packageName && chief.localWorkspaces.has(packageName))
198
198
  external.add(packageName);
199
199
  if (!importedSymbols.has(specifierFilePath)) {
200
200
  importedSymbols.set(specifierFilePath, importItems);
@@ -220,7 +220,7 @@ export const main = async (unresolvedConfiguration) => {
220
220
  });
221
221
  external.forEach(specifier => {
222
222
  const packageName = getPackageNameFromModuleSpecifier(specifier);
223
- const isHandled = deputy.maybeAddReferencedExternalDependency(workspace, packageName);
223
+ const isHandled = packageName && deputy.maybeAddReferencedExternalDependency(workspace, packageName);
224
224
  if (!isHandled)
225
225
  collector.addIssue({ type: 'unlisted', filePath, symbol: specifier });
226
226
  });
@@ -57,10 +57,12 @@ const resolveExtendsSpecifier = (specifier) => {
57
57
  .replace(/\/(eslint-)?(recommended.*|strict|all)$/, '');
58
58
  if (/eslint-(config|plugin)-/.test(strippedSpecifier))
59
59
  return strippedSpecifier;
60
- const pluginName = getPackageNameFromModuleSpecifier(strippedSpecifier);
61
- if (pluginName === 'eslint')
60
+ const packageName = getPackageNameFromModuleSpecifier(strippedSpecifier);
61
+ if (!packageName)
62
62
  return;
63
- return resolvePackageName(specifier.startsWith('plugin:') ? 'eslint-plugin' : 'eslint-config', pluginName);
63
+ if (packageName === 'eslint')
64
+ return;
65
+ return resolvePackageName(specifier.startsWith('plugin:') ? 'eslint-plugin' : 'eslint-config', packageName);
64
66
  };
65
67
  const getDependenciesFromSettings = (settings = {}) => {
66
68
  return compact(Object.entries(settings).flatMap(([settingKey, settings]) => {
@@ -1,6 +1,7 @@
1
1
  import { isBuiltin } from 'node:module';
2
2
  import ts from 'typescript';
3
3
  import { getOrSet } from '../util/map.js';
4
+ import { isMaybePackageName } from '../util/modules.js';
4
5
  import { isInNodeModules } from '../util/path.js';
5
6
  import { isDeclarationFileExtension, isAccessExpression, getAccessExpressionName } from './ast-helpers.js';
6
7
  import getExportVisitors from './visitors/exports/index.js';
@@ -56,7 +57,9 @@ export const getImportsAndExports = (sourceFile, options) => {
56
57
  if (!isInNodeModules(filePath)) {
57
58
  addInternalImport({ identifier, specifier, symbol, filePath, isDynamic, isReExport });
58
59
  }
59
- else if (isDeclarationFileExtension(module.resolvedModule.extension)) {
60
+ if (!isMaybePackageName(specifier))
61
+ return;
62
+ if (isDeclarationFileExtension(module.resolvedModule.extension)) {
60
63
  externalImports.add(specifier);
61
64
  }
62
65
  else {
@@ -4,7 +4,7 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
4
4
  syncCompilers: Record<string, SyncCompilerFn>;
5
5
  asyncCompilers: Record<string, AsyncCompilerFn>;
6
6
  exclude?: string[] | undefined;
7
- rules?: Partial<Record<"files" | "dependencies" | "devDependencies" | "unlisted" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers", "error" | "warn" | "off">> | undefined;
7
+ rules?: Partial<Record<"files" | "dependencies" | "devDependencies" | "unlisted" | "binaries" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers", "error" | "warn" | "off">> | undefined;
8
8
  entry?: string | string[] | undefined;
9
9
  project?: string | string[] | undefined;
10
10
  paths?: Record<string, string[]> | undefined;
@@ -1,6 +1,7 @@
1
1
  import type { PackageJson } from '@npmcli/package-json';
2
- export declare const getPackageNameFromModuleSpecifier: (moduleSpecifier: string) => string;
2
+ export declare const getPackageNameFromModuleSpecifier: (moduleSpecifier: string) => string | undefined;
3
3
  export declare const getPackageNameFromFilePath: (value: string) => string;
4
+ export declare const isMaybePackageName: (specifier: string) => boolean;
4
5
  export declare const isDefinitelyTyped: (packageName: string) => boolean;
5
6
  export declare const getDefinitelyTypedFor: (packageName: string) => string;
6
7
  export declare const getPackageFromDefinitelyTyped: (typedDependency: string) => string;
@@ -2,6 +2,8 @@ import { _glob } from './glob.js';
2
2
  import { getStringValues } from './object.js';
3
3
  import { toPosix } from './path.js';
4
4
  export const getPackageNameFromModuleSpecifier = (moduleSpecifier) => {
5
+ if (!isMaybePackageName(moduleSpecifier))
6
+ return;
5
7
  const parts = moduleSpecifier.split('/').slice(0, 2);
6
8
  return moduleSpecifier.startsWith('@') ? parts.join('/') : parts[0];
7
9
  };
@@ -11,6 +13,7 @@ export const getPackageNameFromFilePath = (value) => {
11
13
  return match[match.length - 1];
12
14
  return value;
13
15
  };
16
+ export const isMaybePackageName = (specifier) => /^@?[a-z0-9]/.test(specifier);
14
17
  export const isDefinitelyTyped = (packageName) => packageName.startsWith('@types/');
15
18
  export const getDefinitelyTypedFor = (packageName) => {
16
19
  if (isDefinitelyTyped(packageName))
@@ -21,8 +21,11 @@ const resolveSpecifier = (dir, specifier) => {
21
21
  return toPosix(require.resolve(specifier));
22
22
  }
23
23
  catch {
24
- const relativeSpecifier = specifier.replace(getPackageNameFromModuleSpecifier(specifier), '.');
25
- return tryResolve(join(dir, relativeSpecifier), dir);
24
+ const packageName = getPackageNameFromModuleSpecifier(specifier);
25
+ if (packageName) {
26
+ const relativeSpecifier = specifier.replace(packageName, '.');
27
+ return tryResolve(join(dir, relativeSpecifier), dir);
28
+ }
26
29
  }
27
30
  };
28
31
  export const _require = timerify(require);
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.12.1";
1
+ export declare const version = "2.12.3";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.12.1';
1
+ export const version = '2.12.3';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.12.1",
3
+ "version": "2.12.3",
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",