knip 6.44.0 → 6.44.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.
- package/README.md +2 -4
- package/dist/DependencyDeputy.js +2 -2
- package/dist/ProjectPrincipal.d.ts +2 -1
- package/dist/ProjectPrincipal.js +3 -3
- package/dist/binaries/resolvers/bun.js +7 -2
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/plugins/babel/index.js +6 -1
- package/dist/plugins/cspell/index.js +9 -2
- package/dist/plugins/eleventy/index.js +2 -2
- package/dist/plugins/mocha/index.js +1 -1
- package/dist/plugins/npm-package-json-lint/index.js +1 -1
- package/dist/plugins/npm-package-json-lint/types.d.ts +1 -1
- package/dist/plugins/relay/index.js +1 -1
- package/dist/plugins/release-it/index.js +1 -1
- package/dist/plugins/rsbuild/index.js +29 -1
- package/dist/plugins/rsbuild/types.d.ts +8 -0
- package/dist/plugins/svgr/index.js +2 -1
- package/dist/plugins/swc/index.js +8 -3
- package/dist/plugins/webpack/index.d.ts +2 -0
- package/dist/plugins/webpack/index.js +7 -4
- package/dist/session/configuration.d.ts +3 -0
- package/dist/session/configuration.js +19 -0
- package/dist/session/session.js +4 -3
- package/dist/typescript/visitors/imports.d.ts +2 -1
- package/dist/typescript/visitors/imports.js +57 -39
- package/dist/typescript/visitors/walk.js +2 -1
- package/dist/util/create-options.d.ts +1 -1
- package/dist/util/create-options.js +4 -2
- package/dist/util/loader.js +10 -18
- package/dist/util/modules.js +2 -1
- package/dist/util/watch.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,8 +50,7 @@ following projects:
|
|
|
50
50
|
[2]: https://img.shields.io/npm/v/knip?color=f56e0f
|
|
51
51
|
[3]: https://img.shields.io/badge/dynamic/json?url=https://npm-gapless.webpro.nl/downloads/range/last-month/knip&query=$.totalCompact&label=downloads&suffix=/month&color=f56e0f
|
|
52
52
|
[4]: https://github.com/webpro-nl/knip
|
|
53
|
-
[5]:
|
|
54
|
-
https://img.shields.io/github/stars/webpro-nl/knip?style=flat&color=f56e0f
|
|
53
|
+
[5]: https://img.shields.io/github/stars/webpro-nl/knip?style=flat&color=f56e0f
|
|
55
54
|
[6]: https://knip.dev
|
|
56
55
|
[7]: https://www.npmx.dev/package/@knip/create-config
|
|
57
56
|
[8]: https://www.npmx.dev/package/@knip/language-server
|
|
@@ -69,7 +68,6 @@ following projects:
|
|
|
69
68
|
[20]: https://github.com/pnpm/pnpm/tree/main/deps/graph-sequencer
|
|
70
69
|
[21]: https://github.com/pnpm/pnpm/blob/main/LICENSE
|
|
71
70
|
[22]: https://github.com/jaredwray/cacheable/tree/main/packages/file-entry-cache
|
|
72
|
-
[23]:
|
|
73
|
-
https://github.com/jaredwray/cacheable/blob/main/packages/file-entry-cache/LICENSE
|
|
71
|
+
[23]: https://github.com/jaredwray/cacheable/blob/main/packages/file-entry-cache/LICENSE
|
|
74
72
|
[24]: https://github.com/npm/json-parse-even-better-errors
|
|
75
73
|
[25]: https://github.com/npm/json-parse-even-better-errors/blob/main/LICENSE.md
|
package/dist/DependencyDeputy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isBuiltin } from 'node:module';
|
|
2
|
-
import { DT_SCOPE, IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES, IGNORED_RUNTIME_DEPENDENCIES, ROOT_WORKSPACE_NAME, } from './constants.js';
|
|
2
|
+
import { DT_SCOPE, IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES, IGNORED_RUNTIME_DEPENDENCIES, PROTOCOL_CLOUDFLARE, ROOT_WORKSPACE_NAME, } from './constants.js';
|
|
3
3
|
import { getDependencyMetaData } from './manifest/index.js';
|
|
4
4
|
import { PackagePeeker } from './PackagePeeker.js';
|
|
5
5
|
import { getDefinitelyTypedFor, getPackageFromDefinitelyTyped, getPackageNameFromModuleSpecifier, isDefinitelyTyped, } from './util/modules.js';
|
|
@@ -127,7 +127,7 @@ export class DependencyDeputy {
|
|
|
127
127
|
maybeAddReferencedExternalDependency(workspace, packageName, { specifier, isDevOnly, isTypeOnly, isResolved, isPublishedType, isCaught }) {
|
|
128
128
|
if (!this.isReportDependencies)
|
|
129
129
|
return true;
|
|
130
|
-
if (specifier.startsWith('node:') || isBuiltin(specifier))
|
|
130
|
+
if (specifier.startsWith('node:') || specifier.startsWith(PROTOCOL_CLOUDFLARE) || isBuiltin(specifier))
|
|
131
131
|
return true;
|
|
132
132
|
if (IGNORED_RUNTIME_DEPENDENCIES.has(packageName))
|
|
133
133
|
return true;
|
|
@@ -2,6 +2,7 @@ import type { ParseResult } from 'oxc-parser';
|
|
|
2
2
|
import { CacheConsultant } from './CacheConsultant.ts';
|
|
3
3
|
import type { Compilers } from './compilers/types.ts';
|
|
4
4
|
import type { GetImportsAndExportsOptions, IgnoreExportsUsedInFile, PluginVisitorContext, PluginVisitorObject } from './types/config.ts';
|
|
5
|
+
import type { ConfigurationFiles } from './session/configuration.ts';
|
|
5
6
|
import type { FileNode } from './types/module-graph.ts';
|
|
6
7
|
import type { Paths } from './types/project.ts';
|
|
7
8
|
import type { ResolveGlobPattern } from './typescript/resolve-module-names.ts';
|
|
@@ -39,7 +40,7 @@ export declare class ProjectPrincipal {
|
|
|
39
40
|
addCompilers(workspaceName: string, compilers: Compilers): void;
|
|
40
41
|
addPaths(paths: Paths, basePath: string, scope: string): void;
|
|
41
42
|
addRootDirs(rootDirs: string[] | undefined, scope: string): void;
|
|
42
|
-
collectConfigurationImports(
|
|
43
|
+
collectConfigurationImports(configurationFiles: ConfigurationFiles): void;
|
|
43
44
|
init(): void;
|
|
44
45
|
private hasAcceptedExtension;
|
|
45
46
|
addEntryPath(filePath: string, options?: {
|
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -100,8 +100,8 @@ export class ProjectPrincipal {
|
|
|
100
100
|
const scoped = this.rootDirs.get(scope) ?? [];
|
|
101
101
|
this.rootDirs.set(scope, compact([...scoped, ...rootDirs]));
|
|
102
102
|
}
|
|
103
|
-
collectConfigurationImports(
|
|
104
|
-
for (const filePath of paths) {
|
|
103
|
+
collectConfigurationImports(configurationFiles) {
|
|
104
|
+
for (const filePath of configurationFiles.paths) {
|
|
105
105
|
if (!DEFAULT_EXTENSIONS.has(extname(filePath)))
|
|
106
106
|
continue;
|
|
107
107
|
const source = this.fileManager.readRawFile(filePath);
|
|
@@ -111,7 +111,7 @@ export class ProjectPrincipal {
|
|
|
111
111
|
for (const specifier of extractSpecifiers(_parseFile(filePath, source), source, filePath)) {
|
|
112
112
|
const resolved = this.resolveSpecifier(specifier, filePath);
|
|
113
113
|
if (resolved && !isInNodeModules(resolved))
|
|
114
|
-
|
|
114
|
+
configurationFiles.addImport(filePath, resolved);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
catch { }
|
|
@@ -56,7 +56,12 @@ const commands = new Set([
|
|
|
56
56
|
]);
|
|
57
57
|
export const resolve = (_binary, words, options) => {
|
|
58
58
|
const binary = toCommandBinary(_binary, options);
|
|
59
|
-
const parsed = parseArgs(words, {
|
|
59
|
+
const parsed = parseArgs(words, {
|
|
60
|
+
string: ['cwd'],
|
|
61
|
+
boolean: ['bun', 'hot', 'if-present', 'silent', 'smol', 'watch'],
|
|
62
|
+
alias: { bun: 'b' },
|
|
63
|
+
isStorePositions: true,
|
|
64
|
+
});
|
|
60
65
|
const [command, script] = parsed._;
|
|
61
66
|
if (command === 'x') {
|
|
62
67
|
const wordsForX = words.filter(word => word.value !== 'x');
|
|
@@ -81,7 +86,7 @@ export const resolve = (_binary, words, options) => {
|
|
|
81
86
|
const dir = parsed.cwd ? join(cwd, parsed.cwd) : undefined;
|
|
82
87
|
const opts = dir ? { cwd: dir } : {};
|
|
83
88
|
if (command !== 'run')
|
|
84
|
-
return [binary, ...fromArgs(words, opts)];
|
|
89
|
+
return [binary, ...fromArgs(dir ? words : words.slice(parsed.positionalIndices[0]), opts)];
|
|
85
90
|
const input = toBinary(filePath, { optional: true });
|
|
86
91
|
if (dir)
|
|
87
92
|
input.dir = dir;
|
package/dist/constants.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare const BETA_TAG = "@beta";
|
|
|
11
11
|
export declare const ALIAS_TAG = "@alias";
|
|
12
12
|
export declare const DT_SCOPE = "@types";
|
|
13
13
|
export declare const PROTOCOL_VIRTUAL = "virtual:";
|
|
14
|
+
export declare const PROTOCOL_CLOUDFLARE = "cloudflare:";
|
|
14
15
|
export declare const IGNORED_GLOBAL_BINARIES: Set<string>;
|
|
15
16
|
export declare const IGNORED_DEPENDENCIES: Set<string>;
|
|
16
17
|
export declare const IGNORED_RUNTIME_DEPENDENCIES: Set<string>;
|
package/dist/constants.js
CHANGED
|
@@ -20,6 +20,7 @@ export const BETA_TAG = '@beta';
|
|
|
20
20
|
export const ALIAS_TAG = '@alias';
|
|
21
21
|
export const DT_SCOPE = '@types';
|
|
22
22
|
export const PROTOCOL_VIRTUAL = 'virtual:';
|
|
23
|
+
export const PROTOCOL_CLOUDFLARE = 'cloudflare:';
|
|
23
24
|
export const IGNORED_GLOBAL_BINARIES = new Set([
|
|
24
25
|
'amplify',
|
|
25
26
|
'aws',
|
|
@@ -5,7 +5,12 @@ import { api, resolveName } from './helpers.js';
|
|
|
5
5
|
const title = 'Babel';
|
|
6
6
|
const enablers = [/^@babel\//];
|
|
7
7
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
8
|
-
const config = [
|
|
8
|
+
const config = [
|
|
9
|
+
'babel.config.{json,js,cjs,mjs,cts,ts,mts}',
|
|
10
|
+
'.babelrc.{json,js,cjs,mjs,cts}',
|
|
11
|
+
'.babelrc',
|
|
12
|
+
'package.json',
|
|
13
|
+
];
|
|
9
14
|
const getName = (value) => [Array.isArray(value) ? value[0] : value].filter(name => typeof name === 'string');
|
|
10
15
|
export const getDependenciesFromConfig = (config) => {
|
|
11
16
|
const presets = config.presets?.flatMap(getName).map(name => resolveName(name, 'preset')) ?? [];
|
|
@@ -5,10 +5,17 @@ const enablers = ['cspell'];
|
|
|
5
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
6
|
const config = [
|
|
7
7
|
'package.json',
|
|
8
|
-
'cspell.config.{js,cjs,mjs,ts,mts,json,yaml,yml}',
|
|
9
|
-
'cspell.{
|
|
8
|
+
'{.,}cspell.config.{js,cjs,mjs,ts,cts,mts,json,jsonc,yaml,yml,toml}',
|
|
9
|
+
'{.,}cspell.{jsonc,yaml,yml}',
|
|
10
10
|
'.c{s,S}pell.json',
|
|
11
11
|
'c{s,S}pell.json',
|
|
12
|
+
'.vscode/c{s,S}pell.json',
|
|
13
|
+
'.vscode/.cspell.json',
|
|
14
|
+
'.config/{.,}cspell.config.{js,cjs,mjs,ts,cts,mts,json,jsonc,yaml,yml,toml}',
|
|
15
|
+
'.config/.c{s,S}pell.json',
|
|
16
|
+
'.config/c{s,S}pell.json',
|
|
17
|
+
'.config/{.,}cspell.jsonc',
|
|
18
|
+
'.config/cspell.{yaml,yml}',
|
|
12
19
|
];
|
|
13
20
|
const resolveConfig = config => {
|
|
14
21
|
return [config?.import ?? []].flat().map(id => toDeferResolve(id));
|
|
@@ -8,7 +8,7 @@ const title = 'Eleventy';
|
|
|
8
8
|
const enablers = ['@11ty/eleventy'];
|
|
9
9
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
10
10
|
const config = ['.eleventy.js', 'eleventy.config.{js,cjs,mjs}'];
|
|
11
|
-
const production = ['posts/**/*.11tydata.js', '_data/**/*.{js,cjs,mjs}'];
|
|
11
|
+
const production = ['posts/**/*.11tydata.{js,cjs,mjs}', '_data/**/*.{js,cjs,mjs}'];
|
|
12
12
|
const resolveConfig = async (localConfig, options) => {
|
|
13
13
|
const { configFileDir } = options;
|
|
14
14
|
const dummyUserConfig = new DummyEleventyConfig();
|
|
@@ -38,7 +38,7 @@ const resolveConfig = async (localConfig, options) => {
|
|
|
38
38
|
.concat([
|
|
39
39
|
join(inputDir, dataDir, '**/*.{js,cjs,mjs}'),
|
|
40
40
|
join(inputDir, `**/*.{${typeof templateFormats === 'string' ? templateFormats : templateFormats.join(',')}}`),
|
|
41
|
-
join(inputDir, '**/*.11tydata.js'),
|
|
41
|
+
join(inputDir, '**/*.11tydata.{js,cjs,mjs}'),
|
|
42
42
|
...copiedEntries,
|
|
43
43
|
].map(id => toProductionEntry(id)));
|
|
44
44
|
};
|
|
@@ -4,7 +4,7 @@ import { hasDependency } from '../../util/plugin.js';
|
|
|
4
4
|
const title = 'Mocha';
|
|
5
5
|
const enablers = ['mocha'];
|
|
6
6
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
7
|
-
const config = ['.mocharc.{js,cjs,json,jsonc,yml,yaml}', 'package.json'];
|
|
7
|
+
const config = ['.mocharc.{js,cjs,mjs,json,jsonc,yml,yaml}', 'package.json'];
|
|
8
8
|
const entry = ['**/test/*.{js,cjs,mjs}'];
|
|
9
9
|
const defaultExtensions = ['js', 'cjs', 'mjs'];
|
|
10
10
|
const builtInReporters = new Set([
|
|
@@ -7,7 +7,7 @@ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
|
7
7
|
const packageJsonPath = 'npmpackagejsonlint';
|
|
8
8
|
const config = ['package.json', ...toCosmiconfig('npmpackagejsonlint')];
|
|
9
9
|
const resolveConfig = localConfig => {
|
|
10
|
-
return localConfig?.extends ? [localConfig.extends].map(id => toDependency(id)) : [];
|
|
10
|
+
return localConfig?.extends ? [localConfig.extends].flat().map(id => toDependency(id)) : [];
|
|
11
11
|
};
|
|
12
12
|
const plugin = {
|
|
13
13
|
title,
|
|
@@ -5,7 +5,7 @@ import { hasDependency } from '../../util/plugin.js';
|
|
|
5
5
|
const title = 'Relay';
|
|
6
6
|
const enablers = ['vite-plugin-relay', '@swc/plugin-relay', 'babel-plugin-relay'];
|
|
7
7
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
8
|
-
const config = ['relay.config.json', 'relay.config.js'];
|
|
8
|
+
const config = ['package.json', 'relay.config.json', 'relay.config.js'];
|
|
9
9
|
const resolveConfig = async (config) => {
|
|
10
10
|
const projects = 'projects' in config ? Object.values(config.projects) : [config];
|
|
11
11
|
return projects.map(project => {
|
|
@@ -3,7 +3,7 @@ import { hasDependency } from '../../util/plugin.js';
|
|
|
3
3
|
const title = 'Release It!';
|
|
4
4
|
const enablers = ['release-it'];
|
|
5
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
|
-
const config = ['.release-it.{json,js,cjs,ts,yml,yaml,toml}', 'package.json'];
|
|
6
|
+
const config = ['.release-it.{json,jsonc,json5,js,mjs,cjs,ts,mts,cts,yml,yaml,toml}', 'package.json'];
|
|
7
7
|
const resolveConfig = (config, options) => {
|
|
8
8
|
const plugins = config.plugins ? Object.keys(config.plugins) : [];
|
|
9
9
|
const scripts = config.hooks ? Object.values(config.hooks).flat() : [];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { toProductionEntry } from '../../util/input.js';
|
|
1
|
+
import { toDeferResolve, toProductionEntry } from '../../util/input.js';
|
|
2
2
|
import { hasDependency } from '../../util/plugin.js';
|
|
3
3
|
import { resolveConfig as resolveRspackConfig } from '../rspack/index.js';
|
|
4
|
+
import { getSwcPluginSpecifiers } from '../webpack/index.js';
|
|
4
5
|
const title = 'Rsbuild';
|
|
5
6
|
const enablers = ['@rsbuild/core'];
|
|
6
7
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
@@ -17,6 +18,22 @@ const getConfigs = async (configOrFn) => {
|
|
|
17
18
|
configs.push(await configOrFn(params));
|
|
18
19
|
return configs;
|
|
19
20
|
};
|
|
21
|
+
const getAliases = (chain) => {
|
|
22
|
+
const aliases = {};
|
|
23
|
+
for (const item of [chain].flat()) {
|
|
24
|
+
if (typeof item === 'function')
|
|
25
|
+
continue;
|
|
26
|
+
for (const key in item) {
|
|
27
|
+
const targets = [];
|
|
28
|
+
for (const target of [item[key]].flat())
|
|
29
|
+
if (typeof target === 'string')
|
|
30
|
+
targets.push(target);
|
|
31
|
+
if (targets.length > 0)
|
|
32
|
+
aliases[key] = targets;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return aliases;
|
|
36
|
+
};
|
|
20
37
|
const resolveConfig = async (configOrFn, options) => {
|
|
21
38
|
const entries = new Set();
|
|
22
39
|
const inputs = [];
|
|
@@ -48,6 +65,17 @@ const resolveConfig = async (configOrFn, options) => {
|
|
|
48
65
|
};
|
|
49
66
|
const checkConfig = async (localConfig, config) => {
|
|
50
67
|
checkSource(localConfig.source);
|
|
68
|
+
const alias = localConfig.resolve?.alias;
|
|
69
|
+
if (alias) {
|
|
70
|
+
for (const input of await resolveRspackConfig({ resolve: { alias: getAliases(alias) } }, options)) {
|
|
71
|
+
inputs.push(input);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const swc = localConfig.tools?.swc;
|
|
75
|
+
if (swc && typeof swc === 'object') {
|
|
76
|
+
for (const specifier of getSwcPluginSpecifiers(swc))
|
|
77
|
+
inputs.push(toDeferResolve(specifier));
|
|
78
|
+
}
|
|
51
79
|
if (!localConfig.tools?.rspack)
|
|
52
80
|
return;
|
|
53
81
|
const target = localConfig.output?.target ?? config.output?.target ?? 'web';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Configuration } from 'webpack';
|
|
2
|
+
import type { SWCConfig } from '../swc/types.ts';
|
|
2
3
|
type EntryDescription = Record<string, unknown>;
|
|
3
4
|
type Entry = Record<string, string | string[] | (EntryDescription & {
|
|
4
5
|
html?: boolean;
|
|
@@ -12,18 +13,25 @@ type RspackConfigUtils = {
|
|
|
12
13
|
isWebWorker: boolean;
|
|
13
14
|
};
|
|
14
15
|
type RspackConfig = Configuration | ((config: Configuration, utils: RspackConfigUtils) => Configuration | void | Promise<Configuration | void>);
|
|
16
|
+
type AliasObject = Record<string, string | false | (string | false)[]>;
|
|
17
|
+
type Alias = AliasObject | ((aliases: AliasObject) => AliasObject | void);
|
|
18
|
+
export type AliasChain = Alias | Alias[];
|
|
15
19
|
export type RsbuildConfig = {
|
|
16
20
|
plugins?: unknown[];
|
|
17
21
|
mode?: 'development' | 'production' | 'none';
|
|
18
22
|
output?: {
|
|
19
23
|
target?: RspackConfigUtils['target'];
|
|
20
24
|
};
|
|
25
|
+
resolve?: {
|
|
26
|
+
alias?: AliasChain;
|
|
27
|
+
};
|
|
21
28
|
source?: {
|
|
22
29
|
entry?: Entry;
|
|
23
30
|
preEntry?: string | string[];
|
|
24
31
|
};
|
|
25
32
|
tools?: {
|
|
26
33
|
rspack?: RspackConfig | RspackConfig[];
|
|
34
|
+
swc?: SWCConfig | ((config: SWCConfig) => SWCConfig | void);
|
|
27
35
|
};
|
|
28
36
|
environments?: {
|
|
29
37
|
[k: string]: Omit<RsbuildConfig, 'environments'>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { toDependency } from '../../util/input.js';
|
|
2
2
|
import { hasDependency } from '../../util/plugin.js';
|
|
3
|
+
import { toCosmiconfig } from '../../util/plugin-config.js';
|
|
3
4
|
const title = 'SVGR';
|
|
4
5
|
const enablers = ['@svgr/cli', '@svgr/core'];
|
|
5
6
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
|
-
const config = ['.
|
|
7
|
+
const config = ['package.json', ...toCosmiconfig('svgr')];
|
|
7
8
|
const resolveConfig = async (config) => {
|
|
8
9
|
const inputs = [];
|
|
9
10
|
if (config.plugins) {
|
|
@@ -6,9 +6,14 @@ const enablers = ['@swc/core'];
|
|
|
6
6
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
7
7
|
const config = ['.swcrc'];
|
|
8
8
|
const resolveConfig = async (config) => {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
9
|
+
const dependencies = [];
|
|
10
|
+
for (const item of [config].flat()) {
|
|
11
|
+
for (const [id] of item?.jsc?.experimental?.plugins ?? [])
|
|
12
|
+
dependencies.push(id);
|
|
13
|
+
if (item?.jsc?.externalHelpers)
|
|
14
|
+
dependencies.push('@swc/helpers');
|
|
15
|
+
}
|
|
16
|
+
return compact(dependencies).map(id => toDependency(id));
|
|
12
17
|
};
|
|
13
18
|
const plugin = {
|
|
14
19
|
title,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Plugin, ResolveConfig } from '../../types/config.ts';
|
|
2
|
+
import type { SWCConfig } from '../swc/types.ts';
|
|
2
3
|
import type { WebpackConfig } from './types.ts';
|
|
4
|
+
export declare const getSwcPluginSpecifiers: (options: SWCConfig) => string[];
|
|
3
5
|
export declare const findWebpackDependenciesFromConfig: ResolveConfig<WebpackConfig>;
|
|
4
6
|
declare const plugin: Plugin;
|
|
5
7
|
export default plugin;
|
|
@@ -59,10 +59,8 @@ const resolveRuleSetDependencies = (rule) => {
|
|
|
59
59
|
});
|
|
60
60
|
};
|
|
61
61
|
const isSwcLoader = (loader) => loader === 'builtin:swc-loader' || loader.endsWith('/swc-loader') || loader === 'swc-loader';
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
return [];
|
|
65
|
-
const plugins = use.options.jsc?.experimental?.plugins;
|
|
62
|
+
export const getSwcPluginSpecifiers = (options) => {
|
|
63
|
+
const plugins = options.jsc?.experimental?.plugins;
|
|
66
64
|
if (!Array.isArray(plugins))
|
|
67
65
|
return [];
|
|
68
66
|
return plugins.flatMap(plugin => {
|
|
@@ -73,6 +71,11 @@ const resolveSwcPluginDependencies = (use) => {
|
|
|
73
71
|
return [];
|
|
74
72
|
});
|
|
75
73
|
};
|
|
74
|
+
const resolveSwcPluginDependencies = (use) => {
|
|
75
|
+
if (!hasLoaderOptions(use) || !isSwcLoader(use.loader))
|
|
76
|
+
return [];
|
|
77
|
+
return getSwcPluginSpecifiers(use.options);
|
|
78
|
+
};
|
|
76
79
|
const resolveUseItem = (use) => {
|
|
77
80
|
if (!use)
|
|
78
81
|
return [];
|
|
@@ -5,8 +5,11 @@ export declare class SessionConfigurationChangedError extends Error {
|
|
|
5
5
|
}
|
|
6
6
|
export declare class ConfigurationFiles {
|
|
7
7
|
paths: Set<string>;
|
|
8
|
+
private importers;
|
|
8
9
|
private matchers;
|
|
9
10
|
constructor(options: MainOptions);
|
|
10
11
|
addPatterns(dir: string, patterns: string[]): void;
|
|
12
|
+
addImport(importer: string, imported: string): void;
|
|
13
|
+
getAffected(changes: WatchChange[], cwd: string): Set<string>;
|
|
11
14
|
getChange(changes: WatchChange[], cwd: string): SessionConfigurationChangedError | undefined;
|
|
12
15
|
}
|
|
@@ -8,6 +8,7 @@ export class SessionConfigurationChangedError extends Error {
|
|
|
8
8
|
}
|
|
9
9
|
export class ConfigurationFiles {
|
|
10
10
|
paths = new Set();
|
|
11
|
+
importers = new Map();
|
|
11
12
|
matchers = [];
|
|
12
13
|
constructor(options) {
|
|
13
14
|
const manifests = [];
|
|
@@ -32,6 +33,24 @@ export class ConfigurationFiles {
|
|
|
32
33
|
if (included.length > 0)
|
|
33
34
|
this.matchers.push({ dir, isMatch: picomatch(included, { dot: true, ignore: excluded }) });
|
|
34
35
|
}
|
|
36
|
+
addImport(importer, imported) {
|
|
37
|
+
this.paths.add(imported);
|
|
38
|
+
const importers = this.importers.get(imported);
|
|
39
|
+
if (importers)
|
|
40
|
+
importers.add(importer);
|
|
41
|
+
else
|
|
42
|
+
this.importers.set(imported, new Set([importer]));
|
|
43
|
+
}
|
|
44
|
+
getAffected(changes, cwd) {
|
|
45
|
+
const affected = new Set();
|
|
46
|
+
for (const change of changes)
|
|
47
|
+
affected.add(toAbsolute(toPosix(change.filePath), cwd));
|
|
48
|
+
for (const filePath of affected) {
|
|
49
|
+
for (const importer of this.importers.get(filePath) ?? [])
|
|
50
|
+
affected.add(importer);
|
|
51
|
+
}
|
|
52
|
+
return affected;
|
|
53
|
+
}
|
|
35
54
|
getChange(changes, cwd) {
|
|
36
55
|
for (const change of changes) {
|
|
37
56
|
const filePath = toAbsolute(toPosix(change.filePath), cwd);
|
package/dist/session/session.js
CHANGED
|
@@ -49,9 +49,10 @@ export const createSession = async (options) => {
|
|
|
49
49
|
clearModuleResolutionCaches();
|
|
50
50
|
clearGlobCache();
|
|
51
51
|
clearGitignoreCache();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
const { configurationFiles } = current.session;
|
|
53
|
+
if (configurationFiles)
|
|
54
|
+
unload(configurationFiles.getAffected(changes, current.options.cwd));
|
|
55
|
+
const nextOptions = await createOptions(current.options.createdFrom, true);
|
|
55
56
|
current = await initialize({ ...nextOptions, isCache: false });
|
|
56
57
|
Object.assign(results, current.results);
|
|
57
58
|
return { duration: performance.now() - startTime, mem: process.memoryUsage().heapUsed };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { ArrayExpression, Expression, ImportExpression, VariableDeclarator } from 'oxc-parser';
|
|
1
|
+
import type { ArrayExpression, CallExpression, Expression, ImportExpression, VariableDeclarator } from 'oxc-parser';
|
|
2
2
|
import type { WalkState } from './walk.ts';
|
|
3
3
|
export declare function getPromiseAllElements(expression: Expression): ArrayExpression['elements'] | undefined;
|
|
4
4
|
export declare function handleVariableDeclarator(node: VariableDeclarator, s: WalkState): void;
|
|
5
|
+
export declare function handleImportThen(node: CallExpression, s: WalkState): void;
|
|
5
6
|
export declare function handleImportExpression(node: ImportExpression, s: WalkState): void;
|
|
@@ -25,46 +25,8 @@ export function handleVariableDeclarator(node, s) {
|
|
|
25
25
|
importExpr = init;
|
|
26
26
|
}
|
|
27
27
|
if (importExpr && isStringLiteral(importExpr.source)) {
|
|
28
|
-
s.handledImportExpressions.add(importExpr.start);
|
|
29
|
-
const specifier = getStringValue(importExpr.source);
|
|
30
28
|
const caughtFlag = init.type === 'AwaitExpression' && s.caughtTryBlockEnds.length > 0 ? IMPORT_FLAGS.CAUGHT : IMPORT_FLAGS.NONE;
|
|
31
|
-
|
|
32
|
-
for (const prop of node.id.properties) {
|
|
33
|
-
if (prop.type === 'Property') {
|
|
34
|
-
const importedName = prop.key?.type === 'Identifier'
|
|
35
|
-
? prop.key.name
|
|
36
|
-
: prop.key?.type === 'Literal' && typeof prop.key.value === 'string'
|
|
37
|
-
? prop.key.value
|
|
38
|
-
: undefined;
|
|
39
|
-
const localName = prop.value?.type === 'Identifier' ? prop.value.name : importedName;
|
|
40
|
-
const alias = localName !== importedName ? localName : undefined;
|
|
41
|
-
s.addImport(specifier, importedName, alias, undefined, prop.key?.start ?? prop.start, IMPORT_FLAGS.DYNAMIC | caughtFlag);
|
|
42
|
-
}
|
|
43
|
-
else if (prop.type === 'RestElement' && prop.argument?.type === 'Identifier') {
|
|
44
|
-
s.addImport(specifier, IMPORT_STAR, prop.argument.name, undefined, prop.start, IMPORT_FLAGS.DYNAMIC | caughtFlag);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else if (node.id.type === 'Identifier') {
|
|
49
|
-
if (init.type === 'AwaitExpression') {
|
|
50
|
-
s.addImport(specifier, 'default', node.id.name, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | caughtFlag);
|
|
51
|
-
const resolved = s.resolveModule(specifier, s.filePath);
|
|
52
|
-
if (resolved && !resolved.isExternalLibraryImport && !isInNodeModules(resolved.resolvedFileName)) {
|
|
53
|
-
s.localImportMap.set(node.id.name, {
|
|
54
|
-
importedName: IMPORT_STAR,
|
|
55
|
-
filePath: resolved.resolvedFileName,
|
|
56
|
-
isNamespace: true,
|
|
57
|
-
isDynamicImport: true,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.OPAQUE | caughtFlag);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.OPAQUE | caughtFlag);
|
|
67
|
-
}
|
|
29
|
+
handleDynamicImportBinding(node.id, importExpr, init.type === 'AwaitExpression', caughtFlag, s);
|
|
68
30
|
return;
|
|
69
31
|
}
|
|
70
32
|
if (init.type === 'CallExpression' &&
|
|
@@ -268,6 +230,62 @@ export function handleVariableDeclarator(node, s) {
|
|
|
268
230
|
}
|
|
269
231
|
}
|
|
270
232
|
}
|
|
233
|
+
function handleDynamicImportBinding(id, importExpr, isAwaited, caughtFlag, s) {
|
|
234
|
+
s.handledImportExpressions.add(importExpr.start);
|
|
235
|
+
const specifier = getStringValue(importExpr.source);
|
|
236
|
+
if (id.type === 'ObjectPattern') {
|
|
237
|
+
for (const prop of id.properties) {
|
|
238
|
+
if (prop.type === 'Property') {
|
|
239
|
+
const importedName = prop.key?.type === 'Identifier'
|
|
240
|
+
? prop.key.name
|
|
241
|
+
: prop.key?.type === 'Literal' && typeof prop.key.value === 'string'
|
|
242
|
+
? prop.key.value
|
|
243
|
+
: undefined;
|
|
244
|
+
const localName = prop.value?.type === 'Identifier' ? prop.value.name : importedName;
|
|
245
|
+
const alias = localName !== importedName ? localName : undefined;
|
|
246
|
+
s.addImport(specifier, importedName, alias, undefined, prop.key?.start ?? prop.start, IMPORT_FLAGS.DYNAMIC | caughtFlag);
|
|
247
|
+
}
|
|
248
|
+
else if (prop.type === 'RestElement' && prop.argument?.type === 'Identifier') {
|
|
249
|
+
s.addImport(specifier, IMPORT_STAR, prop.argument.name, undefined, prop.start, IMPORT_FLAGS.DYNAMIC | caughtFlag);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else if (id.type === 'Identifier') {
|
|
254
|
+
if (isAwaited) {
|
|
255
|
+
s.addImport(specifier, 'default', id.name, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | caughtFlag);
|
|
256
|
+
const resolved = s.resolveModule(specifier, s.filePath);
|
|
257
|
+
if (resolved && !resolved.isExternalLibraryImport && !isInNodeModules(resolved.resolvedFileName)) {
|
|
258
|
+
s.localImportMap.set(id.name, {
|
|
259
|
+
importedName: IMPORT_STAR,
|
|
260
|
+
filePath: resolved.resolvedFileName,
|
|
261
|
+
isNamespace: true,
|
|
262
|
+
isDynamicImport: true,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.OPAQUE | caughtFlag);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
s.addImport(specifier, undefined, undefined, undefined, importExpr.source.start, IMPORT_FLAGS.DYNAMIC | IMPORT_FLAGS.OPAQUE | caughtFlag);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
export function handleImportThen(node, s) {
|
|
275
|
+
const callee = node.callee;
|
|
276
|
+
if (callee.type !== 'MemberExpression' || callee.computed || callee.property.name !== 'then')
|
|
277
|
+
return;
|
|
278
|
+
if (callee.object.type !== 'ImportExpression' || !isStringLiteral(callee.object.source))
|
|
279
|
+
return;
|
|
280
|
+
const fn = node.arguments[0];
|
|
281
|
+
if (fn?.type !== 'ArrowFunctionExpression' && fn?.type !== 'FunctionExpression')
|
|
282
|
+
return;
|
|
283
|
+
const param = fn.params[0];
|
|
284
|
+
if (param?.type !== 'Identifier' && param?.type !== 'ObjectPattern')
|
|
285
|
+
return;
|
|
286
|
+
const caughtFlag = s.caughtImportExpressions.has(callee.object.start) ? IMPORT_FLAGS.CAUGHT : IMPORT_FLAGS.NONE;
|
|
287
|
+
handleDynamicImportBinding(param, callee.object, true, caughtFlag, s);
|
|
288
|
+
}
|
|
271
289
|
export function handleImportExpression(node, s) {
|
|
272
290
|
if (s.handledImportExpressions.has(node.start))
|
|
273
291
|
return;
|
|
@@ -7,7 +7,7 @@ import { collectAugmentationRefs, getLineAndCol, getStringValue, isStringLiteral
|
|
|
7
7
|
import { EMPTY_TAGS } from './jsdoc.js';
|
|
8
8
|
import { handleCallExpression, handleNewExpression, trackCustomElementRegistry } from './calls.js';
|
|
9
9
|
import { handleExportAssignment, handleExportDefault, handleExportNamed, handleExpressionStatement, } from './exports.js';
|
|
10
|
-
import { getPromiseAllElements, handleImportExpression, handleVariableDeclarator } from './imports.js';
|
|
10
|
+
import { getPromiseAllElements, handleImportExpression, handleImportThen, handleVariableDeclarator, } from './imports.js';
|
|
11
11
|
import { handleJSXMemberExpression, handleMemberExpression } from './members.js';
|
|
12
12
|
let state;
|
|
13
13
|
const _getFix = (start, end, flags) => state.options.isFixExports ? [start, end, flags ?? FIX_FLAGS.NONE] : undefined;
|
|
@@ -419,6 +419,7 @@ const coreVisitorObject = {
|
|
|
419
419
|
}
|
|
420
420
|
},
|
|
421
421
|
CallExpression(node) {
|
|
422
|
+
handleImportThen(node, state);
|
|
422
423
|
handleCallExpression(node, state);
|
|
423
424
|
},
|
|
424
425
|
NewExpression(node) {
|
|
@@ -3,7 +3,7 @@ import { type ParsedCLIArgs } from './cli-arguments.ts';
|
|
|
3
3
|
interface CreateOptions extends Partial<Options> {
|
|
4
4
|
args?: ParsedCLIArgs;
|
|
5
5
|
}
|
|
6
|
-
export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
6
|
+
export declare const createOptions: (options: CreateOptions, isReload?: boolean) => Promise<{
|
|
7
7
|
createdFrom: CreateOptions;
|
|
8
8
|
cacheLocation: string;
|
|
9
9
|
catalog: import("../CatalogCounselor.ts").CatalogContainer[];
|
|
@@ -8,12 +8,12 @@ import { findFile, loadJSON } from './fs.js';
|
|
|
8
8
|
import { getIncludedIssueTypes, shorthandCycles, shorthandDeps, shorthandExports, shorthandFiles, } from './get-included-issue-types.js';
|
|
9
9
|
import { defaultRules } from './issue-initializers.js';
|
|
10
10
|
import { loadResolvedConfigFile } from './load-config.js';
|
|
11
|
-
import { _load } from './loader.js';
|
|
11
|
+
import { _load, unload } from './loader.js';
|
|
12
12
|
import { logWarning } from './log.js';
|
|
13
13
|
import { getKeysByValue } from './object.js';
|
|
14
14
|
import { isAbsolute, isInternal, join, resolveCwd, toAbsolute } from './path.js';
|
|
15
15
|
import { splitTags } from './tag.js';
|
|
16
|
-
export const createOptions = async (options) => {
|
|
16
|
+
export const createOptions = async (options, isReload = false) => {
|
|
17
17
|
const { args = {} } = options;
|
|
18
18
|
const cwd = resolveCwd(options.cwd ?? args.directory ?? '.');
|
|
19
19
|
const manifestPath = findFile(cwd, 'package.json');
|
|
@@ -32,6 +32,8 @@ export const createOptions = async (options) => {
|
|
|
32
32
|
if (args.config && !configFilePath && !manifest.knip) {
|
|
33
33
|
throw new ConfigurationError(`Unable to find ${args.config} or package.json#knip`);
|
|
34
34
|
}
|
|
35
|
+
if (options.isSession && !isReload && configFilePath)
|
|
36
|
+
unload([configFilePath]);
|
|
35
37
|
const loadedConfig = Object.assign({}, manifest.knip, configFilePath ? await loadResolvedConfigFile(configFilePath, args) : {});
|
|
36
38
|
const validIssueTypes = new Set(ISSUE_TYPES);
|
|
37
39
|
for (const key of ['rules', 'include', 'exclude']) {
|
package/dist/util/loader.js
CHANGED
|
@@ -6,26 +6,15 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
6
6
|
}
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
|
-
import { readFileSync } from 'node:fs';
|
|
10
9
|
import { createRequire } from 'node:module';
|
|
11
10
|
import { pathToFileURL } from 'node:url';
|
|
12
11
|
import { LoaderError } from './errors.js';
|
|
13
|
-
import {
|
|
12
|
+
import { loadFile, loadJSON, loadJSONC, loadTOML, loadYAML, parseJSONC, parseYAML } from './fs.js';
|
|
14
13
|
import { jiti } from './jiti.js';
|
|
15
14
|
import { timerify } from './Performance.js';
|
|
16
|
-
import {
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const ext = extname(filePath);
|
|
20
|
-
if (ext !== '.js')
|
|
21
|
-
return ext === '.mjs';
|
|
22
|
-
for (let dir = dirname(filePath); dir !== dirname(dir); dir = dirname(dir)) {
|
|
23
|
-
const manifestPath = findFile(dir, 'package.json');
|
|
24
|
-
if (manifestPath)
|
|
25
|
-
return JSON.parse(readFileSync(manifestPath, 'utf8')).type === 'module';
|
|
26
|
-
}
|
|
27
|
-
return false;
|
|
28
|
-
};
|
|
15
|
+
import { extname, isInternal, toNative } from './path.js';
|
|
16
|
+
const versions = new Map();
|
|
17
|
+
const isReloadable = (ext) => ext === '.js' || ext === '.mjs' || ext === '.cjs';
|
|
29
18
|
const reload = async (filePath, version) => {
|
|
30
19
|
let imported;
|
|
31
20
|
try {
|
|
@@ -67,8 +56,9 @@ const load = async (filePath) => {
|
|
|
67
56
|
if (ext === '.toml') {
|
|
68
57
|
return await loadTOML(filePath);
|
|
69
58
|
}
|
|
70
|
-
const version =
|
|
71
|
-
|
|
59
|
+
const version = versions.get(filePath) ?? 0;
|
|
60
|
+
versions.set(filePath, version);
|
|
61
|
+
if (version && isReloadable(ext))
|
|
72
62
|
return await reload(filePath, version);
|
|
73
63
|
return await jiti.import(filePath, { default: true });
|
|
74
64
|
}
|
|
@@ -82,6 +72,8 @@ export const unload = (filePaths) => {
|
|
|
82
72
|
for (const filePath of filePaths) {
|
|
83
73
|
delete cache[filePath];
|
|
84
74
|
delete cache[toNative(filePath)];
|
|
85
|
-
|
|
75
|
+
const version = versions.get(filePath);
|
|
76
|
+
if (version !== undefined)
|
|
77
|
+
versions.set(filePath, version + 1);
|
|
86
78
|
}
|
|
87
79
|
};
|
package/dist/util/modules.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { DT_SCOPE, PROTOCOL_VIRTUAL } from '../constants.js';
|
|
2
|
+
import { DT_SCOPE, PROTOCOL_CLOUDFLARE, PROTOCOL_VIRTUAL } from '../constants.js';
|
|
3
3
|
import { isAbsolute, isInNodeModules, join, toPosix } from './path.js';
|
|
4
4
|
export const getPackageNameFromModuleSpecifier = (specifier) => {
|
|
5
5
|
if (!isStartsLikePackageName(specifier) && !isTildePackageName(specifier))
|
|
@@ -89,6 +89,7 @@ const CHAR_HASH = 35;
|
|
|
89
89
|
const CHAR_QUESTION = 63;
|
|
90
90
|
export const sanitizeSpecifier = (specifier) => {
|
|
91
91
|
if (specifier.startsWith('node:') ||
|
|
92
|
+
specifier.startsWith(PROTOCOL_CLOUDFLARE) ||
|
|
92
93
|
isAbsolute(specifier) ||
|
|
93
94
|
specifier.charCodeAt(0) === CHAR_COLON ||
|
|
94
95
|
specifier.startsWith(PROTOCOL_VIRTUAL)) {
|
package/dist/util/watch.js
CHANGED
|
@@ -16,7 +16,7 @@ export const getSessionHandler = async (options, { analyzedFiles, analyzeSourceF
|
|
|
16
16
|
const deleted = new Set();
|
|
17
17
|
const modified = new Set();
|
|
18
18
|
if (configurationFiles)
|
|
19
|
-
principal.collectConfigurationImports(configurationFiles
|
|
19
|
+
principal.collectConfigurationImports(configurationFiles);
|
|
20
20
|
const processFileChanges = async (changes) => {
|
|
21
21
|
const startTime = performance.now();
|
|
22
22
|
let hasRelevantChanges = false;
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "6.44.
|
|
1
|
+
export declare const version = "6.44.1";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '6.44.
|
|
1
|
+
export const version = '6.44.1';
|