knip 5.64.3 → 5.66.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.
Files changed (37) hide show
  1. package/dist/ConfigurationChief.d.ts +8 -0
  2. package/dist/ConfigurationChief.js +7 -1
  3. package/dist/IssueCollector.d.ts +7 -0
  4. package/dist/IssueCollector.js +39 -0
  5. package/dist/WorkspaceWorker.d.ts +2 -5
  6. package/dist/WorkspaceWorker.js +2 -7
  7. package/dist/compilers/index.d.ts +13 -0
  8. package/dist/graph/build.js +5 -4
  9. package/dist/index.js +1 -0
  10. package/dist/plugins/danger/index.d.ts +8 -0
  11. package/dist/plugins/danger/index.js +11 -0
  12. package/dist/plugins/eleventy/helpers.d.ts +1 -0
  13. package/dist/plugins/eleventy/helpers.js +1 -0
  14. package/dist/plugins/index.d.ts +6 -0
  15. package/dist/plugins/index.js +2 -0
  16. package/dist/plugins/lint-staged/index.js +11 -5
  17. package/dist/plugins/lint-staged/types.d.ts +9 -4
  18. package/dist/plugins/typescript/index.js +1 -1
  19. package/dist/schema/configuration.d.ts +13 -0
  20. package/dist/schema/configuration.js +4 -0
  21. package/dist/schema/plugins.d.ts +5 -0
  22. package/dist/schema/plugins.js +1 -0
  23. package/dist/types/PluginNames.d.ts +2 -2
  24. package/dist/types/PluginNames.js +1 -0
  25. package/dist/types/config.d.ts +5 -1
  26. package/dist/typescript/ast-helpers.d.ts +1 -1
  27. package/dist/typescript/ast-helpers.js +12 -1
  28. package/dist/typescript/get-imports-and-exports.js +14 -6
  29. package/dist/util/create-options.d.ts +13 -0
  30. package/dist/util/fs.d.ts +2 -1
  31. package/dist/util/fs.js +15 -5
  32. package/dist/util/glob-core.js +5 -4
  33. package/dist/util/loader.js +6 -3
  34. package/dist/version.d.ts +1 -1
  35. package/dist/version.js +1 -1
  36. package/package.json +1 -1
  37. package/schema.json +38 -10
@@ -147,6 +147,11 @@ export declare class ConfigurationChief {
147
147
  entry?: string | string[] | undefined;
148
148
  project?: string | string[] | undefined;
149
149
  } | undefined;
