knip 5.61.3 → 5.62.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.
@@ -16,7 +16,7 @@ import { defaultRules } from './util/issue-initializers.js';
16
16
  import { _load } from './util/loader.js';
17
17
  import mapWorkspaces from './util/map-workspaces.js';
18
18
  import { getKeysByValue } from './util/object.js';
19
- import { join, relative } from './util/path.js';
19
+ import { isAbsolute, join, relative } from './util/path.js';
20
20
  import { normalizePluginConfig } from './util/plugin.js';
21
21
  import { toRegexOrString } from './util/regex.js';
22
22
  import { ELLIPSIS } from './util/string.js';
@@ -100,7 +100,7 @@ export class ConfigurationChief {
100
100
  this.manifest.workspaces = pnpmWorkspaces;
101
101
  }
102
102
  for (const configPath of rawConfigArg ? [rawConfigArg] : KNIP_CONFIG_LOCATIONS) {
103
- this.resolvedConfigFilePath = findFile(this.cwd, configPath);
103
+ this.resolvedConfigFilePath = isAbsolute(configPath) ? configPath : findFile(this.cwd, configPath);
104
104
  if (this.resolvedConfigFilePath)
105
105
  break;
106
106
  }
@@ -3,7 +3,21 @@ import { isFile } from '../../util/fs.js';
3
3
  import { toEntry } from '../../util/input.js';
4
4
  import { isAbsolute, join } from '../../util/path.js';
5
5
  import { resolveX } from './bunx.js';
