knip 6.40.0 → 6.42.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.
- package/README.md +1 -1
- package/dist/ConfigurationChief.d.ts +30 -0
- package/dist/DependencyDeputy.d.ts +1 -0
- package/dist/DependencyDeputy.js +28 -2
- package/dist/IssueCollector.js +13 -15
- package/dist/IssueFixer.js +1 -1
- package/dist/WorkspaceWorker.js +15 -8
- package/dist/binaries/bash-parser.js +16 -33
- package/dist/binaries/command.d.ts +1 -1
- package/dist/binaries/command.js +14 -8
- package/dist/binaries/resolvers/bun.js +1 -0
- package/dist/graph/build.js +18 -9
- package/dist/graph-explorer/operations/is-referenced.js +8 -2
- package/dist/manifest/index.d.ts +1 -0
- package/dist/manifest/index.js +7 -3
- package/dist/plugins/_component-style-urls/component-style-urls-visitor.d.ts +2 -0
- package/dist/plugins/_component-style-urls/component-style-urls-visitor.js +40 -0
- package/dist/plugins/angular/index.js +7 -1
- package/dist/plugins/biome/index.js +2 -2
- package/dist/plugins/commitlint/index.js +2 -2
- package/dist/plugins/eslint/helpers.js +1 -1
- package/dist/plugins/expo/helpers.js +1 -1
- package/dist/plugins/expo/index.js +4 -24
- package/dist/plugins/expo-router/index.d.ts +3 -0
- package/dist/plugins/expo-router/index.js +32 -0
- package/dist/plugins/filesystem-routing/index.d.ts +3 -0
- package/dist/plugins/filesystem-routing/index.js +57 -0
- package/dist/plugins/flue/index.d.ts +3 -0
- package/dist/plugins/flue/index.js +42 -0
- package/dist/plugins/github-actions/index.js +1 -1
- package/dist/plugins/index.d.ts +5 -0
- package/dist/plugins/index.js +10 -0
- package/dist/plugins/jest/index.js +5 -0
- package/dist/plugins/jest/visitors/mock.d.ts +2 -0
- package/dist/plugins/jest/visitors/mock.js +91 -0
- package/dist/plugins/mise/scripts.js +56 -76
- package/dist/plugins/moonrepo/index.js +2 -1
- package/dist/plugins/next/index.js +33 -1
- package/dist/plugins/nx/index.js +50 -8
- package/dist/plugins/nx/types.d.ts +8 -0
- package/dist/plugins/oxlint/index.js +1 -1
- package/dist/plugins/react-native/index.js +1 -1
- package/dist/plugins/react-router/index.d.ts +3 -0
- package/dist/plugins/react-router/index.js +3 -0
- package/dist/plugins/rsbuild/index.js +20 -6
- package/dist/plugins/rsbuild/types.d.ts +6 -0
- package/dist/plugins/rstest/index.js +1 -1
- package/dist/plugins/rstest/types.d.ts +1 -5
- package/dist/plugins/solidjs-vite-plugin/index.d.ts +6 -0
- package/dist/plugins/solidjs-vite-plugin/index.js +17 -0
- package/dist/plugins/solidjs-vite-plugin/resolveFromAST.d.ts +3 -0
- package/dist/plugins/solidjs-vite-plugin/resolveFromAST.js +76 -0
- package/dist/plugins/sst/resolveFromAST.js +1 -1
- package/dist/plugins/stencil/index.js +2 -39
- package/dist/plugins/storybook/index.js +2 -4
- package/dist/plugins/sveltejs-package/helpers.js +7 -44
- package/dist/plugins/taskfile/index.js +3 -6
- package/dist/plugins/tsrs/index.d.ts +3 -0
- package/dist/plugins/tsrs/index.js +15 -0
- package/dist/plugins/typescript/index.d.ts +12 -1
- package/dist/plugins/typescript/index.js +5 -7
- package/dist/plugins/vite/helpers.d.ts +1 -0
- package/dist/plugins/vite/helpers.js +15 -1
- package/dist/plugins/vitest/index.js +2 -2
- package/dist/run.js +2 -0
- package/dist/schema/configuration.d.ts +75 -0
- package/dist/schema/plugins.d.ts +25 -0
- package/dist/schema/plugins.js +5 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +5 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/workspace.d.ts +1 -0
- package/dist/typescript/visitors/imports.js +11 -0
- package/dist/typescript/visitors/jsdoc.js +27 -22
- package/dist/util/create-options.d.ts +50 -0
- package/dist/util/create-options.js +2 -3
- package/dist/util/glob-cache.d.ts +2 -2
- package/dist/util/glob-core.js +70 -47
- package/dist/util/glob.js +15 -10
- package/dist/util/load-tsconfig.d.ts +1 -1
- package/dist/util/load-tsconfig.js +21 -11
- package/dist/util/module-graph.js +9 -4
- package/dist/util/path.d.ts +1 -0
- package/dist/util/path.js +1 -0
- package/dist/util/scripts.d.ts +4 -2
- package/dist/util/scripts.js +33 -67
- package/dist/util/to-source-path.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -11
- package/schema.json +20 -0
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ following projects:
|
|
|
48
48
|
|
|
49
49
|
[1]: https://www.npmx.dev/package/knip
|
|
50
50
|
[2]: https://img.shields.io/npm/v/knip?color=f56e0f
|
|
51
|
-
[3]: https://img.shields.io/npm/
|
|
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
53
|
[5]:
|
|
54
54
|
https://img.shields.io/github/stars/webpro-nl/knip?style=flat&color=f56e0f
|
|
@@ -237,6 +237,11 @@ export declare class ConfigurationChief {
|
|
|
237
237
|
entry?: string | string[] | undefined;
|
|
238
238
|
project?: string | string[] | undefined;
|
|
239
239
|
} | undefined;
|
|
240
|
+
'expo-router'?: string | boolean | string[] | {
|
|
241
|
+
config?: string | string[] | undefined;
|
|
242
|
+
entry?: string | string[] | undefined;
|
|
243
|
+
project?: string | string[] | undefined;
|
|
244
|
+
} | undefined;
|
|
240
245
|
'expressive-code'?: string | boolean | string[] | {
|
|
241
246
|
config?: string | string[] | undefined;
|
|
242
247
|
entry?: string | string[] | undefined;
|
|
@@ -247,6 +252,16 @@ export declare class ConfigurationChief {
|
|
|
247
252
|
entry?: string | string[] | undefined;
|
|
248
253
|
project?: string | string[] | undefined;
|
|
249
254
|
} | undefined;
|
|
255
|
+
'filesystem-routing'?: string | boolean | string[] | {
|
|
256
|
+
config?: string | string[] | undefined;
|
|
257
|
+
entry?: string | string[] | undefined;
|
|
258
|
+
project?: string | string[] | undefined;
|
|
259
|
+
} | undefined;
|
|
260
|
+
flue?: string | boolean | string[] | {
|
|
261
|
+
config?: string | string[] | undefined;
|
|
262
|
+
entry?: string | string[] | undefined;
|
|
263
|
+
project?: string | string[] | undefined;
|
|
264
|
+
} | undefined;
|
|
250
265
|
fumadocs?: string | boolean | string[] | {
|
|
251
266
|
config?: string | string[] | undefined;
|
|
252
267
|
entry?: string | string[] | undefined;
|
|
@@ -712,6 +727,11 @@ export declare class ConfigurationChief {
|
|
|
712
727
|
entry?: string | string[] | undefined;
|
|
713
728
|
project?: string | string[] | undefined;
|
|
714
729
|
} | undefined;
|
|
730
|
+
'solidjs-vite-plugin'?: string | boolean | string[] | {
|
|
731
|
+
config?: string | string[] | undefined;
|
|
732
|
+
entry?: string | string[] | undefined;
|
|
733
|
+
project?: string | string[] | undefined;
|
|
734
|
+
} | undefined;
|
|
715
735
|
sst?: string | boolean | string[] | {
|
|
716
736
|
config?: string | string[] | undefined;
|
|
717
737
|
entry?: string | string[] | undefined;
|
|
@@ -827,6 +847,11 @@ export declare class ConfigurationChief {
|
|
|
827
847
|
entry?: string | string[] | undefined;
|
|
828
848
|
project?: string | string[] | undefined;
|
|
829
849
|
} | undefined;
|
|
850
|
+
tsrs?: string | boolean | string[] | {
|
|
851
|
+
config?: string | string[] | undefined;
|
|
852
|
+
entry?: string | string[] | undefined;
|
|
853
|
+
project?: string | string[] | undefined;
|
|
854
|
+
} | undefined;
|
|
830
855
|
tsup?: string | boolean | string[] | {
|
|
831
856
|
config?: string | string[] | undefined;
|
|
832
857
|
entry?: string | string[] | undefined;
|
|
@@ -1076,8 +1101,11 @@ export declare class ConfigurationChief {
|
|
|
1076
1101
|
eve?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1077
1102
|
execa?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1078
1103
|
expo?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1104
|
+
"expo-router"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1079
1105
|
"expressive-code"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1080
1106
|
fast?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1107
|
+
"filesystem-routing"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1108
|
+
flue?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1081
1109
|
fumadocs?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1082
1110
|
gatsby?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1083
1111
|
"github-action"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
@@ -1171,6 +1199,7 @@ export declare class ConfigurationChief {
|
|
|
1171
1199
|
"serverless-framework"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1172
1200
|
"simple-git-hooks"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1173
1201
|
"size-limit"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1202
|
+
"solidjs-vite-plugin"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1174
1203
|
sst?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1175
1204
|
starlight?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1176
1205
|
stencil?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
@@ -1194,6 +1223,7 @@ export declare class ConfigurationChief {
|
|
|
1194
1223
|
"ts-node"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1195
1224
|
tsd?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1196
1225
|
tsdown?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1226
|
+
tsrs?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1197
1227
|
tsup?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1198
1228
|
tsx?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1199
1229
|
turbo?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
@@ -40,6 +40,7 @@ export declare class DependencyDeputy {
|
|
|
40
40
|
peerDependencies: DependencySet;
|
|
41
41
|
optionalPeerDependencies: DependencySet;
|
|
42
42
|
requiredPeerDependencies: DependencyArray;
|
|
43
|
+
uninstalledOptionalDependencies: DependencySet;
|
|
43
44
|
allDependencies: DependencySet;
|
|
44
45
|
engines: Record<string, string>;
|
|
45
46
|
isPrivate: boolean;
|
package/dist/DependencyDeputy.js
CHANGED
|
@@ -38,15 +38,25 @@ export class DependencyDeputy {
|
|
|
38
38
|
const requiredPeerDependencies = peerDependencies.filter(dep => !optionalPeerDependencies.has(dep));
|
|
39
39
|
const devDependencies = Object.keys(manifest.devDependencies ?? {});
|
|
40
40
|
const allDependencies = [...dependencies, ...devDependencies, ...peerDependencies, ...optionalDependencies];
|
|
41
|
-
const
|
|
41
|
+
const uninstalledOptionalDependencies = new Set();
|
|
42
|
+
const packageNames = [
|
|
43
|
+
...dependencies,
|
|
44
|
+
...peerDependencies,
|
|
45
|
+
...optionalDependencies,
|
|
46
|
+
...(this.isProduction ? [] : devDependencies),
|
|
47
|
+
];
|
|
42
48
|
if (this.isReportDependencies) {
|
|
43
|
-
const { hostDependencies, installedBinaries, hasTypesIncluded } = getDependencyMetaData({
|
|
49
|
+
const { hostDependencies, installedBinaries, hasTypesIncluded, uninstalledDependencies } = getDependencyMetaData({
|
|
44
50
|
packageNames,
|
|
45
51
|
dir,
|
|
46
52
|
});
|
|
47
53
|
this.setHostDependencies(name, hostDependencies);
|
|
48
54
|
this.installedBinaries.set(name, installedBinaries);
|
|
49
55
|
this.hasTypesIncluded.set(name, hasTypesIncluded);
|
|
56
|
+
for (const dependency of optionalDependencies) {
|
|
57
|
+
if (uninstalledDependencies.has(dependency))
|
|
58
|
+
uninstalledOptionalDependencies.add(dependency);
|
|
59
|
+
}
|
|
50
60
|
}
|
|
51
61
|
const ignoreDependencies = id.flatMap(id => filterIsProduction(id, this.isProduction)).map(toRegexOrString);
|
|
52
62
|
const ignoreBinaries = ib.flatMap(ib => filterIsProduction(ib, this.isProduction)).map(toRegexOrString);
|
|
@@ -66,6 +76,7 @@ export class DependencyDeputy {
|
|
|
66
76
|
peerDependencies: new Set(peerDependencies),
|
|
67
77
|
optionalPeerDependencies,
|
|
68
78
|
requiredPeerDependencies,
|
|
79
|
+
uninstalledOptionalDependencies,
|
|
69
80
|
allDependencies: new Set(allDependencies),
|
|
70
81
|
engines: manifest.engines ?? {},
|
|
71
82
|
isPrivate: Boolean(manifest.private),
|
|
@@ -171,6 +182,21 @@ export class DependencyDeputy {
|
|
|
171
182
|
}
|
|
172
183
|
}
|
|
173
184
|
}
|
|
185
|
+
const optionalDependencies = new Set();
|
|
186
|
+
for (const name of workspaceNames) {
|
|
187
|
+
const manifest = this._manifests.get(name);
|
|
188
|
+
if (!manifest)
|
|
189
|
+
continue;
|
|
190
|
+
for (const dependency of manifest.uninstalledOptionalDependencies) {
|
|
191
|
+
const defaultBinaryName = dependency.replace(/^@[^/]+\//, '');
|
|
192
|
+
if (defaultBinaryName === binaryName) {
|
|
193
|
+
optionalDependencies.add(dependency);
|
|
194
|
+
this.addReferencedDependency(name, dependency);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (optionalDependencies.size)
|
|
199
|
+
return optionalDependencies;
|
|
174
200
|
return;
|
|
175
201
|
}
|
|
176
202
|
isInDependencies(workspaceName, packageName, isDevOnly) {
|
package/dist/IssueCollector.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import picomatch from 'picomatch';
|
|
2
2
|
import { ROOT_WORKSPACE_NAME } from './constants.js';
|
|
3
3
|
import { partition } from './util/array.js';
|
|
4
|
-
import { prependDirToPattern } from './util/glob.js';
|
|
5
4
|
import { initCounters, initIssues } from './util/issue-initializers.js';
|
|
6
5
|
import { relative } from './util/path.js';
|
|
7
6
|
const createMatcher = (patterns) => {
|
|
@@ -82,23 +81,22 @@ export class IssueCollector {
|
|
|
82
81
|
return;
|
|
83
82
|
const issueTypePatterns = new Map();
|
|
84
83
|
for (const [pattern, issueTypes] of Object.entries(ignoreIssues)) {
|
|
85
|
-
const id = prependDirToPattern(this.cwd, pattern);
|
|
86
84
|
for (const issueType of issueTypes) {
|
|
87
85
|
if (!issueTypePatterns.has(issueType)) {
|
|
88
86
|
issueTypePatterns.set(issueType, []);
|
|
89
87
|
}
|
|
90
|
-
issueTypePatterns.get(issueType)?.push(
|
|
88
|
+
issueTypePatterns.get(issueType)?.push(pattern);
|
|
91
89
|
}
|
|
92
90
|
}
|
|
93
91
|
for (const [issueType, patterns] of issueTypePatterns) {
|
|
94
92
|
this.issueMatchers.set(issueType, picomatch(patterns, { dot: true }));
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
|
-
shouldIgnoreIssue(
|
|
95
|
+
shouldIgnoreIssue(relativePath, issueType) {
|
|
98
96
|
const matcher = this.issueMatchers.get(issueType);
|
|
99
97
|
if (!matcher)
|
|
100
98
|
return false;
|
|
101
|
-
return matcher(
|
|
99
|
+
return matcher(relativePath);
|
|
102
100
|
}
|
|
103
101
|
addFileCounts({ processed, unused }) {
|
|
104
102
|
this.counters.processed += processed;
|
|
@@ -110,17 +108,17 @@ export class IssueCollector {
|
|
|
110
108
|
continue;
|
|
111
109
|
if (this.referencedFiles.has(filePath))
|
|
112
110
|
continue;
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
const symbol = relative(this.cwd, filePath);
|
|
112
|
+
if (this.isMatch(symbol)) {
|
|
113
|
+
this.markUsedPatterns(symbol, this.unusedIgnorePatterns);
|
|
115
114
|
continue;
|
|
116
115
|
}
|
|
117
|
-
if (this.isFileMatch(
|
|
118
|
-
this.markUsedPatterns(
|
|
116
|
+
if (this.isFileMatch(symbol)) {
|
|
117
|
+
this.markUsedPatterns(symbol, this.unusedIgnoreFilesPatterns);
|
|
119
118
|
continue;
|
|
120
119
|
}
|
|
121
|
-
if (this.shouldIgnoreIssue(
|
|
120
|
+
if (this.shouldIgnoreIssue(symbol, 'files'))
|
|
122
121
|
continue;
|
|
123
|
-
const symbol = relative(this.cwd, filePath);
|
|
124
122
|
this.issues.files[symbol] = {
|
|
125
123
|
[symbol]: { type: 'files', filePath, symbol, workspace: '', severity: this.rules.files, fixes: [] },
|
|
126
124
|
};
|
|
@@ -131,15 +129,15 @@ export class IssueCollector {
|
|
|
131
129
|
addIssue(issue) {
|
|
132
130
|
if (!this.workspaceFilter(issue.filePath))
|
|
133
131
|
return;
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
const key = relative(this.cwd, issue.filePath);
|
|
133
|
+
if (this.isMatch(key)) {
|
|
134
|
+
this.markUsedPatterns(key, this.unusedIgnorePatterns);
|
|
136
135
|
return;
|
|
137
136
|
}
|
|
138
|
-
if (this.shouldIgnoreIssue(
|
|
137
|
+
if (this.shouldIgnoreIssue(key, issue.type))
|
|
139
138
|
return;
|
|
140
139
|
if (this.rules[issue.type] === 'off')
|
|
141
140
|
return;
|
|
142
|
-
const key = relative(this.cwd, issue.filePath);
|
|
143
141
|
issue.severity = this.rules[issue.type];
|
|
144
142
|
const issues = this.issues[issue.type];
|
|
145
143
|
issues[key] = issues[key] ?? {};
|
package/dist/IssueFixer.js
CHANGED
|
@@ -21,7 +21,7 @@ export const fix = async (issues, counters, options) => {
|
|
|
21
21
|
}
|
|
22
22
|
if (options.isFormat) {
|
|
23
23
|
const report = await formatly(Array.from(touchedFiles));
|
|
24
|
-
if (report.ran && report.result
|
|
24
|
+
if (report.ran && report.result.runner !== 'dry-run' && report.result.code === 0) {
|
|
25
25
|
debugLogArray('*', `Formatted files using ${report.formatter.name} (${report.formatter.runner})`, touchedFiles);
|
|
26
26
|
}
|
|
27
27
|
else {
|
package/dist/WorkspaceWorker.js
CHANGED
|
@@ -14,7 +14,7 @@ import { _glob, hasNoProductionSuffix, hasProductionSuffix, negate } from './uti
|
|
|
14
14
|
import { isCatalog, isConfig, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
|
|
15
15
|
import { filterTransitiveDependencies } from './util/filter-transitive-dependencies.js';
|
|
16
16
|
import { timerify } from './util/Performance.js';
|
|
17
|
-
import { basename, dirname, join, toRelative } from './util/path.js';
|
|
17
|
+
import { basename, dirname, join, relative, toRelative } from './util/path.js';
|
|
18
18
|
import { extractPatternExtensions } from './util/pattern-extensions.js';
|
|
19
19
|
import { formatCauseMessage } from './util/errors.js';
|
|
20
20
|
import { logError } from './util/log.js';
|
|
@@ -294,6 +294,7 @@ export class WorkspaceWorker {
|
|
|
294
294
|
}
|
|
295
295
|
const options = {
|
|
296
296
|
...baseScriptOptions,
|
|
297
|
+
pluginName,
|
|
297
298
|
config,
|
|
298
299
|
configFilePath: containingFilePath,
|
|
299
300
|
configFileDir: cwd,
|
|
@@ -469,18 +470,24 @@ export class WorkspaceWorker {
|
|
|
469
470
|
hints.push({ type: `${type}-empty`, identifier, workspaceName });
|
|
470
471
|
return hints;
|
|
471
472
|
}
|
|
473
|
+
const dir = this.dir;
|
|
474
|
+
const relativePaths = [];
|
|
475
|
+
const hasMatch = (isMatch) => {
|
|
476
|
+
for (let i = 0; i < filePaths.length; i++) {
|
|
477
|
+
if (isMatch((relativePaths[i] ??= relative(dir, filePaths[i]))))
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
return false;
|
|
481
|
+
};
|
|
472
482
|
for (const pattern of patterns) {
|
|
473
483
|
if (pattern.startsWith('!'))
|
|
474
484
|
continue;
|
|
475
|
-
const
|
|
476
|
-
if (includedPaths.has(
|
|
485
|
+
const id = pattern.replace(/!$/, '');
|
|
486
|
+
if (includedPaths.has(join(dir, id))) {
|
|
477
487
|
hints.push({ type: `${type}-redundant`, identifier: pattern, workspaceName });
|
|
478
488
|
}
|
|
479
|
-
else {
|
|
480
|
-
|
|
481
|
-
if (!filePaths.some(filePath => matcher(filePath))) {
|
|
482
|
-
hints.push({ type: `${type}-empty`, identifier: pattern, workspaceName });
|
|
483
|
-
}
|
|
489
|
+
else if (!hasMatch(picomatch(id))) {
|
|
490
|
+
hints.push({ type: `${type}-empty`, identifier: pattern, workspaceName });
|
|
484
491
|
}
|
|
485
492
|
}
|
|
486
493
|
if (type === 'project' && compilerExtensions) {
|
|
@@ -1,26 +1,11 @@
|
|
|
1
|
-
import { parse } from 'unbash';
|
|
1
|
+
import { forEachChild, parse } from 'unbash';
|
|
2
2
|
import { debugLogObject } from '../util/debug.js';
|
|
3
3
|
import { extractBinary, isValidBinary } from '../util/modules.js';
|
|
4
4
|
import { relative } from '../util/path.js';
|
|
5
5
|
import { substringBefore, truncate } from '../util/string.js';
|
|
6
|
-
import {
|
|
6
|
+
import { isScriptExpansion } from '../util/scripts.js';
|
|
7
7
|
import { getDependenciesFromCommand } from './command.js';
|
|
8
8
|
import { toScript } from './util.js';
|
|
9
|
-
const collectExpansionScripts = (word, out) => {
|
|
10
|
-
if (!word.parts)
|
|
11
|
-
return;
|
|
12
|
-
for (const part of word.parts) {
|
|
13
|
-
if ((part.type === 'CommandExpansion' || part.type === 'ProcessSubstitution') && part.script) {
|
|
14
|
-
out.push(part.script);
|
|
15
|
-
}
|
|
16
|
-
else if (part.type === 'DoubleQuoted' || part.type === 'LocaleString') {
|
|
17
|
-
for (const child of part.parts) {
|
|
18
|
-
if (child.type === 'CommandExpansion' && child.script)
|
|
19
|
-
out.push(child.script);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
9
|
export const getDependenciesFromScript = (script, options) => {
|
|
25
10
|
if (!script)
|
|
26
11
|
return [];
|
|
@@ -51,23 +36,21 @@ export const getDependenciesFromScript = (script, options) => {
|
|
|
51
36
|
};
|
|
52
37
|
const processScript = (s) => {
|
|
53
38
|
collectFunctionNames(s.commands);
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
39
|
+
const inputs = [];
|
|
40
|
+
const visit = (node) => {
|
|
41
|
+
if (node.type === 'Command')
|
|
42
|
+
inputs.push(...processCommand(node));
|
|
43
|
+
if (isScriptExpansion(node)) {
|
|
44
|
+
if (node.script)
|
|
45
|
+
inputs.push(...processScript(node.script));
|
|
46
|
+
}
|
|
47
|
+
else
|
|
48
|
+
forEachChild(node, visit);
|
|
49
|
+
};
|
|
50
|
+
visit(s);
|
|
51
|
+
return inputs;
|
|
62
52
|
};
|
|
63
|
-
const processCommand = (node
|
|
64
|
-
if (node.name)
|
|
65
|
-
collectExpansionScripts(node.name, pending);
|
|
66
|
-
for (const prefix of node.prefix)
|
|
67
|
-
if (prefix.value)
|
|
68
|
-
collectExpansionScripts(prefix.value, pending);
|
|
69
|
-
for (const suffix of node.suffix)
|
|
70
|
-
collectExpansionScripts(suffix, pending);
|
|
53
|
+
const processCommand = (node) => {
|
|
71
54
|
if (definedFunctions.size && node.name && definedFunctions.has(extractBinary(node.name.value)))
|
|
72
55
|
return [];
|
|
73
56
|
return getDependenciesFromCommand(node, { ...options, fromArgs }, fromWords);
|
|
@@ -2,4 +2,4 @@ import type { Command, Word } from 'unbash';
|
|
|
2
2
|
import type { BinaryResolverOptions, GetInputsFromScriptsOptions } from '../types/config.ts';
|
|
3
3
|
import { type Input } from '../util/input.ts';
|
|
4
4
|
export declare const getInputsFromNodeOptions: (prefix: Command['prefix']) => Input[];
|
|
5
|
-
export declare const getDependenciesFromCommand: (node: Command, options: BinaryResolverOptions, fromWords?: (words: Word[], options: GetInputsFromScriptsOptions) => Input[]) => Input[];
|
|
5
|
+
export declare const getDependenciesFromCommand: (node: Pick<Command, 'name' | 'prefix' | 'args'>, options: BinaryResolverOptions, fromWords?: (words: Word[], options: GetInputsFromScriptsOptions) => Input[]) => Input[];
|
package/dist/binaries/command.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { Plugins, pluginArgsMap } from '../plugins.js';
|
|
2
2
|
import { toDeferResolve } from '../util/input.js';
|
|
3
3
|
import { extractBinary, isInNodeModulesBin, isRelativeNodeModulesBin } from '../util/modules.js';
|
|
4
|
+
import { getCommandWords } from '../util/scripts.js';
|
|
4
5
|
import { resolve as fallbackResolve, spawningBinaries } from './fallback.js';
|
|
5
6
|
import KnownResolvers, { isPackageManager } from './resolvers/index.js';
|
|
6
7
|
import { resolve as resolverFromPlugins } from './plugins.js';
|
|
7
8
|
import { parseNodeArgs, toCommandBinary } from './util.js';
|
|
8
|
-
export const getInputsFromNodeOptions = (prefix) =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
export const getInputsFromNodeOptions = (prefix) => {
|
|
10
|
+
const inputs = [];
|
|
11
|
+
for (const item of prefix) {
|
|
12
|
+
if (item.type !== 'Assignment' || item.name !== 'NODE_OPTIONS' || item.value.type !== 'Word')
|
|
13
|
+
continue;
|
|
14
|
+
const args = parseNodeArgs(item.value.value.split(' '));
|
|
15
|
+
if (args.require)
|
|
16
|
+
for (const id of [args.require].flat())
|
|
17
|
+
inputs.push(toDeferResolve(id));
|
|
18
|
+
}
|
|
19
|
+
return inputs;
|
|
20
|
+
};
|
|
15
21
|
export const getDependenciesFromCommand = (node, options, fromWords = options.fromArgs) => {
|
|
16
22
|
const text = node.name?.value;
|
|
17
23
|
if (!text)
|
|
@@ -31,7 +37,7 @@ export const getDependenciesFromCommand = (node, options, fromWords = options.fr
|
|
|
31
37
|
};
|
|
32
38
|
}
|
|
33
39
|
const { fromArgs } = options;
|
|
34
|
-
const words = node
|
|
40
|
+
const words = getCommandWords(node);
|
|
35
41
|
if (binary === '!' || binary === 'test')
|
|
36
42
|
return fromArgs(words);
|
|
37
43
|
const fromNodeOptions = getInputsFromNodeOptions(node.prefix);
|
package/dist/graph/build.js
CHANGED
|
@@ -51,8 +51,8 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
deputy.setWorkspacePkgNames(chief.availableWorkspacePkgNames);
|
|
54
|
-
collector.addIgnorePatterns(chief.config.ignore.map(id => ({ pattern:
|
|
55
|
-
collector.addIgnoreFilesPatterns(chief.config.ignoreFiles.map(id => ({ pattern:
|
|
54
|
+
collector.addIgnorePatterns(chief.config.ignore.map(id => ({ pattern: id, id })));
|
|
55
|
+
collector.addIgnoreFilesPatterns(chief.config.ignoreFiles.map(id => ({ pattern: id, id })));
|
|
56
56
|
if (options.configFilePath) {
|
|
57
57
|
principal.addEntryPath(options.configFilePath, { skipExportsAnalysis: true });
|
|
58
58
|
}
|
|
@@ -79,7 +79,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
79
79
|
continue;
|
|
80
80
|
const dependencies = deputy.getDependencies(name);
|
|
81
81
|
const tsConfigFilePath = join(dir, options.tsConfigFile ?? 'tsconfig.json');
|
|
82
|
-
const { isFile, compilerOptions, fileNames, include, exclude, sourceMapPairs, paths: tsConfigPaths, } = await loadTSConfig(tsConfigFilePath);
|
|
82
|
+
const { isFile, compilerOptions, fileNames, include, exclude, sourceMapPairs, paths: tsConfigPaths, } = await loadTSConfig(tsConfigFilePath, options.isUseTscFiles);
|
|
83
83
|
const [definitionPaths, tscSourcePaths] = partition(fileNames, filePath => IS_DTS.test(filePath));
|
|
84
84
|
const worker = new WorkspaceWorker({
|
|
85
85
|
name,
|
|
@@ -122,7 +122,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
122
122
|
inputs.add(toProductionEntry(tryRealpath(id), { containingFilePath: tsConfigFilePath }));
|
|
123
123
|
}
|
|
124
124
|
const sharedGlobOptions = { cwd: options.cwd, dir, gitignore: options.gitignore };
|
|
125
|
-
const fn = (id) => ({ pattern: prependDir(
|
|
125
|
+
const fn = (id) => ({ pattern: prependDir(name, id), id, workspaceName: name });
|
|
126
126
|
collector.addIgnorePatterns(config.ignore.map(fn));
|
|
127
127
|
collector.addIgnoreFilesPatterns(config.ignoreFiles.map(fn));
|
|
128
128
|
const entrySpecifiersFromManifest = getEntrySpecifiersFromManifest(manifest);
|
|
@@ -249,7 +249,10 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
249
249
|
}
|
|
250
250
|
const developmentMatchers = [];
|
|
251
251
|
if (options.isProduction) {
|
|
252
|
-
const toPattern = (pattern) =>
|
|
252
|
+
const toPattern = (pattern) => {
|
|
253
|
+
const id = removeProductionSuffix(pattern);
|
|
254
|
+
return isAbsolute(id) ? relative(options.cwd, id) : join(name, id);
|
|
255
|
+
};
|
|
253
256
|
for (const map of [entryPatterns, entryPatternsSkipExports]) {
|
|
254
257
|
for (const patterns of map.values()) {
|
|
255
258
|
const [excluded, included] = partition(patterns, pattern => pattern.startsWith('!'));
|
|
@@ -260,7 +263,12 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
}
|
|
263
|
-
const productionPaths = (paths) => developmentMatchers.length
|
|
266
|
+
const productionPaths = (paths) => developmentMatchers.length
|
|
267
|
+
? paths.filter(path => {
|
|
268
|
+
const relativePath = relative(options.cwd, path);
|
|
269
|
+
return !developmentMatchers.some(match => match(relativePath));
|
|
270
|
+
})
|
|
271
|
+
: paths;
|
|
264
272
|
const userEntryPatterns = options.isProduction
|
|
265
273
|
? worker.getProductionEntryFilePatterns()
|
|
266
274
|
: worker.getEntryFilePatterns();
|
|
@@ -313,10 +321,11 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
313
321
|
}
|
|
314
322
|
if (extensions.length > 0) {
|
|
315
323
|
const extPart = extensions.length === 1 ? extensions[0] : `.{${extensions.map(ext => ext.slice(1)).join(',')}}`;
|
|
316
|
-
const
|
|
324
|
+
const tsConfigDir = relative(dir, dirname(tsConfigFilePath));
|
|
325
|
+
const bases = include ? new Set(include.map(p => join(tsConfigDir, picomatch.scan(p).base))) : new Set(['']);
|
|
317
326
|
const patterns = [
|
|
318
|
-
...Array.from(bases, base =>
|
|
319
|
-
...(exclude?.map(p => `!${p}`) ?? []),
|
|
327
|
+
...Array.from(bases, base => join(base, `**/*${extPart}`)),
|
|
328
|
+
...(exclude?.map(p => `!${join(tsConfigDir, p)}`) ?? []),
|
|
320
329
|
];
|
|
321
330
|
const compilerPaths = await _glob({ ...sharedGlobOptions, patterns, label: 'compiler extension paths' });
|
|
322
331
|
for (const compilerPath of compilerPaths) {
|
|
@@ -38,10 +38,16 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
|
|
|
38
38
|
return hasCompleteResult();
|
|
39
39
|
}
|
|
40
40
|
const node = graph.get(path);
|
|
41
|
-
|
|
42
|
-
if (!identifier || !node || !file) {
|
|
41
|
+
if (!identifier || !node) {
|
|
43
42
|
return false;
|
|
44
43
|
}
|
|
44
|
+
if (isEntryFile && node.skipExports) {
|
|
45
|
+
isReferenced = true;
|
|
46
|
+
return hasCompleteResult();
|
|
47
|
+
}
|
|
48
|
+
const file = node.importedBy;
|
|
49
|
+
if (!file)
|
|
50
|
+
return false;
|
|
45
51
|
const follow = (sources, nextId, nextViaStar = viaStar) => {
|
|
46
52
|
for (const byFilePath of sources) {
|
|
47
53
|
if (walkDown(byFilePath, nextId, nextViaStar))
|
package/dist/manifest/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ declare const getMetaDataFromPackageJson: ({ dir, packageNames }: Options) => {
|
|
|
7
7
|
hostDependencies: HostDependencies;
|
|
8
8
|
installedBinaries: InstalledBinaries;
|
|
9
9
|
hasTypesIncluded: Set<string>;
|
|
10
|
+
uninstalledDependencies: Set<string>;
|
|
10
11
|
};
|
|
11
12
|
export declare const getDependencyMetaData: typeof getMetaDataFromPackageJson;
|
|
12
13
|
export {};
|
package/dist/manifest/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const getMetaDataFromPackageJson = ({ dir, packageNames }) => {
|
|
|
5
5
|
const hostDependencies = new Map();
|
|
6
6
|
const installedBinaries = new Map();
|
|
7
7
|
const hasTypesIncluded = new Set();
|
|
8
|
+
const uninstalledDependencies = new Set();
|
|
8
9
|
const addBinary = (key, value) => {
|
|
9
10
|
const set = installedBinaries.get(key);
|
|
10
11
|
if (set)
|
|
@@ -15,10 +16,9 @@ const getMetaDataFromPackageJson = ({ dir, packageNames }) => {
|
|
|
15
16
|
for (const packageName of packageNames) {
|
|
16
17
|
const manifest = loadPackageManifest({ dir, packageName });
|
|
17
18
|
if (manifest) {
|
|
18
|
-
const
|
|
19
|
-
const binaries = typeof manifest.bin === 'string' ? [defaultBinaryName] : Object.keys(manifest.bin ?? {});
|
|
19
|
+
const binaries = typeof manifest.bin === 'string' ? [packageName] : Object.keys(manifest.bin ?? {});
|
|
20
20
|
for (const binaryName of binaries)
|
|
21
|
-
addBinary(binaryName, packageName);
|
|
21
|
+
addBinary(binaryName.replace(/^@[^/]+\//, ''), packageName);
|
|
22
22
|
const packagePeerDependencies = Object.keys(manifest.peerDependencies ?? {});
|
|
23
23
|
for (const packagePeerDependency of packagePeerDependencies) {
|
|
24
24
|
const hostDependency = {
|
|
@@ -35,11 +35,15 @@ const getMetaDataFromPackageJson = ({ dir, packageNames }) => {
|
|
|
35
35
|
if (!isDefinitelyTyped(packageName) && (manifest.types || manifest.typings))
|
|
36
36
|
hasTypesIncluded.add(packageName);
|
|
37
37
|
}
|
|
38
|
+
else {
|
|
39
|
+
uninstalledDependencies.add(packageName);
|
|
40
|
+
}
|
|
38
41
|
}
|
|
39
42
|
return {
|
|
40
43
|
hostDependencies,
|
|
41
44
|
installedBinaries,
|
|
42
45
|
hasTypesIncluded,
|
|
46
|
+
uninstalledDependencies,
|
|
43
47
|
};
|
|
44
48
|
};
|
|
45
49
|
export const getDependencyMetaData = timerify(getMetaDataFromPackageJson);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IMPORT_FLAGS } from '../../constants.js';
|
|
2
|
+
import { getPropertyValues } from '../../typescript/ast-helpers.js';
|
|
3
|
+
import { dirname, join } from '../../util/path.js';
|
|
4
|
+
export function createComponentStyleUrlsVisitor(ctx, isSpecifier) {
|
|
5
|
+
const componentNames = new Set();
|
|
6
|
+
return {
|
|
7
|
+
Program() {
|
|
8
|
+
componentNames.clear();
|
|
9
|
+
},
|
|
10
|
+
ImportDeclaration(node) {
|
|
11
|
+
if (!isSpecifier(node.source?.value))
|
|
12
|
+
return;
|
|
13
|
+
for (const spec of node.specifiers ?? []) {
|
|
14
|
+
if (spec.type === 'ImportSpecifier' &&
|
|
15
|
+
spec.imported.type === 'Identifier' &&
|
|
16
|
+
spec.imported.name === 'Component')
|
|
17
|
+
componentNames.add(spec.local.name);
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
ClassDeclaration(node) {
|
|
21
|
+
if (componentNames.size === 0)
|
|
22
|
+
return;
|
|
23
|
+
const dir = dirname(ctx.filePath);
|
|
24
|
+
for (const decorator of node.decorators ?? []) {
|
|
25
|
+
const expr = decorator.expression;
|
|
26
|
+
if (expr?.type !== 'CallExpression')
|
|
27
|
+
continue;
|
|
28
|
+
if (expr.callee?.type !== 'Identifier' || !componentNames.has(expr.callee.name))
|
|
29
|
+
continue;
|
|
30
|
+
const arg = expr.arguments?.[0];
|
|
31
|
+
if (arg?.type !== 'ObjectExpression')
|
|
32
|
+
continue;
|
|
33
|
+
for (const url of getPropertyValues(arg, 'styleUrl'))
|
|
34
|
+
ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
|
|
35
|
+
for (const url of getPropertyValues(arg, 'styleUrls'))
|
|
36
|
+
ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -2,6 +2,7 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { toConfig, toDeferResolve, toDependency, toEntry, toProductionEntry } from '../../util/input.js';
|
|
3
3
|
import { isInternal, join } from '../../util/path.js';
|
|
4
4
|
import { hasDependency } from '../../util/plugin.js';
|
|
5
|
+
import { createComponentStyleUrlsVisitor } from '../_component-style-urls/component-style-urls-visitor.js';
|
|
5
6
|
import * as karma from '../karma/helpers.js';
|
|
6
7
|
const title = 'Angular';
|
|
7
8
|
const enablers = ['@angular/cli'];
|
|
@@ -72,7 +73,7 @@ const resolveConfig = async (config, options) => {
|
|
|
72
73
|
karma.inputsFromFrameworks(['jasmine']).forEach(inputs.add, inputs);
|
|
73
74
|
}
|
|
74
75
|
if (karmaConfig && !karma.configFiles.includes(karmaConfig)) {
|
|
75
|
-
inputs.add(toConfig('karma', karmaConfig
|
|
76
|
+
inputs.add(toConfig('karma', karmaConfig));
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
}
|
|
@@ -111,11 +112,16 @@ const isAngularBuilderRefWithName = ({ builderRef, name }) => {
|
|
|
111
112
|
};
|
|
112
113
|
const PRODUCTION_CONFIG_NAME = 'production';
|
|
113
114
|
const BUILD_TARGET_NAME = 'build';
|
|
115
|
+
const isAngularSpecifier = (specifier) => specifier === '@angular/core';
|
|
116
|
+
const registerVisitors = ({ ctx, registerVisitor }) => {
|
|
117
|
+
registerVisitor(createComponentStyleUrlsVisitor(ctx, isAngularSpecifier));
|
|
118
|
+
};
|
|
114
119
|
const plugin = {
|
|
115
120
|
title,
|
|
116
121
|
enablers,
|
|
117
122
|
isEnabled,
|
|
118
123
|
config,
|
|
119
124
|
resolveConfig,
|
|
125
|
+
registerVisitors,
|
|
120
126
|
};
|
|
121
127
|
export default plugin;
|