150
+ danger?: string | boolean | string[] | {
151
+ config?: string | string[] | undefined;
152
+ entry?: string | string[] | undefined;
153
+ project?: string | string[] | undefined;
154
+ } | undefined;
150
155
  'dependency-cruiser'?: string | boolean | string[] | {
151
156
  config?: string | string[] | undefined;
152
157
  entry?: string | string[] | undefined;
@@ -626,6 +631,7 @@ export declare class ConfigurationChief {
626
631
  project?: string | string[] | undefined;
627
632
  paths?: Record<string, string[]> | undefined;
628
633
  ignore?: string | string[] | undefined;
634
+ ignoreFiles?: string | string[] | undefined;
629
635
  ignoreBinaries?: (string | RegExp)[] | undefined;
630
636
  ignoreDependencies?: (string | RegExp)[] | undefined;
631
637
  ignoreMembers?: (string | RegExp)[] | undefined;
@@ -657,6 +663,7 @@ export declare class ConfigurationChief {
657
663
  cspell?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
658
664
  cucumber?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
659
665
  cypress?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
666
+ danger?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
660
667
  "dependency-cruiser"?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
661
668
  docusaurus?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
662
669
  dotenv?: (boolean | import("./types/config.js").EnsuredPluginConfiguration) | undefined;
@@ -756,6 +763,7 @@ export declare class ConfigurationChief {
756
763
  project: string[];
757
764
  paths: Record<string, string[]>;
758
765
  ignore: string[];
766
+ ignoreFiles: string[];
759
767
  isIncludeEntryExports: boolean;
760
768
  };
761
769
  findWorkspaceByFilePath(filePath: string): Workspace | undefined;
@@ -31,6 +31,7 @@ const getDefaultWorkspaceConfig = (extensions = []) => {
31
31
  const isPluginName = (name) => pluginNames.includes(name);
32
32
  const defaultConfig = {
33
33
  ignore: [],
34
+ ignoreFiles: [],
34
35
  ignoreBinaries: [],
35
36
  ignoreDependencies: [],
36
37
  ignoreMembers: [],
@@ -91,11 +92,13 @@ export class ConfigurationChief {
91
92
  }
92
93
  normalize(rawConfig) {
93
94
  const ignore = arrayify(rawConfig.ignore ?? defaultConfig.ignore);
95
+ const ignoreFiles = arrayify(rawConfig.ignoreFiles ?? defaultConfig.ignoreFiles);
94
96
  const ignoreBinaries = rawConfig.ignoreBinaries ?? [];
95
97
  const ignoreDependencies = rawConfig.ignoreDependencies ?? [];
96
98
  const ignoreMembers = rawConfig.ignoreMembers ?? [];
97
99
  const ignoreUnresolved = rawConfig.ignoreUnresolved ?? [];
98
100
  const ignoreExportsUsedInFile = rawConfig.ignoreExportsUsedInFile ?? false;
101
+ const ignoreIssues = rawConfig.ignoreIssues;
99
102
  const ignoreWorkspaces = rawConfig.ignoreWorkspaces ?? defaultConfig.ignoreWorkspaces;
100
103
  const isIncludeEntryExports = rawConfig.includeEntryExports ?? this.isIncludeEntryExports;
101
104
  const { syncCompilers, asyncCompilers } = rawConfig;
@@ -107,11 +110,13 @@ export class ConfigurationChief {
107
110
  }
108
111
  return {
109
112
  ignore,
113
+ ignoreFiles,
110
114
  ignoreBinaries,
111
115
  ignoreDependencies,
112
116
  ignoreMembers,
113
117
  ignoreUnresolved,
114
118
  ignoreExportsUsedInFile,
119
+ ignoreIssues,
115
120
  ignoreWorkspaces,
116
121
  isIncludeEntryExports,
117
122
  syncCompilers: new Map(Object.entries(syncCompilers ?? {})),
@@ -309,6 +314,7 @@ export class ConfigurationChief {
309
314
  const project = workspaceConfig.project ? arrayify(workspaceConfig.project) : baseConfig.project;
310
315
  const paths = workspaceConfig.paths ?? {};
311
316
  const ignore = arrayify(workspaceConfig.ignore);
317
+ const ignoreFiles = arrayify(workspaceConfig.ignoreFiles);
312
318
  const isIncludeEntryExports = workspaceConfig.includeEntryExports ?? this.config.isIncludeEntryExports;
313
319
  const plugins = {};
314
320
  for (const [pluginName, pluginConfig] of Object.entries(this.config.rootPluginConfigs)) {
@@ -320,7 +326,7 @@ export class ConfigurationChief {
320
326
  plugins[pluginName] = normalizePluginConfig(pluginConfig);
321
327
  }
322
328
  }
323
- return { entry, project, paths, ignore, isIncludeEntryExports, ...plugins };
329
+ return { entry, project, paths, ignore, ignoreFiles, isIncludeEntryExports, ...plugins };
324
330
  }
325
331
  findWorkspaceByFilePath(filePath) {
326
332
  const workspaceDir = this.availableWorkspaceDirs.find(workspaceDir => filePath.startsWith(`${workspaceDir}/`));
@@ -1,3 +1,4 @@
1
+ import type { IgnoreIssues } from './types/config.js';
1
2
  import type { ConfigurationHint, Issue, TagHint } from './types/issues.js';
2
3
  import type { MainOptions } from './util/create-options.js';
3
4
  export declare class IssueCollector {
@@ -10,9 +11,15 @@ export declare class IssueCollector {
10
11
  private configurationHints;
11
12
  private tagHints;
12
13
  private ignorePatterns;
14
+ private ignoreFilesPatterns;
13
15
  private isMatch;
16
+ private isFileMatch;
17
+ private issueMatchers;
14
18
  constructor(options: MainOptions);
15
19
  addIgnorePatterns(patterns: string[]): void;
20
+ addIgnoreFilesPatterns(patterns: string[]): void;
21
+ setIgnoreIssues(ignoreIssues?: IgnoreIssues): void;
22
+ private shouldIgnoreIssue;
16
23
  addFileCounts({ processed, unused }: {
17
24
  processed: number;
18
25
  unused: number;
@@ -13,12 +13,16 @@ export class IssueCollector {
13
13
  configurationHints = new Map();
14
14
  tagHints = new Set();
15
15
  ignorePatterns = new Set();
16
+ ignoreFilesPatterns = new Set();
16
17
  isMatch;
18
+ isFileMatch;
19
+ issueMatchers = new Map();
17
20
  constructor(options) {
18
21
  this.cwd = options.cwd;
19
22
  this.rules = options.rules;
20
23
  this.filter = options.workspace ? join(options.cwd, options.workspace) : undefined;
21
24
  this.isMatch = () => false;
25
+ this.isFileMatch = () => false;
22
26
  }
23
27
  addIgnorePatterns(patterns) {
24
28
  for (const pattern of patterns)
@@ -26,6 +30,35 @@ export class IssueCollector {
26
30
  const p = [...this.ignorePatterns];
27
31
  this.isMatch = (filePath) => isMatch(filePath, p, { dot: true });
28
32
  }
33
+ addIgnoreFilesPatterns(patterns) {
34
+ for (const pattern of patterns)
35
+ this.ignoreFilesPatterns.add(pattern);
36
+ const p = [...this.ignoreFilesPatterns];
37
+ this.isFileMatch = (filePath) => isMatch(filePath, p, { dot: true });
38
+ }
39
+ setIgnoreIssues(ignoreIssues) {
40
+ if (!ignoreIssues)
41
+ return;
42
+ const issueTypePatterns = new Map();
43
+ for (const [pattern, issueTypes] of Object.entries(ignoreIssues)) {
44
+ for (const issueType of issueTypes) {
45
+ if (!issueTypePatterns.has(issueType)) {
46
+ issueTypePatterns.set(issueType, []);
47
+ }
48
+ issueTypePatterns.get(issueType)?.push(pattern);
49
+ }
50
+ }
51
+ for (const [issueType, patterns] of issueTypePatterns) {
52
+ this.issueMatchers.set(issueType, (filePath) => isMatch(filePath, patterns, { dot: true }));
53
+ }
54
+ }
55
+ shouldIgnoreIssue(filePath, issueType) {
56
+ const matcher = this.issueMatchers.get(issueType);
57
+ if (!matcher)
58
+ return false;
59
+ const relativePath = relative(this.cwd, filePath);
60
+ return matcher(relativePath);
61
+ }
29
62
  addFileCounts({ processed, unused }) {
30
63
  this.counters.processed += processed;
31
64
  this.counters.total += processed + unused;
@@ -38,6 +71,10 @@ export class IssueCollector {
38
71
  continue;
39
72
  if (this.isMatch(filePath))
40
73
  continue;
74
+ if (this.isFileMatch(filePath))
75
+ continue;
76
+ if (this.shouldIgnoreIssue(filePath, 'files'))
77
+ continue;
41
78
  this.issues.files.add(filePath);
42
79
  const symbol = relative(this.cwd, filePath);
43
80
  this.issues._files[symbol] = [{ type: 'files', filePath, symbol, severity: this.rules.files }];
@@ -50,6 +87,8 @@ export class IssueCollector {
50
87
  return;
51
88
  if (this.isMatch(issue.filePath))
52
89
  return;
90
+ if (this.shouldIgnoreIssue(issue.filePath, issue.type))
91
+ return;
53
92
  const key = relative(this.cwd, issue.filePath);
54
93
  const { type } = issue;
55
94
  issue.severity = this.rules[type];
@@ -1,6 +1,6 @@
1
1
  import { CacheConsultant } from './CacheConsultant.js';
2
2
  import { type Workspace } from './ConfigurationChief.js';
3
- import type { Configuration, GetReferencedInternalFilePath, GetSourceFile, WorkspaceConfiguration } from './types/config.js';
3
+ import type { GetReferencedInternalFilePath, GetSourceFile, WorkspaceConfiguration } from './types/config.js';
4
4
  import type { ConfigurationHint } from './types/issues.js';
5
5
  import type { PluginName } from './types/PluginNames.js';
6
6
  import type { PackageJson } from './types/package-json.js';
@@ -16,7 +16,6 @@ type WorkspaceManagerOptions = {
16
16
  getReferencedInternalFilePath: GetReferencedInternalFilePath;
17
17
  findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
18
18
  getSourceFile: GetSourceFile;
19
- rootIgnore: Configuration['ignore'];
20
19
  negatedWorkspacePatterns: string[];
21
20
  ignoredWorkspacePatterns: string[];
22
21
  enabledPluginsInAncestors: string[];
@@ -37,7 +36,6 @@ export declare class WorkspaceWorker {
37
36
  getReferencedInternalFilePath: GetReferencedInternalFilePath;
38
37
  findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
39
38
  getSourceFile: GetSourceFile;
40
- rootIgnore: Configuration['ignore'];
41
39
  negatedWorkspacePatterns: string[];
42
40
  ignoredWorkspacePatterns: string[];
43
41
  options: MainOptions;
@@ -46,7 +44,7 @@ export declare class WorkspaceWorker {
46
44
  enabledPluginsInAncestors: string[];
47
45
  cache: CacheConsultant<CacheItem>;
48
46
  configFilesMap: Map<string, Map<PluginName, Set<string>>>;
49
- constructor({ name, dir, config, manifest, dependencies, rootIgnore, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, getReferencedInternalFilePath, findWorkspaceByFilePath, getSourceFile, configFilesMap, options, }: WorkspaceManagerOptions);
47
+ constructor({ name, dir, config, manifest, dependencies, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, getReferencedInternalFilePath, findWorkspaceByFilePath, getSourceFile, configFilesMap, options, }: WorkspaceManagerOptions);
50
48
  init(): Promise<void>;
51
49
  private determineEnabledPlugins;
52
50
  private getConfigForPlugin;
@@ -58,7 +56,6 @@ export declare class WorkspaceWorker {
58
56
  getProductionEntryFilePatterns(negatedTestFilePatterns: string[]): string[];
59
57
  getProductionProjectFilePatterns(negatedTestFilePatterns: string[]): string[];
60
58
  private getConfigurationFilePatterns;
61
- getIgnorePatterns(): string[];
62
59
  runPlugins(): Promise<Input[]>;
63
60
  getConfigurationHints(type: 'entry' | 'project', patterns: string[], filePaths: string[], includedPaths: Set<string>): Set<ConfigurationHint>;
64
61
  onDispose(): void;
@@ -7,7 +7,7 @@ import { getFilteredScripts } from './manifest/helpers.js';
7
7
  import { PluginEntries, Plugins } from './plugins.js';
8
8
  import { compact } from './util/array.js';
9
9
  import { debugLogArray, debugLogObject } from './util/debug.js';
10
- import { _glob, hasNoProductionSuffix, hasProductionSuffix, negate, prependDirToPattern } from './util/glob.js';
10
+ import { _glob, hasNoProductionSuffix, hasProductionSuffix, negate } from './util/glob.js';
11
11
  import { isConfig, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
12
12
  import { getKeysByValue } from './util/object.js';
13
13
  import { timerify } from './util/Performance.js';
@@ -25,7 +25,6 @@ export class WorkspaceWorker {
25
25
  getReferencedInternalFilePath;
26
26
  findWorkspaceByFilePath;
27
27
  getSourceFile;
28
- rootIgnore;
29
28
  negatedWorkspacePatterns = [];
30
29
  ignoredWorkspacePatterns = [];
31
30
  options;
@@ -34,13 +33,12 @@ export class WorkspaceWorker {
34
33
  enabledPluginsInAncestors;
35
34
  cache;
36
35
  configFilesMap;
37
- constructor({ name, dir, config, manifest, dependencies, rootIgnore, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, getReferencedInternalFilePath, findWorkspaceByFilePath, getSourceFile, configFilesMap, options, }) {
36
+ constructor({ name, dir, config, manifest, dependencies, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, getReferencedInternalFilePath, findWorkspaceByFilePath, getSourceFile, configFilesMap, options, }) {
38
37
  this.name = name;
39
38
  this.dir = dir;
40
39
  this.config = config;
41
40
  this.manifest = manifest;
42
41
  this.dependencies = dependencies;
43
- this.rootIgnore = rootIgnore;
44
42
  this.negatedWorkspacePatterns = negatedWorkspacePatterns;
45
43
  this.ignoredWorkspacePatterns = ignoredWorkspacePatterns;
46
44
  this.enabledPluginsInAncestors = enabledPluginsInAncestors;
@@ -159,9 +157,6 @@ export class WorkspaceWorker {
159
157
  const pluginConfig = this.getConfigForPlugin(pluginName);
160
158
  return pluginConfig.config ?? plugin.config ?? [];
161
159
  }
162
- getIgnorePatterns() {
163
- return [...this.rootIgnore, ...this.config.ignore.map(pattern => prependDirToPattern(this.name, pattern))];
164
- }
165
160
  async runPlugins() {
166
161
  const wsName = this.name;
167
162
  const cwd = this.dir;
@@ -99,6 +99,11 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
99
99
  entry?: string | string[] | undefined;
100
100
  project?: string | string[] | undefined;
101
101
  } | undefined;
102
+ danger?: string | boolean | string[] | {
103
+ config?: string | string[] | undefined;
104
+ entry?: string | string[] | undefined;
105
+ project?: string | string[] | undefined;
106
+ } | undefined;
102
107
  'dependency-cruiser'?: string | boolean | string[] | {
103
108
  config?: string | string[] | undefined;
104
109
  entry?: string | string[] | undefined;
@@ -670,6 +675,11 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
670
675
  entry?: string | string[] | undefined;
671
676
  project?: string | string[] | undefined;
672
677
  } | undefined;
678
+ danger?: string | boolean | string[] | {
679
+ config?: string | string[] | undefined;
680
+ entry?: string | string[] | undefined;
681
+ project?: string | string[] | undefined;
682
+ } | undefined;
673
683
  'dependency-cruiser'?: string | boolean | string[] | {
674
684
  config?: string | string[] | undefined;
675
685
  entry?: string | string[] | undefined;
@@ -1149,6 +1159,7 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
1149
1159
  project?: string | string[] | undefined;
1150
1160
  paths?: Record<string, string[]> | undefined;
1151
1161
  ignore?: string | string[] | undefined;
1162
+ ignoreFiles?: string | string[] | undefined;
1152
1163
  ignoreBinaries?: (string | RegExp)[] | undefined;
1153
1164
  ignoreDependencies?: (string | RegExp)[] | undefined;
1154
1165
  ignoreMembers?: (string | RegExp)[] | undefined;
@@ -1163,6 +1174,7 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
1163
1174
  project?: string | string[] | undefined;
1164
1175
  paths?: Record<string, string[]> | undefined;
1165
1176
  ignore?: string | string[] | undefined;
1177
+ ignoreFiles?: string | string[] | undefined;
1166
1178
  ignoreBinaries?: (string | RegExp)[] | undefined;
1167
1179
  ignoreDependencies?: (string | RegExp)[] | undefined;
1168
1180
  ignoreMembers?: (string | RegExp)[] | undefined;
@@ -1175,6 +1187,7 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
1175
1187
  member?: boolean | undefined;
1176
1188
  type?: boolean | undefined;
1177
1189
  } | undefined;
1190
+ ignoreIssues?: Record<string, ("files" | "dependencies" | "devDependencies" | "optionalPeerDependencies" | "unlisted" | "binaries" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers")[]> | undefined;
1178
1191
  ignoreWorkspaces?: string[] | undefined;
1179
1192
  includeEntryExports?: boolean | undefined;
1180
1193
  compilers?: Record<string, true | ((filename: string, contents: string) => string) | ((filename: string, contents: string) => Promise<string>)> | undefined;
@@ -3,7 +3,7 @@ import { getCompilerExtensions, getIncludedCompilers } from '../compilers/index.
3
3
  import { DEFAULT_EXTENSIONS, FOREIGN_FILE_EXTENSIONS } from '../constants.js';
4
4
  import { debugLog, debugLogArray } from '../util/debug.js';
5
5
  import { getReferencedInputsHandler } from '../util/get-referenced-inputs.js';
6
- import { _glob, _syncGlob, negate } from '../util/glob.js';
6
+ import { _glob, _syncGlob, negate, prependDirToPattern } from '../util/glob.js';
7
7
  import { isAlias, isConfig, isDeferResolveEntry, isDeferResolveProductionEntry, isEntry, isIgnore, isProductionEntry, isProject, toProductionEntry, } from '../util/input.js';
8
8
  import { loadTSConfig } from '../util/load-tsconfig.js';
9
9
  import { getOrCreateFileNode, updateImportMap } from '../util/module-graph.js';
@@ -34,6 +34,8 @@ export async function build({ chief, collector, deputy, factory, isGitIgnored, s
34
34
  ...chief.getIgnores(name),
35
35
  });
36
36
  }
37
+ collector.addIgnorePatterns(chief.config.ignore.map(p => join(options.cwd, p)));
38
+ collector.addIgnoreFilesPatterns(chief.config.ignoreFiles.map(p => join(options.cwd, p)));
37
39
  for (const workspace of workspaces) {
38
40
  const { name, dir, ancestors, pkgName, manifestPath: filePath } = workspace;
39
41
  streamer.cast('Analyzing workspace', name);
@@ -57,7 +59,6 @@ export async function build({ chief, collector, deputy, factory, isGitIgnored, s
57
59
  dependencies,
58
60
  getReferencedInternalFilePath: (input) => getReferencedInternalFilePath(input, workspace),
59
61
  findWorkspaceByFilePath: chief.findWorkspaceByFilePath.bind(chief),
60
- rootIgnore: chief.config.ignore,
61
62
  negatedWorkspacePatterns: chief.getNegatedWorkspacePatterns(name),
62
63
  ignoredWorkspacePatterns: chief.getIgnoredWorkspacesFor(name),
63
64
  enabledPluginsInAncestors: ancestors.flatMap(ancestor => enabledPluginsStore.get(ancestor) ?? []),
@@ -72,9 +73,9 @@ export async function build({ chief, collector, deputy, factory, isGitIgnored, s
72
73
  for (const id of definitionPaths)
73
74
  inputs.add(toProductionEntry(id, { containingFilePath: tsConfigFilePath }));
74
75
  }
75
- const ignore = worker.getIgnorePatterns();
76
76
  const sharedGlobOptions = { cwd: options.cwd, dir, gitignore: options.gitignore };
77
- collector.addIgnorePatterns(ignore.map(pattern => join(options.cwd, pattern)));
77
+ collector.addIgnorePatterns(config.ignore.map(p => join(options.cwd, prependDirToPattern(name, p))));
78
+ collector.addIgnoreFilesPatterns(config.ignoreFiles.map(p => join(options.cwd, prependDirToPattern(name, p))));
78
79
  const entrySpecifiersFromManifest = getEntrySpecifiersFromManifest(manifest);
79
80
  for (const filePath of await toSourceFilePaths(entrySpecifiersFromManifest, dir, extensionGlobStr)) {
80
81
  inputs.add(toProductionEntry(filePath));
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ export const main = async (options) => {
24
24
  streamer.cast('Reading workspace configuration');
25
25
  const workspaces = await chief.getWorkspaces();
26
26
  const isGitIgnored = await getGitIgnoredHandler(options);
27
+ collector.setIgnoreIssues(chief.config.ignoreIssues);
27
28
  debugLogObject('*', 'Included workspaces', () => workspaces.map(w => w.pkgName));
28
29
  debugLogObject('*', 'Included workspace configs', () => workspaces.map(w => ({ pkgName: w.pkgName, name: w.name, config: w.config, ancestors: w.ancestors })));
29
30
  const { graph, entryPaths, analyzedFiles, unreferencedFiles, analyzeSourceFile } = await build({
@@ -0,0 +1,8 @@
1
+ import type { IsPluginEnabled } from '../../types/config.js';
2
+ declare const _default: {
3
+ title: string;
4
+ enablers: string[];
5
+ isEnabled: IsPluginEnabled;
6
+ entry: string[];
7
+ };
8
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { hasDependency } from '../../util/plugin.js';
2
+ const title = 'Danger';
3
+ const enablers = ['danger'];
4
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
5
+ const entry = ['dangerfile.{js,cjs,mjs,ts}'];
6
+ export default {
7
+ title,
8
+ enablers,
9
+ isEnabled,
10
+ entry,
11
+ };
@@ -82,6 +82,7 @@ export declare class DummyEleventyConfig {
82
82
  setLayoutsDirectory(): void;
83
83
  setFreezeReservedData(): void;
84
84
  addDateParsing(): void;
85
+ addBundle(): void;
85
86
  _uniqueId: {};
86
87
  events: {};
87
88
  benchmarkManager: {};
@@ -91,6 +91,7 @@ export class DummyEleventyConfig {
91
91
  setLayoutsDirectory() { }
92
92
  setFreezeReservedData() { }
93
93
  addDateParsing() { }
94
+ addBundle() { }
94
95
  _uniqueId = {};
95
96
  events = {};
96
97
  benchmarkManager = {};
@@ -141,6 +141,12 @@ export declare const Plugins: {
141
141
  entry: string[];
142
142
  resolveConfig: import("../types/config.js").ResolveConfig<import("./cypress/types.js").CypressConfig>;
143
143
  };
144
+ danger: {
145
+ title: string;
146
+ enablers: string[];
147
+ isEnabled: import("../types/config.js").IsPluginEnabled;
148
+ entry: string[];
149
+ };
144
150
  'dependency-cruiser': {
145
151
  title: string;
146
152
  enablers: string[];
@@ -17,6 +17,7 @@ import { default as createTypescriptApp } from './create-typescript-app/index.js
17
17
  import { default as cspell } from './cspell/index.js';
18
18
  import { default as cucumber } from './cucumber/index.js';
19
19
  import { default as cypress } from './cypress/index.js';
20
+ import { default as danger } from './danger/index.js';
20
21
  import { default as dependencyCruiser } from './dependency-cruiser/index.js';
21
22
  import { default as docusaurus } from './docusaurus/index.js';
22
23
  import { default as dotenv } from './dotenv/index.js';
@@ -132,6 +133,7 @@ export const Plugins = {
132
133
  cspell,
133
134
  cucumber,
134
135
  cypress,
136
+ danger,
135
137
  'dependency-cruiser': dependencyCruiser,
136
138
  docusaurus,
137
139
  dotenv,
@@ -10,18 +10,24 @@ const config = [
10
10
  ...toLilconfig('lint-staged'),
11
11
  ...toLilconfig('lintstaged'),
12
12
  ];
13
+ const resolveEntry = async (value) => {
14
+ if (Array.isArray(value))
15
+ return (await Promise.all(value.map(resolveEntry))).flat();
16
+ if (typeof value === 'function')
17
+ return [await value([])].flat().filter(item => typeof item === 'string');
18
+ return typeof value === 'string' ? [value] : [];
19
+ };
13
20
  const resolveConfig = async (config, options) => {
14
21
  if (options.isProduction)
15
22
  return [];
16
- if (typeof config === 'function')
17
- config = config();
18
- if (!config)
23
+ const cfg = typeof config === 'function' ? await config([]) : config;
24
+ if (!cfg)
19
25
  return [];
20
26
  const inputs = new Set();
21
- for (const [key, entry] of Object.entries(config)) {
27
+ for (const [key, entry] of Object.entries(cfg)) {
22
28
  if (key.startsWith('_'))
23
29
  continue;
24
- const scripts = [typeof entry === 'function' ? await entry([]) : entry].flat();
30
+ const scripts = await resolveEntry(entry);
25
31
  for (const id of options.getInputsFromScripts(scripts))
26
32
  inputs.add(id);
27
33
  }
@@ -1,5 +1,10 @@
1
- type Script = string | string[];
2
- type Entry = Script | ((filenames: string[]) => Script | Promise<Script>);
3
- type Config = Record<string, Entry>;
4
- export type LintStagedConfig = Config | (() => Config);
1
+ type SyncGenerateTask = (stagedFileNames: readonly string[]) => string | string[];
2
+ type AsyncGenerateTask = (stagedFileNames: readonly string[]) => Promise<string | string[]>;
3
+ type GenerateTask = SyncGenerateTask | AsyncGenerateTask;
4
+ type TaskFunction = {
5
+ title: string;
6
+ task: (stagedFileNames: readonly string[]) => void | Promise<void>;
7
+ };
8
+ export type Entry = string | TaskFunction | GenerateTask | (string | GenerateTask)[];
9
+ export type LintStagedConfig = Record<string, Entry> | GenerateTask;
5
10
  export {};
@@ -37,7 +37,7 @@ const args = {
37
37
  alias: { project: ['p'] },
38
38
  config: [['project', (p) => (p.endsWith('.json') ? p : join(p, 'tsconfig.json'))]],
39
39
  };
40
- const note = '[Whats up with that configurable tsconfig.json location?](/reference/faq#whats-up-with-that-configurable-tsconfigjson-location)';
40
+ const note = "[What's up with that configurable tsconfig.json location?](/reference/faq#whats-up-with-that-configurable-tsconfigjson-location)";
41
41
  export const docs = { note };
42
42
  export default {
43
43
  title,
@@ -97,6 +97,11 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
97
97
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
98
98
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
99
99
  }, z.core.$strip>]>>;
100
+ danger: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
101
+ config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
102
+ entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
103
+ project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
104
+ }, z.core.$strip>]>>;
100
105
  'dependency-cruiser': z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
101
106
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
102
107
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -668,6 +673,11 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
668
673
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
669
674
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
670
675
  }, z.core.$strip>]>>;
676
+ danger: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
677
+ config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
678
+ entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
679
+ project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
680
+ }, z.core.$strip>]>>;
671
681
  'dependency-cruiser': z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
672
682
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
673
683
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -1147,6 +1157,7 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
1147
1157
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1148
1158
  paths: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>>>;
1149
1159
  ignore: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1160
+ ignoreFiles: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1150
1161
  ignoreBinaries: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniCustom<RegExp, RegExp>]>>>;
1151
1162
  ignoreDependencies: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniCustom<RegExp, RegExp>]>>>;
1152
1163
  ignoreMembers: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniCustom<RegExp, RegExp>]>>>;
@@ -1165,6 +1176,7 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
1165
1176
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1166
1177
  paths: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>>>;
1167
1178
  ignore: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1179
+ ignoreFiles: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1168
1180
  ignoreBinaries: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniCustom<RegExp, RegExp>]>>>;
1169
1181
  ignoreDependencies: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniCustom<RegExp, RegExp>]>>>;
1170
1182
  ignoreMembers: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniCustom<RegExp, RegExp>]>>>;
@@ -1177,6 +1189,7 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
1177
1189
  member: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
1178
1190
  type: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
1179
1191
  }, z.core.$strict>]>>;
1192
+ ignoreIssues: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniUnion<readonly [z.ZodMiniLiteral<"files">, z.ZodMiniLiteral<"dependencies">, z.ZodMiniLiteral<"devDependencies">, z.ZodMiniLiteral<"optionalPeerDependencies">, z.ZodMiniLiteral<"unlisted">, z.ZodMiniLiteral<"binaries">, z.ZodMiniLiteral<"unresolved">, z.ZodMiniLiteral<"exports">, z.ZodMiniLiteral<"types">, z.ZodMiniLiteral<"nsExports">, z.ZodMiniLiteral<"nsTypes">, z.ZodMiniLiteral<"duplicates">, z.ZodMiniLiteral<"enumMembers">, z.ZodMiniLiteral<"classMembers">]>>>>;
1180
1193
  ignoreWorkspaces: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
1181
1194
  includeEntryExports: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
1182
1195
  compilers: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnion<readonly [z.ZodMiniUnion<readonly [z.ZodMiniLiteral<true>, z.ZodMiniCustom<SyncCompiler, SyncCompiler>]>, z.ZodMiniCustom<AsyncCompiler, AsyncCompiler>]>>>;
@@ -32,6 +32,7 @@ const ignoreExportsUsedInFileObjectSchema = z.strictObject({
32
32
  type: z.optional(z.boolean()),
33
33
  });
34
34
  const ignoreExportsUsedInFileSchema = z.union([z.boolean(), ignoreExportsUsedInFileObjectSchema]);
35
+ const ignoreIssuesSchema = z.record(z.string(), z.array(issueTypeSchema));
35
36
  const rootConfigurationSchema = z.object({
36
37
  $schema: z.optional(z.string()),
37
38
  rules: z.optional(rulesSchema),
@@ -39,11 +40,13 @@ const rootConfigurationSchema = z.object({
39
40
  project: z.optional(globSchema),
40
41
  paths: z.optional(pathsSchema),
41
42
  ignore: z.optional(globSchema),
43
+ ignoreFiles: z.optional(globSchema),
42
44
  ignoreBinaries: z.optional(stringOrRegexSchema),
43
45
  ignoreDependencies: z.optional(stringOrRegexSchema),
44
46
  ignoreMembers: z.optional(stringOrRegexSchema),
45
47
  ignoreUnresolved: z.optional(stringOrRegexSchema),
46
48
  ignoreExportsUsedInFile: z.optional(ignoreExportsUsedInFileSchema),
49
+ ignoreIssues: z.optional(ignoreIssuesSchema),
47
50
  ignoreWorkspaces: z.optional(z.array(z.string())),
48
51
  includeEntryExports: z.optional(z.boolean()),
49
52
  compilers: z.optional(compilersSchema),
@@ -61,6 +64,7 @@ const baseWorkspaceConfigurationSchema = z.object({
61
64
  project: z.optional(globSchema),
62
65
  paths: z.optional(pathsSchema),
63
66
  ignore: z.optional(globSchema),
67
+ ignoreFiles: z.optional(globSchema),
64
68
  ignoreBinaries: z.optional(stringOrRegexSchema),
65
69
  ignoreDependencies: z.optional(stringOrRegexSchema),
66
70
  ignoreMembers: z.optional(stringOrRegexSchema),
@@ -101,6 +101,11 @@ export declare const pluginsSchema: z.ZodMiniObject<{
101
101
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
102
102
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
103
103
  }, z.core.$strip>]>;
104
+ danger: z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
105
+ config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
106
+ entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
107
+ project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
108
+ }, z.core.$strip>]>;
104
109
  'dependency-cruiser': z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
105
110
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
106
111
  entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -29,6 +29,7 @@ export const pluginsSchema = z.object({
29
29
  cspell: pluginSchema,
30
30
  cucumber: pluginSchema,
31
31
  cypress: pluginSchema,
32
+ danger: pluginSchema,
32
33
  'dependency-cruiser': pluginSchema,
33
34
  docusaurus: pluginSchema,
34
35
  dotenv: pluginSchema,
@@ -1,2 +1,2 @@
1
- export type PluginName = 'angular' | 'astro' | 'ava' | 'babel' | 'biome' | 'bumpp' | 'bun' | 'c8' | 'capacitor' | 'changelogen' | 'changelogithub' | 'changesets' | 'commitizen' | 'commitlint' | 'convex' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'dependency-cruiser' | 'docusaurus' | 'dotenv' | 'drizzle' | 'eleventy' | 'eslint' | 'expo' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'hardhat' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'ladle' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lockfile-lint' | 'lost-pixel' | 'markdownlint' | 'metro' | 'mocha' | 'moonrepo' | 'msw' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'node' | 'node-modules-inspector' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nx' | 'nyc' | 'oclif' | 'oxlint' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'pnpm' | 'postcss' | 'preconstruct' | 'prettier' | 'prisma' | 'react-cosmos' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rollup' | 'rsbuild' | 'rslib' | 'rspack' | 'rstest' | 'semantic-release' | 'sentry' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'svgo' | 'syncpack' | 'tailwind' | 'travis' | 'ts-node' | 'tsdown' | 'tsup' | 'tsx' | 'typedoc' | 'typescript' | 'unbuild' | 'unocss' | 'vercel-og' | 'vike' | 'vite' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'xo' | 'yarn' | 'yorkie';
2
- export declare const pluginNames: readonly ["angular", "astro", "ava", "babel", "biome", "bumpp", "bun", "c8", "capacitor", "changelogen", "changelogithub", "changesets", "commitizen", "commitlint", "convex", "create-typescript-app", "cspell", "cucumber", "cypress", "dependency-cruiser", "docusaurus", "dotenv", "drizzle", "eleventy", "eslint", "expo", "gatsby", "github-action", "github-actions", "glob", "graphql-codegen", "hardhat", "husky", "i18next-parser", "jest", "karma", "ladle", "lefthook", "lint-staged", "linthtml", "lockfile-lint", "lost-pixel", "markdownlint", "metro", "mocha", "moonrepo", "msw", "nano-staged", "nest", "netlify", "next", "node", "node-modules-inspector", "nodemon", "npm-package-json-lint", "nuxt", "nx", "nyc", "oclif", "oxlint", "playwright", "playwright-ct", "playwright-test", "plop", "pnpm", "postcss", "preconstruct", "prettier", "prisma", "react-cosmos", "react-router", "relay", "release-it", "remark", "remix", "rollup", "rsbuild", "rslib", "rspack", "rstest", "semantic-release", "sentry", "simple-git-hooks", "size-limit", "sst", "starlight", "storybook", "stryker", "stylelint", "svelte", "svgo", "syncpack", "tailwind", "travis", "ts-node", "tsdown", "tsup", "tsx", "typedoc", "typescript", "unbuild", "unocss", "vercel-og", "vike", "vite", "vitest", "vue", "webdriver-io", "webpack", "wireit", "wrangler", "xo", "yarn", "yorkie"];
1
+ export type PluginName = 'angular' | 'astro' | 'ava' | 'babel' | 'biome' | 'bumpp' | 'bun' | 'c8' | 'capacitor' | 'changelogen' | 'changelogithub' | 'changesets' | 'commitizen' | 'commitlint' | 'convex' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'danger' | 'dependency-cruiser' | 'docusaurus' | 'dotenv' | 'drizzle' | 'eleventy' | 'eslint' | 'expo' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'hardhat' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'ladle' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lockfile-lint' | 'lost-pixel' | 'markdownlint' | 'metro' | 'mocha' | 'moonrepo' | 'msw' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'node' | 'node-modules-inspector' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nx' | 'nyc' | 'oclif' | 'oxlint' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'pnpm' | 'postcss' | 'preconstruct' | 'prettier' | 'prisma' | 'react-cosmos' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rollup' | 'rsbuild' | 'rslib' | 'rspack' | 'rstest' | 'semantic-release' | 'sentry' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'svgo' | 'syncpack' | 'tailwind' | 'travis' | 'ts-node' | 'tsdown' | 'tsup' | 'tsx' | 'typedoc' | 'typescript' | 'unbuild' | 'unocss' | 'vercel-og' | 'vike' | 'vite' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'xo' | 'yarn' | 'yorkie';
2
+ export declare const pluginNames: readonly ["angular", "astro", "ava", "babel", "biome", "bumpp", "bun", "c8", "capacitor", "changelogen", "changelogithub", "changesets", "commitizen", "commitlint", "convex", "create-typescript-app", "cspell", "cucumber", "cypress", "danger", "dependency-cruiser", "docusaurus", "dotenv", "drizzle", "eleventy", "eslint", "expo", "gatsby", "github-action", "github-actions", "glob", "graphql-codegen", "hardhat", "husky", "i18next-parser", "jest", "karma", "ladle", "lefthook", "lint-staged", "linthtml", "lockfile-lint", "lost-pixel", "markdownlint", "metro", "mocha", "moonrepo", "msw", "nano-staged", "nest", "netlify", "next", "node", "node-modules-inspector", "nodemon", "npm-package-json-lint", "nuxt", "nx", "nyc", "oclif", "oxlint", "playwright", "playwright-ct", "playwright-test", "plop", "pnpm", "postcss", "preconstruct", "prettier", "prisma", "react-cosmos", "react-router", "relay", "release-it", "remark", "remix", "rollup", "rsbuild", "rslib", "rspack", "rstest", "semantic-release", "sentry", "simple-git-hooks", "size-limit", "sst", "starlight", "storybook", "stryker", "stylelint", "svelte", "svgo", "syncpack", "tailwind", "travis", "ts-node", "tsdown", "tsup", "tsx", "typedoc", "typescript", "unbuild", "unocss", "vercel-og", "vike", "vite", "vitest", "vue", "webdriver-io", "webpack", "wireit", "wrangler", "xo", "yarn", "yorkie"];
@@ -18,6 +18,7 @@ export const pluginNames = [
18
18
  'cspell',
19
19
  'cucumber',
20
20
  'cypress',
21
+ 'danger',
21
22
  'dependency-cruiser',
22
23
  'docusaurus',
23
24
  'dotenv',
@@ -5,7 +5,7 @@ import type { knipConfigurationSchema } from '../schema/configuration.js';
5
5
  import type { pluginSchema } from '../schema/plugins.js';
6
6
  import type { Input } from '../util/input.js';
7
7
  import type { Args } from './args.js';
8
- import type { SymbolType } from './issues.js';
8
+ import type { IssueType, SymbolType } from './issues.js';
9
9
  import type { Tags } from './options.js';
10
10
  import type { PluginName } from './PluginNames.js';
11
11
  import type { PackageJson } from './package-json.js';
@@ -25,6 +25,7 @@ export type RawPluginConfiguration = z.infer<typeof pluginSchema>;
25
25
  export type IgnorePatterns = (string | RegExp)[];
26
26
  type IgnorableExport = Exclude<SymbolType, SymbolType.UNKNOWN>;
27
27
  export type IgnoreExportsUsedInFile = boolean | Partial<Record<IgnorableExport, boolean>>;
28
+ export type IgnoreIssues = Record<string, IssueType[]>;
28
29
  export type GetImportsAndExportsOptions = {
29
30
  skipTypeOnly: boolean;
30
31
  isFixExports: boolean;
@@ -34,9 +35,11 @@ export type GetImportsAndExportsOptions = {
34
35
  };
35
36
  export interface Configuration {
36
37
  ignore: NormalizedGlob;
38
+ ignoreFiles: NormalizedGlob;
37
39
  ignoreBinaries: IgnorePatterns;
38
40
  ignoreDependencies: IgnorePatterns;
39
41
  ignoreExportsUsedInFile: IgnoreExportsUsedInFile;
42
+ ignoreIssues?: IgnoreIssues;
40
43
  ignoreMembers: IgnorePatterns;
41
44
  ignoreUnresolved: IgnorePatterns;
42
45
  ignoreWorkspaces: string[];
@@ -56,6 +59,7 @@ interface BaseWorkspaceConfiguration {
56
59
  project: NormalizedGlob;
57
60
  paths: Record<string, string[]>;
58
61
  ignore: NormalizedGlob;
62
+ ignoreFiles: NormalizedGlob;
59
63
  isIncludeEntryExports: boolean;
60
64
  }
61
65
  type PluginConfiguration = EnsuredPluginConfiguration | boolean;
@@ -34,7 +34,7 @@ export declare const getLineAndCharacterOfPosition: (node: ts.Node, pos: number)
34
34
  };
35
35
  export declare const getAccessMembers: (typeChecker: ts.TypeChecker, node: ts.Identifier) => string[];
36
36
  export declare const isDestructuring: (node: ts.Node) => boolean;
37
- export declare const getDestructuredIds: (name: ts.ObjectBindingPattern) => string[];
37
+ export declare const getDestructuredNames: (name: ts.ObjectBindingPattern) => [string[], boolean];
38
38
  export declare const isConsiderReferencedNS: (node: ts.Identifier) => boolean;
39
39
  export declare const isObjectEnumerationCallExpressionArgument: (node: ts.Identifier) => boolean;
40
40
  export declare const isInForIteration: (node: ts.Node) => boolean;
@@ -169,7 +169,18 @@ export const isDestructuring = (node) => node.parent &&
169
169
  ts.isVariableDeclaration(node.parent) &&
170
170
  ts.isVariableDeclarationList(node.parent.parent) &&
171
171
  ts.isObjectBindingPattern(node.parent.name);
172
- export const getDestructuredIds = (name) => name.elements.map(element => element.name.getText());
172
+ export const getDestructuredNames = (name) => {
173
+ const members = [];
174
+ let hasSpread = false;
175
+ for (const element of name.elements) {
176
+ if (element.dotDotDotToken) {
177
+ hasSpread = true;
178
+ break;
179
+ }
180
+ members.push(element.name.getText());
181
+ }
182
+ return [members, hasSpread];
183
+ };
173
184
  export const isConsiderReferencedNS = (node) => ts.isPropertyAssignment(node.parent) ||
174
185
  ts.isShorthandPropertyAssignment(node.parent) ||
175
186
  (ts.isCallExpression(node.parent) && node.parent.arguments.includes(node)) ||
@@ -6,7 +6,7 @@ import { getPackageNameFromFilePath, isStartsLikePackageName, sanitizeSpecifier
6
6
  import { timerify } from '../util/Performance.js';
7
7
  import { isInNodeModules } from '../util/path.js';
8
8
  import { shouldIgnore } from '../util/tag.js';
9
- import { getAccessMembers, getDestructuredIds, getJSDocTags, getLineAndCharacterOfPosition, getTypeRef, isAccessExpression, isConsiderReferencedNS, isDestructuring, isImportSpecifier, isInForIteration, isObjectEnumerationCallExpressionArgument, isReferencedInExport, } from './ast-helpers.js';
9
+ import { getAccessMembers, getDestructuredNames, getJSDocTags, getLineAndCharacterOfPosition, getTypeRef, isAccessExpression, isConsiderReferencedNS, isDestructuring, isImportSpecifier, isInForIteration, isObjectEnumerationCallExpressionArgument, isReferencedInExport, } from './ast-helpers.js';
10
10
  import { findInternalReferences, isType } from './find-internal-references.js';
11
11
  import getDynamicImportVisitors from './visitors/dynamic-imports/index.js';
12
12
  import getExportVisitors from './visitors/exports/index.js';
@@ -259,9 +259,14 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
259
259
  if (ts.isPropertyAccessExpression(node.parent)) {
260
260
  const ns = String(symbol.escapedName);
261
261
  const key = String(node.parent.name.escapedText);
262
- const members = getDestructuredIds(node.parent.parent.name).map(n => `${key}.${n}`);
263
- addNsMemberRefs(imports, ns, key);
264
- addNsMemberRefs(imports, ns, members);
262
+ const [members, hasSpread] = getDestructuredNames(node.parent.parent.name);
263
+ if (hasSpread)
264
+ imports.refs.add(id);
265
+ else {
266
+ const ids = members.map(id => `${key}.${id}`);
267
+ addNsMemberRefs(imports, ns, key);
268
+ addNsMemberRefs(imports, ns, ids);
269
+ }
265
270
  }
266
271
  }
267
272
  else {
@@ -270,8 +275,11 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
270
275
  }
271
276
  }
272
277
  else if (isDestructuring(node)) {
273
- const members = getDestructuredIds(node.parent.name);
274
- addNsMemberRefs(imports, id, members);
278
+ const [members, hasSpread] = getDestructuredNames(node.parent.name);
279
+ if (hasSpread)
280
+ imports.refs.add(id);
281
+ else
282
+ addNsMemberRefs(imports, id, members);
275
283
  }
276
284
  else {
277
285
  const typeRef = getTypeRef(node);
@@ -133,6 +133,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
133
133
  entry?: string | string[] | undefined;
134
134
  project?: string | string[] | undefined;
135
135
  } | undefined;
136
+ danger?: string | boolean | string[] | {
137
+ config?: string | string[] | undefined;
138
+ entry?: string | string[] | undefined;
139
+ project?: string | string[] | undefined;
140
+ } | undefined;
136
141
  'dependency-cruiser'?: string | boolean | string[] | {
137
142
  config?: string | string[] | undefined;
138
143
  entry?: string | string[] | undefined;
@@ -704,6 +709,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
704
709
  entry?: string | string[] | undefined;
705
710
  project?: string | string[] | undefined;
706
711
  } | undefined;
712
+ danger?: string | boolean | string[] | {
713
+ config?: string | string[] | undefined;
714
+ entry?: string | string[] | undefined;
715
+ project?: string | string[] | undefined;
716
+ } | undefined;
707
717
  'dependency-cruiser'?: string | boolean | string[] | {
708
718
  config?: string | string[] | undefined;
709
719
  entry?: string | string[] | undefined;
@@ -1183,6 +1193,7 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1183
1193
  project?: string | string[] | undefined;
1184
1194
  paths?: Record<string, string[]> | undefined;
1185
1195
  ignore?: string | string[] | undefined;
1196
+ ignoreFiles?: string | string[] | undefined;
1186
1197
  ignoreBinaries?: (string | RegExp)[] | undefined;
1187
1198
  ignoreDependencies?: (string | RegExp)[] | undefined;
1188
1199
  ignoreMembers?: (string | RegExp)[] | undefined;
@@ -1197,6 +1208,7 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1197
1208
  project?: string | string[] | undefined;
1198
1209
  paths?: Record<string, string[]> | undefined;
1199
1210
  ignore?: string | string[] | undefined;
1211
+ ignoreFiles?: string | string[] | undefined;
1200
1212
  ignoreBinaries?: (string | RegExp)[] | undefined;
1201
1213
  ignoreDependencies?: (string | RegExp)[] | undefined;
1202
1214
  ignoreMembers?: (string | RegExp)[] | undefined;
@@ -1209,6 +1221,7 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1209
1221
  member?: boolean | undefined;
1210
1222
  type?: boolean | undefined;
1211
1223
  } | undefined;
1224
+ ignoreIssues?: Record<string, ("files" | "dependencies" | "devDependencies" | "optionalPeerDependencies" | "unlisted" | "binaries" | "unresolved" | "exports" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers")[]> | undefined;
1212
1225
  ignoreWorkspaces?: string[] | undefined;
1213
1226
  includeEntryExports?: boolean | undefined;
1214
1227
  compilers?: Record<string, true | ((filename: string, contents: string) => string) | ((filename: string, contents: string) => Promise<string>)> | undefined;
package/dist/util/fs.d.ts CHANGED
@@ -3,7 +3,8 @@ export declare const isFile: (filePath: string) => boolean;
3
3
  export declare const findFile: (workingDir: string, fileName: string) => string | undefined;
4
4
  export declare const loadFile: (filePath: string) => Promise<string>;
5
5
  export declare const loadJSON: (filePath: string) => Promise<any>;
6
+ export declare const loadJSONC: (filePath: string) => Promise<any>;
6
7
  export declare const loadYAML: (filePath: string) => Promise<unknown>;
7
8
  export declare const loadTOML: (filePath: string) => Promise<import("smol-toml").TomlTable>;
8
- export declare const parseJSON: (filePath: string, contents: string) => Promise<any>;
9
+ export declare const parseJSONC: (filePath: string, contents: string) => Promise<any>;
9
10
  export declare const parseYAML: (contents: string) => unknown;
package/dist/util/fs.js CHANGED
@@ -4,7 +4,7 @@ import yaml from 'js-yaml';
4
4
  import { parse as parseTOML } from 'smol-toml';
5
5
  import stripJsonComments from 'strip-json-comments';
6
6
  import { LoaderError } from './errors.js';
7
- import { join } from './path.js';
7
+ import { extname, join } from './path.js';
8
8
  export const isDirectory = (filePath) => {
9
9
  try {
10
10
  return statSync(filePath).isDirectory();
@@ -36,7 +36,16 @@ export const loadFile = async (filePath) => {
36
36
  };
37
37
  export const loadJSON = async (filePath) => {
38
38
  const contents = await loadFile(filePath);
39
- return parseJSON(filePath, contents);
39
+ try {
40
+ return JSON.parse(contents);
41
+ }
42
+ catch {
43
+ return parseJSONC(filePath, contents);
44
+ }
45
+ };
46
+ export const loadJSONC = async (filePath) => {
47
+ const contents = await loadFile(filePath);
48
+ return parseJSONC(filePath, contents);
40
49
  };
41
50
  export const loadYAML = async (filePath) => {
42
51
  const contents = await loadFile(filePath);
@@ -46,12 +55,13 @@ export const loadTOML = async (filePath) => {
46
55
  const contents = await loadFile(filePath);
47
56
  return parseTOML(contents);
48
57
  };
49
- export const parseJSON = async (filePath, contents) => {
58
+ export const parseJSONC = async (filePath, contents) => {
50
59
  try {
51
- return JSON.parse(stripJsonComments(contents, { trailingCommas: true }));
60
+ return JSON.parse(stripJsonComments(contents, { trailingCommas: true, whitespace: false }));
52
61
  }
53
62
  catch (error) {
54
- throw new LoaderError(`Error parsing ${filePath}`, { cause: error });
63
+ const message = `Error parsing ${filePath} ${extname(filePath) === '.json5' ? 'JSON5 features beyond comments and trailing commas are not fully supported. Consider converting to .jsonc format.' : ''}`;
64
+ throw new LoaderError(message, { cause: error });
55
65
  }
56
66
  };
57
67
  export const parseYAML = (contents) => {
@@ -154,14 +154,15 @@ export async function glob(_patterns, options) {
154
154
  }
155
155
  if (willCache)
156
156
  cachedGlobIgnores.set(options.dir, compact(_ignore));
157
- const ignorePatterns = (cachedIgnores || _ignore).concat(negatedPatterns);
157
+ const ignorePatterns = (cachedIgnores || _ignore).concat(negatedPatterns.map(pattern => pattern.slice(1)));
158
158
  const { dir, label, ...fgOptions } = { ...options, ignore: ignorePatterns };
159
159
  const paths = await fg.glob(patterns, fgOptions);
160
- const name = relative(options.cwd, dir) || ROOT_WORKSPACE_NAME;
161
- debugLogObject(name, label ? `Finding ${label}` : 'Finding paths', () => ({
160
+ debugLogObject(relative(options.cwd, dir) || ROOT_WORKSPACE_NAME, label ? `Finding ${label}` : 'Finding paths', () => ({
162
161
  patterns,
163
162
  ...fgOptions,
164
- ignore: hasCache ? `// using cache from ${name}` : ignorePatterns,
163
+ ignore: hasCache && ignorePatterns.length === (cachedIgnores || _ignore).length
164
+ ? `// using cache from previous glob cwd: ${fgOptions.cwd}`
165
+ : ignorePatterns,
165
166
  paths,
166
167
  }));
167
168
  return paths;
@@ -1,5 +1,5 @@
1
1
  import { LoaderError } from './errors.js';
2
- import { loadFile, loadJSON, loadTOML, loadYAML, parseJSON, parseYAML } from './fs.js';
2
+ import { loadFile, loadJSON, loadJSONC, loadTOML, loadYAML, parseJSONC, parseYAML } from './fs.js';
3
3
  import { jiti } from './jiti.js';
4
4
  import { timerify } from './Performance.js';
5
5
  import { extname, isInternal } from './path.js';
@@ -12,7 +12,7 @@ const load = async (filePath) => {
12
12
  return parseYAML(contents);
13
13
  }
14
14
  catch {
15
- return parseJSON(filePath, contents);
15
+ return parseJSONC(filePath, contents);
16
16
  }
17
17
  }
18
18
  if (ext === '.yaml' || ext === '.yml') {
@@ -21,9 +21,12 @@ const load = async (filePath) => {
21
21
  if (ext === '' && isInternal(filePath)) {
22
22
  return await loadFile(filePath);
23
23
  }
24
- if (ext === '.json' || ext === '.jsonc' || ext === '.json5') {
24
+ if (ext === '.json') {
25
25
  return await loadJSON(filePath);
26
26
  }
27
+ if (ext === '.jsonc' || ext === '.json5') {
28
+ return await loadJSONC(filePath);
29
+ }
27
30
  if (typeof Bun !== 'undefined') {
28
31
  const imported = await import(filePath);
29
32
  return imported.default ?? imported;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.64.3";
1
+ export declare const version = "5.66.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.64.3';
1
+ export const version = '5.66.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.64.3",
3
+ "version": "5.66.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": {
package/schema.json CHANGED
@@ -22,27 +22,32 @@
22
22
  ],
23
23
  "properties": {
24
24
  "ignoreBinaries": {
25
- "title": "Binaries to ignore (regex allowed)",
25
+ "title": "Binaries to exclude from the report (regex allowed)",
26
26
  "examples": ["rm", "docker-compose", "curl"],
27
27
  "$ref": "#/definitions/list"
28
28
  },
29
29
  "ignoreDependencies": {
30
- "title": "Dependencies from package.json to ignore (regex allowed)",
30
+ "title": "Dependencies to exclude from the report (regex allowed)",
31
+ "examples": ["husky", "lint-staged"],
32
+ "$ref": "#/definitions/list"
33
+ },
34
+ "ignoreFiles": {
35
+ "title": "Unused files to exclude from the report",
31
36
  "examples": ["husky", "lint-staged"],
32
37
  "$ref": "#/definitions/list"
33
38
  },
34
39
  "ignoreMembers": {
35
- "title": "Class and enum members to ignore (regex allowed)",
40
+ "title": "Class and enum members to exclude from the report (regex allowed)",
36
41
  "examples": ["render", "on.*"],
37
42
  "$ref": "#/definitions/list"
38
43
  },
39
44
  "ignoreUnresolved": {
40
- "title": "Unresolved imports to ignore (regex allowed)",
45
+ "title": "Unresolved imports to exclude from the report (regex allowed)",
41
46
  "examples": ["#/virtual"],
42
47
  "$ref": "#/definitions/list"
43
48
  },
44
49
  "ignoreWorkspaces": {
45
- "title": "Workspaces to ignore",
50
+ "title": "Workspaces to exclude from the report",
46
51
  "examples": ["packages/ignore-me"],
47
52
  "$ref": "#/definitions/list"
48
53
  },
@@ -98,6 +103,19 @@
98
103
  }
99
104
  ]
100
105
  },
106
+ "ignoreIssues": {
107
+ "title": " Ignore specific issue types for specific file patterns",
108
+ "examples": [
109
+ {
110
+ "src/generated/**": ["exports", "types"],
111
+ "**/*.generated.ts": ["exports", "classMembers"]
112
+ }
113
+ ],
114
+ "type": "object",
115
+ "additionalProperties": {
116
+ "$ref": "#/definitions/issueTypes"
117
+ }
118
+ },
101
119
  "includeEntryExports": {
102
120
  "title": "Include entry files when reporting unused exports",
103
121
  "type": "boolean"
@@ -240,23 +258,29 @@
240
258
  "$ref": "#/definitions/paths"
241
259
  },
242
260
  "ignore": {
243
- "title": "Files to ignore in the analysis.",
244
- "example": ["**/fixtures", "mocks"],
261
+ "title": "Files to exclude from the report (any issue type)",
262
+ "example": ["**/fixtures/**", "mocks/**"],
263
+ "default": [],
264
+ "$ref": "#/definitions/globPatterns"
265
+ },
266
+ "ignoreFiles": {
267
+ "title": "Unused files to exclude the report",
268
+ "example": ["**/fixtures/**", "mocks/**"],
245
269
  "default": [],
246
270
  "$ref": "#/definitions/globPatterns"
247
271
  },
248
272
  "ignoreBinaries": {
249
- "title": "Binaries to ignore (regex allowed)",
273
+ "title": "Binaries to exclude from the report (regex allowed)",
250
274
  "examples": ["rm", "docker-compose", "curl"],
251
275
  "$ref": "#/definitions/list"
252
276
  },
253
277
  "ignoreDependencies": {
254
- "title": "Dependencies from package.json to ignore (regex allowed)",
278
+ "title": "Dependencies to exclude from the report (regex allowed)",
255
279
  "examples": ["husky", "lint-staged"],
256
280
  "$ref": "#/definitions/list"
257
281
  },
258
282
  "ignoreUnresolved": {
259
- "title": "Unresolved imports to ignore (regex allowed)",
283
+ "title": "Unresolved imports to exclude from the report (regex allowed)",
260
284
  "examples": ["#/virtual"],
261
285
  "$ref": "#/definitions/list"
262
286
  },
@@ -375,6 +399,10 @@
375
399
  "title": "Cypress plugin configuration (https://knip.dev/reference/plugins/cypress)",
376
400
  "$ref": "#/definitions/plugin"
377
401
  },
402
+ "danger": {
403
+ "title": "danger plugin configuration (https://knip.dev/reference/plugins/danger)",
404
+ "$ref": "#/definitions/plugin"
405
+ },
378
406
  "dependency-cruiser": {
379
407
  "title": "dependency-cruiser plugin configuration (https://knip.dev/reference/plugins/dependency-cruiser)",
380
408
  "$ref": "#/definitions/plugin"