6
- const commands = ['add', 'create', 'init', 'install', 'link', 'pm', 'remove', 'run', 'test', 'update', 'upgrade', 'x'];
6
+ const commands = [
7
+ 'add',
8
+ 'audit',
9
+ 'create',
10
+ 'init',
11
+ 'install',
12
+ 'link',
13
+ 'pm',
14
+ 'remove',
15
+ 'run',
16
+ 'test',
17
+ 'update',
18
+ 'upgrade',
19
+ 'x',
20
+ ];
7
21
  export const resolve = (_binary, args, options) => {
8
22
  const parsed = parseArgs(args, { string: ['cwd'] });
9
23
  const [command, script] = parsed._;
@@ -7,12 +7,12 @@ import { debugLog, debugLogArray } from '../util/debug.js';
7
7
  import { getReferencedInputsHandler } from '../util/get-referenced-inputs.js';
8
8
  import { _glob, negate } from '../util/glob.js';
9
9
  import { isAlias, isConfig, isDeferResolveEntry, isDeferResolveProductionEntry, isEntry, isIgnore, isProductionEntry, isProject, toProductionEntry, } from '../util/input.js';
10
+ import { loadTSConfig } from '../util/load-tsconfig.js';
10
11
  import { getOrCreateFileNode, updateImportMap } from '../util/module-graph.js';
11
12
  import { getPackageNameFromModuleSpecifier, isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
12
13
  import { getEntryPathsFromManifest } from '../util/package-json.js';
13
14
  import { dirname, extname, isAbsolute, join, relative, toRelative } from '../util/path.js';
14
15
  import { augmentWorkspace, getToSourcePathHandler, getToSourcePathsHandler } from '../util/to-source-path.js';
15
- import { loadTSConfig } from '../util/tsconfig-loader.js';
16
16
  export async function build({ cacheLocation, chief, collector, cwd, deputy, factory, gitignore, isCache, isFixExports, isFixTypes, isGitIgnored, isIsolateWorkspaces, isProduction, isSkipLibs, isStrict, isWatch, report, streamer, tags, tsConfigFile, workspaces, }) {
17
17
  const configFilesMap = new Map();
18
18
  const enabledPluginsStore = new Map();
@@ -18,7 +18,7 @@ const resolveConfig = async (config, options) => {
18
18
  for (const [targetName, target] of Object.entries(project.architect)) {
19
19
  const { options: opts, configurations: configs } = target;
20
20
  const [packageName] = typeof target.builder === 'string' ? target.builder.split(':') : [];
21
- if (typeof packageName === 'string')
21
+ if (packageName)
22
22
  inputs.add(toDependency(packageName));
23
23
  if (opts) {
24
24
  if ('tsConfig' in opts && typeof opts.tsConfig === 'string') {
@@ -55,7 +55,7 @@ const resolveConfig = async (config, options) => {
55
55
  }));
56
56
  }
57
57
  }
58
- if (target.builder === '@angular-devkit/build-angular:karma' && opts) {
58
+ if (target.builder && isAngularBuilderRefWithName({ builderRef: target.builder, name: 'karma' }) && opts) {
59
59
  const karmaBuilderOptions = opts;
60
60
  const testFilePatterns = karmaBuilderOptions.include ?? ['**/*.spec.ts'];
61
61
  for (const testFilePattern of testFilePatterns) {
@@ -103,6 +103,10 @@ const entriesByOption = (opts) => new Map(Object.entries({
103
103
  ? [opts.ssr.entry]
104
104
  : [],
105
105
  }));
106
+ const isAngularBuilderRefWithName = ({ builderRef, name }) => {
107
+ const [pkg, builderName] = builderRef.split(':');
108
+ return (pkg === '@angular-devkit/build-angular' || pkg === '@angular/build') && builderName === name;
109
+ };
106
110
  const PRODUCTION_CONFIG_NAME = 'production';
107
111
  const BUILD_TARGET_NAME = 'build';
108
112
  export default {
@@ -14,14 +14,10 @@ const production = [
14
14
  ];
15
15
  const resolveFromAST = sourceFile => {
16
16
  const srcDir = getSrcDir(sourceFile);
17
+ const setSrcDir = (entry) => entry.replace(/^`src\//, `${srcDir}/`);
17
18
  return [
18
- ...[`${srcDir}/content/config.ts`, `${srcDir}/content.config.ts`].map(path => toEntry(path)),
19
- ...[
20
- `${srcDir}/pages/**/*.{astro,mdx,js,ts}`,
21
- `${srcDir}/content/**/*.mdx`,
22
- `${srcDir}/middleware.{js,ts}`,
23
- `${srcDir}/actions/index.{js,ts}`,
24
- ].map(path => toProductionEntry(path)),
19
+ ...entry.map(setSrcDir).map(path => toEntry(path)),
20
+ ...production.map(setSrcDir).map(path => toProductionEntry(path)),
25
21
  ];
26
22
  };
27
23
  const resolve = options => {
@@ -20,6 +20,5 @@ export const getSrcDir = (sourceFile) => {
20
20
  });
21
21
  return result;
22
22
  }
23
- const foundValue = visit(sourceFile);
24
- return foundValue ?? srcDir;
23
+ return visit(sourceFile) ?? srcDir;
25
24
  };
@@ -1,14 +1,22 @@
1
+ import { arrayify } from '../../util/array.js';
1
2
  import { toConfig } from '../../util/input.js';
3
+ import { join } from '../../util/path.js';
2
4
  import { hasDependency } from '../../util/plugin.js';
3
5
  const title = 'Biome';
4
6
  const enablers = ['@biomejs/biome'];
5
7
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
8
  const config = ['biome.json', 'biome.jsonc'];
9
+ const isRootConfigReference = (specifier) => specifier === '//';
7
10
  const resolveExtends = (extendsArray, options) => {
8
- return extendsArray.map(specifier => toConfig('biome', specifier, { containingFilePath: options.configFilePath }));
11
+ return extendsArray.map(specifier => {
12
+ if (isRootConfigReference(specifier)) {
13
+ return toConfig('biome', join(options.rootCwd, 'biome'), { containingFilePath: options.configFilePath });
14
+ }
15
+ return toConfig('biome', specifier, { containingFilePath: options.configFilePath });
16
+ });
9
17
  };
10
18
  const resolveConfig = (config, options) => {
11
- return [...resolveExtends(config.extends || [], options)];
19
+ return [...resolveExtends(arrayify(config.extends), options)];
12
20
  };
13
21
  export default {
14
22
  title,
@@ -8,7 +8,8 @@ export const getInputs = (config, options) => {
8
8
  if (extname(configFileName) === '.json' || !/eslint\.config/.test(configFileName)) {
9
9
  return getInputsDeprecated(config, options);
10
10
  }
11
- const dependencies = config.flatMap(config => config.settings ? getDependenciesFromSettings(config.settings).filter(id => id !== '@typescript-eslint/parser') : []);
11
+ const dependencies = config.flatMap(config => config.settings ? getDependenciesFromSettings(config.settings) : []);
12
+ dependencies.push('eslint-import-resolver-typescript');
12
13
  return compact(dependencies).map(id => toDeferResolve(id, { optional: true }));
13
14
  };
14
15
  const getInputsDeprecated = (config, options) => {
@@ -7,7 +7,7 @@ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
7
  const config = [
8
8
  'package.json',
9
9
  'postcss.config.json',
10
- ...toLilconfig('postcss', { configDir: false, additionalExtensions: ['ts', 'mts', 'cts', 'yaml', 'yml'] }),
10
+ ...toLilconfig('postcss', { configDir: false, additionalExtensions: ['mts', 'cts', 'yaml', 'yml'] }),
11
11
  ];
12
12
  const resolveConfig = config => {
13
13
  const plugins = config.plugins
@@ -6,7 +6,7 @@ const enablers = ['size-limit'];
6
6
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
7
  const config = [
8
8
  'package.json',
9
- ...toLilconfig('size-limit', { configDir: false, additionalExtensions: ['ts', 'mts', 'cts'], rcSuffix: '' }),
9
+ ...toLilconfig('size-limit', { configDir: false, additionalExtensions: ['mts', 'cts'], rcSuffix: '' }),
10
10
  ];
11
11
  const resolve = options => {
12
12
  const allDeps = [
@@ -1,5 +1,6 @@
1
1
  import { DEFAULT_EXTENSIONS } from '../../constants.js';
2
- import { toAlias, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
2
+ import { _glob } from '../../util/glob.js';
3
+ import { toAlias, toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
3
4
  import { join, toPosix } from '../../util/path.js';
4
5
  import { hasDependency } from '../../util/plugin.js';
5
6
  import { getEnvPackageName, getExternalReporters } from './helpers.js';
@@ -28,11 +29,20 @@ const findConfigDependencies = (localConfig, options) => {
28
29
  workspaceDependencies.push(...findConfigDependencies(workspaceConfig, options));
29
30
  }
30
31
  }
32
+ const projectsDependencies = [];
33
+ if (testConfig.projects !== undefined) {
34
+ for (const projectConfig of testConfig.projects) {
35
+ if (typeof projectConfig !== 'string') {
36
+ projectsDependencies.push(...findConfigDependencies(projectConfig, options));
37
+ }
38
+ }
39
+ }
31
40
  return [
32
41
  ...[...environments, ...reporters, ...coverage].map(id => toDependency(id)),
33
42
  ...setupFiles,
34
43
  ...globalSetup,
35
44
  ...workspaceDependencies,
45
+ ...projectsDependencies,
36
46
  ];
37
47
  };
38
48
  const getConfigs = async (localConfig) => {
@@ -44,11 +54,25 @@ const getConfigs = async (localConfig) => {
44
54
  for (const mode of ['development', 'production']) {
45
55
  const cfg = await config({ command, mode, ssrBuild: undefined });
46
56
  configs.push(cfg);
57
+ if (cfg.test?.projects) {
58
+ for (const project of cfg.test.projects) {
59
+ if (typeof project !== 'string') {
60
+ configs.push(project);
61
+ }
62
+ }
63
+ }
47
64
  }
48
65
  }
49
66
  }
50
67
  else {
51
68
  configs.push(config);
69
+ if (config.test?.projects) {
70
+ for (const project of config.test.projects) {
71
+ if (typeof project !== 'string') {
72
+ configs.push(project);
73
+ }
74
+ }
75
+ }
52
76
  }
53
77
  }
54
78
  }
@@ -58,6 +82,22 @@ export const resolveConfig = async (localConfig, options) => {
58
82
  const inputs = new Set();
59
83
  inputs.add(toEntry(join(options.cwd, 'src/vite-env.d.ts')));
60
84
  const configs = await getConfigs(localConfig);
85
+ for (const cfg of configs) {
86
+ if (cfg.test?.projects) {
87
+ for (const project of cfg.test.projects) {
88
+ if (typeof project === 'string') {
89
+ const projectFiles = await _glob({
90
+ cwd: options.cwd,
91
+ patterns: [project],
92
+ gitignore: false,
93
+ });
94
+ for (const projectFile of projectFiles) {
95
+ inputs.add(toConfig('vitest', projectFile, { containingFilePath: options.configFilePath }));
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
61
101
  const addStar = (value) => (value.endsWith('*') ? value : join(value, '*').replace(/\/\*\*$/, '/*'));
62
102
  const addAliases = (aliasOptions) => {
63
103
  for (const [alias, value] of Object.entries(aliasOptions)) {
@@ -23,6 +23,11 @@ interface VitestConfig {
23
23
  workspace: never;
24
24
  };
25
25
  })[];
26
+ projects?: (string | (ViteConfig & {
27
+ test: VitestConfig['test'] & {
28
+ projects: never;
29
+ };
30
+ }))[];
26
31
  alias?: AliasOptions;
27
32
  };
28
33
  }
@@ -149,7 +149,7 @@ const getMemberStringLiterals = (typeChecker, node) => {
149
149
  return type.types.map(type => type.value);
150
150
  }
151
151
  if (ts.isPropertyAccessExpression(node)) {
152
- return [node.name.escapedText];
152
+ return [node.name.getText()];
153
153
  }
154
154
  };
155
155
  export const getAccessMembers = (typeChecker, node) => {
@@ -23,7 +23,7 @@ const toConfigMap = (defaultExtensions, builderConfig) => (moduleName, options)
23
23
  return [...baseFiles, rcFiles, ...configFiles, ...configDirFiles];
24
24
  };
25
25
  export const toCosmiconfig = toConfigMap(['json', 'yaml', 'yml', 'js', 'ts', 'cjs', 'mjs'], { configDir: true });
26
- export const toLilconfig = toConfigMap(['json', 'js', 'cjs', 'mjs'], { configDir: true });
26
+ export const toLilconfig = toConfigMap(['json', 'ts', 'js', 'cjs', 'mjs'], { configDir: true });
27
27
  export const toUnconfig = toConfigMap(['json', 'ts', 'mts', 'cts', 'js', 'mjs', 'cjs'], {
28
28
  configDir: false,
29
29
  rcPrefix: '',
@@ -16,6 +16,6 @@ const createSyncResolver = (extensions) => {
16
16
  catch (_error) { }
17
17
  };
18
18
  };
19
- const resolveSync = createSyncResolver([...DEFAULT_EXTENSIONS, '.json']);
19
+ const resolveSync = createSyncResolver([...DEFAULT_EXTENSIONS, '.json', '.jsonc']);
20
20
  export const _resolveSync = timerify(resolveSync);
21
21
  export const _createSyncResolver = extensions => timerify(createSyncResolver(extensions));
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.61.3";
1
+ export declare const version = "5.62.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.61.3';
1
+ export const version = '5.62.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.61.3",
3
+ "version": "5.62.0",
4
4
  "description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://knip.dev",
6
6
  "repository": {