knip 6.43.0 → 6.44.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 (155) hide show
  1. package/dist/CacheConsultant.d.ts +1 -0
  2. package/dist/CacheConsultant.js +2 -0
  3. package/dist/CatalogCounselor.d.ts +1 -3
  4. package/dist/CatalogCounselor.js +18 -15
  5. package/dist/ConfigurationChief.d.ts +24 -0
  6. package/dist/DependencyDeputy.d.ts +2 -1
  7. package/dist/DependencyDeputy.js +9 -4
  8. package/dist/IssueCollector.js +1 -0
  9. package/dist/ProjectPrincipal.d.ts +3 -2
  10. package/dist/ProjectPrincipal.js +32 -10
  11. package/dist/WorkspaceWorker.d.ts +5 -2
  12. package/dist/WorkspaceWorker.js +20 -7
  13. package/dist/binaries/util.js +2 -1
  14. package/dist/cli.js +6 -1
  15. package/dist/compilers/index.d.ts +5 -0
  16. package/dist/compilers/index.js +1 -1
  17. package/dist/constants.d.ts +1 -0
  18. package/dist/constants.js +1 -0
  19. package/dist/graph/analyze.js +3 -2
  20. package/dist/graph/build.d.ts +2 -0
  21. package/dist/graph/build.js +37 -22
  22. package/dist/graph-explorer/cache.d.ts +2 -1
  23. package/dist/graph-explorer/cache.js +5 -1
  24. package/dist/graph-explorer/explorer.d.ts +3 -5
  25. package/dist/graph-explorer/explorer.js +24 -3
  26. package/dist/plugins/biome/index.js +1 -1
  27. package/dist/plugins/cspell/index.js +1 -0
  28. package/dist/plugins/dependency-cruiser/index.js +2 -2
  29. package/dist/plugins/docusaurus/helpers.js +4 -4
  30. package/dist/plugins/electron-vite/index.js +2 -2
  31. package/dist/plugins/expressive-code/index.d.ts +1 -1
  32. package/dist/plugins/expressive-code/index.js +2 -2
  33. package/dist/plugins/gatsby/index.js +6 -6
  34. package/dist/plugins/gatsby/types.d.ts +1 -1
  35. package/dist/plugins/github-actions/index.js +1 -1
  36. package/dist/plugins/i18next-parser/index.js +2 -2
  37. package/dist/plugins/index.d.ts +5 -1
  38. package/dist/plugins/index.js +8 -0
  39. package/dist/plugins/jasmine/index.js +2 -2
  40. package/dist/plugins/karma/index.js +4 -4
  41. package/dist/plugins/kysely-codegen/index.d.ts +3 -0
  42. package/dist/plugins/kysely-codegen/index.js +20 -0
  43. package/dist/plugins/lefthook/index.js +2 -2
  44. package/dist/plugins/lingui/index.d.ts +3 -0
  45. package/dist/plugins/lingui/index.js +16 -0
  46. package/dist/plugins/lockfile-lint/index.js +2 -2
  47. package/dist/plugins/lost-pixel/index.js +2 -2
  48. package/dist/plugins/lunaria/index.js +2 -2
  49. package/dist/plugins/marko/index.js +5 -6
  50. package/dist/plugins/mastra/index.d.ts +3 -0
  51. package/dist/plugins/mastra/index.js +57 -0
  52. package/dist/plugins/mcp/index.js +1 -1
  53. package/dist/plugins/mise/index.js +0 -3
  54. package/dist/plugins/mocha/index.js +42 -3
  55. package/dist/plugins/mocha/types.d.ts +1 -0
  56. package/dist/plugins/nx/index.js +3 -8
  57. package/dist/plugins/nyc/index.js +1 -1
  58. package/dist/plugins/openapi-ts/index.js +2 -2
  59. package/dist/plugins/oxfmt/index.js +2 -2
  60. package/dist/plugins/playwright/index.js +6 -11
  61. package/dist/plugins/pnpm/index.js +2 -4
  62. package/dist/plugins/purgecss/index.d.ts +3 -0
  63. package/dist/plugins/purgecss/index.js +16 -0
  64. package/dist/plugins/railway/index.js +1 -4
  65. package/dist/plugins/remix/index.js +1 -1
  66. package/dist/plugins/rstest/index.js +2 -2
  67. package/dist/plugins/serverless-framework/index.js +1 -1
  68. package/dist/plugins/storybook/index.js +5 -5
  69. package/dist/plugins/sveltekit/resolveFromAST.js +1 -1
  70. package/dist/plugins/syncpack/index.js +2 -2
  71. package/dist/plugins/tanstack-router/index.js +3 -2
  72. package/dist/plugins/taskfile/index.js +4 -7
  73. package/dist/plugins/textlint/helpers.js +2 -2
  74. package/dist/plugins/typescript/index.js +7 -3
  75. package/dist/plugins/unocss/index.js +2 -2
  76. package/dist/plugins/vite-plugin-pwa/index.js +1 -4
  77. package/dist/plugins/vite-plugin-pwa/resolveFromAST.d.ts +0 -2
  78. package/dist/plugins/vite-plugin-pwa/resolveFromAST.js +2 -2
  79. package/dist/plugins/vite-pwa-assets-generator/index.js +2 -2
  80. package/dist/plugins/vitest/helpers.js +4 -7
  81. package/dist/plugins/vitest/index.js +1 -1
  82. package/dist/plugins/webpack/index.js +4 -2
  83. package/dist/plugins/yarn/index.js +2 -4
  84. package/dist/reporters/codeclimate.d.ts +2 -2
  85. package/dist/reporters/codeclimate.js +2 -4
  86. package/dist/reporters/codeowners.d.ts +2 -2
  87. package/dist/reporters/codeowners.js +9 -9
  88. package/dist/reporters/compact.d.ts +2 -2
  89. package/dist/reporters/compact.js +8 -7
  90. package/dist/reporters/cycles.d.ts +2 -2
  91. package/dist/reporters/cycles.js +7 -6
  92. package/dist/reporters/disclosure.d.ts +2 -2
  93. package/dist/reporters/disclosure.js +6 -4
  94. package/dist/reporters/github-actions.d.ts +2 -2
  95. package/dist/reporters/github-actions.js +7 -5
  96. package/dist/reporters/index.d.ts +10 -10
  97. package/dist/reporters/json.d.ts +2 -2
  98. package/dist/reporters/json.js +2 -4
  99. package/dist/reporters/markdown.d.ts +2 -2
  100. package/dist/reporters/markdown.js +11 -9
  101. package/dist/reporters/sarif.d.ts +2 -2
  102. package/dist/reporters/sarif.js +2 -3
  103. package/dist/reporters/symbols.d.ts +2 -2
  104. package/dist/reporters/symbols.js +6 -4
  105. package/dist/run.d.ts +1 -1
  106. package/dist/run.js +3 -10
  107. package/dist/schema/configuration.d.ts +60 -0
  108. package/dist/schema/plugins.d.ts +20 -0
  109. package/dist/schema/plugins.js +4 -0
  110. package/dist/session/configuration.d.ts +12 -0
  111. package/dist/session/configuration.js +43 -0
  112. package/dist/session/incremental.d.ts +54 -0
  113. package/dist/session/incremental.js +49 -0
  114. package/dist/session/session.d.ts +1 -1
  115. package/dist/session/session.js +62 -27
  116. package/dist/session/watch.d.ts +2 -0
  117. package/dist/session/watch.js +41 -0
  118. package/dist/types/PluginNames.d.ts +2 -2
  119. package/dist/types/PluginNames.js +4 -0
  120. package/dist/types/config.d.ts +1 -0
  121. package/dist/types/issues.d.ts +4 -0
  122. package/dist/types/package-json.d.ts +0 -3
  123. package/dist/typescript/get-imports-and-exports.js +2 -0
  124. package/dist/typescript/visitors/calls.js +15 -11
  125. package/dist/typescript/visitors/imports.d.ts +2 -1
  126. package/dist/typescript/visitors/imports.js +25 -19
  127. package/dist/typescript/visitors/members.js +23 -26
  128. package/dist/typescript/visitors/walk.d.ts +3 -0
  129. package/dist/typescript/visitors/walk.js +42 -2
  130. package/dist/util/cli-arguments.d.ts +2 -1
  131. package/dist/util/cli-arguments.js +3 -0
  132. package/dist/util/create-input-handler.js +1 -1
  133. package/dist/util/create-options.d.ts +42 -1
  134. package/dist/util/create-options.js +13 -2
  135. package/dist/util/file-entry-cache.d.ts +2 -0
  136. package/dist/util/file-entry-cache.js +19 -1
  137. package/dist/util/gitignore-cache.d.ts +1 -0
  138. package/dist/util/gitignore-cache.js +1 -0
  139. package/dist/util/glob-core.js +4 -2
  140. package/dist/util/glob.d.ts +1 -0
  141. package/dist/util/glob.js +6 -0
  142. package/dist/util/input.d.ts +2 -0
  143. package/dist/util/loader.d.ts +1 -0
  144. package/dist/util/loader.js +38 -2
  145. package/dist/util/modules.js +3 -1
  146. package/dist/util/path.d.ts +1 -0
  147. package/dist/util/path.js +1 -0
  148. package/dist/util/reporter.d.ts +1 -1
  149. package/dist/util/reporter.js +53 -9
  150. package/dist/util/watch.d.ts +5 -11
  151. package/dist/util/watch.js +84 -68
  152. package/dist/version.d.ts +1 -1
  153. package/dist/version.js +1 -1
  154. package/package.json +1 -1
  155. package/schema.json +16 -0
@@ -1,17 +1,14 @@
1
- import { join } from '../../util/path.js';
2
1
  import { hasDependency } from '../../util/plugin.js';
3
- import { defaultFilename, defaultSrcDir, resolveFromAST } from './resolveFromAST.js';
2
+ import { resolveFromAST } from './resolveFromAST.js';
4
3
  const title = 'vite-plugin-pwa';
5
4
  const enablers = ['vite-plugin-pwa', '@vite-pwa/nuxt'];
6
5
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
6
  const config = ['vite.config.{js,mjs,ts,cjs,mts,cts}', 'nuxt.config.{js,cjs,mjs,ts,cts,mts}'];
8
- const production = [join(defaultSrcDir, defaultFilename)];
9
7
  const plugin = {
10
8
  title,
11
9
  enablers,
12
10
  isEnabled,
13
11
  config,
14
- production,
15
12
  resolveFromAST,
16
13
  };
17
14
  export default plugin;
@@ -1,4 +1,2 @@
1
1
  import type { ResolveFromAST } from '../../types/config.ts';
2
- export declare const defaultSrcDir = "public";
3
- export declare const defaultFilename = "sw.js";
4
2
  export declare const resolveFromAST: ResolveFromAST;
@@ -2,8 +2,8 @@ import { Visitor } from 'oxc-parser';
2
2
  import { findImportedCalls, findProperty, getFirstPropertyValue, getPropertyValues, } from '../../typescript/ast-helpers.js';
3
3
  import { toProductionEntry } from '../../util/input.js';
4
4
  import { join } from '../../util/path.js';
5
- export const defaultSrcDir = 'public';
6
- export const defaultFilename = 'sw.js';
5
+ const defaultSrcDir = 'public';
6
+ const defaultFilename = 'sw.js';
7
7
  const isNuxtConfig = (configFileName) => configFileName.startsWith('nuxt.config.');
8
8
  const getInjectManifestEntry = (options, configFileDir) => {
9
9
  if (!getPropertyValues(options, 'strategies').has('injectManifest'))
@@ -2,11 +2,11 @@ import { hasDependency } from '../../util/plugin.js';
2
2
  const title = '@vite-pwa/assets-generator';
3
3
  const enablers = ['@vite-pwa/assets-generator'];
4
4
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
5
- const config = ['pwa-assets.config.{js,cjs,mjs,ts,cts,mts}'];
5
+ const entry = ['pwa-assets.config.{js,cjs,mjs,ts,cts,mts}'];
6
6
  const plugin = {
7
7
  title,
8
8
  enablers,
9
9
  isEnabled,
10
- config,
10
+ entry,
11
11
  };
12
12
  export default plugin;
@@ -1,5 +1,5 @@
1
1
  import { toAlias, toDependency } from '../../util/input.js';
2
- import { join, toPosix } from '../../util/path.js';
2
+ import { join } from '../../util/path.js';
3
3
  const environments = {
4
4
  node: null,
5
5
  jsdom: null,
@@ -49,13 +49,10 @@ export const getAliasInputs = (aliasOptions, cwd) => {
49
49
  for (const [alias, value] of getAliasEntries(aliasOptions)) {
50
50
  if (!value)
51
51
  continue;
52
- const prefixes = [value]
53
- .flat()
54
- .filter((value) => typeof value === 'string')
55
- .map(prefix => (toPosix(prefix).startsWith(cwd) ? prefix : join(cwd, prefix)));
52
+ const prefixes = [value].flat().filter((value) => typeof value === 'string');
56
53
  if (alias.length > 1)
57
- inputs.push(toAlias(alias, prefixes));
58
- inputs.push(toAlias(addStar(alias), prefixes.map(addStar)));
54
+ inputs.push(toAlias(alias, prefixes, { dir: cwd }));
55
+ inputs.push(toAlias(addStar(alias), prefixes.map(addStar), { dir: cwd }));
59
56
  }
60
57
  return inputs;
61
58
  };
@@ -218,7 +218,7 @@ export const resolveConfig = async (localConfig, options) => {
218
218
  }
219
219
  const _entry = cfg.build?.lib?.entry ?? [];
220
220
  const entries = typeof _entry === 'string' ? [_entry] : Array.isArray(_entry) ? _entry : Object.values(_entry).flat();
221
- const deps = entries.map(specifier => join(viteRoot, specifier)).map(id => toEntry(id));
221
+ const deps = entries.map(specifier => toAbsolute(specifier, viteRoot)).map(id => toEntry(id));
222
222
  for (const dependency of deps)
223
223
  inputs.add(dependency);
224
224
  }
@@ -1,5 +1,5 @@
1
1
  import { toAlias, toDeferResolve, toDeferResolveEntry, toDeferResolveProductionEntry, toDependency, } from '../../util/input.js';
2
- import { extname, isInternal, join, toAbsolute } from '../../util/path.js';
2
+ import { extname, isInternal, join } from '../../util/path.js';
3
3
  import { hasDependency } from '../../util/plugin.js';
4
4
  import { getDependenciesFromConfig } from '../babel/index.js';
5
5
  import { createRequireContextVisitor } from './visitors/requireContext.js';
@@ -44,6 +44,8 @@ const resolveRuleSetDependencies = (rule) => {
44
44
  const d = getDependenciesFromConfig(rule.options).map(d => d.specifier);
45
45
  return [useItem, ...d];
46
46
  }
47
+ if (typeof useItem === 'string' && useItem && rule.options && rule.use == null)
48
+ useItem = { loader: useItem, options: rule.options };
47
49
  return [useItem].flat().flatMap((item) => {
48
50
  if (!item)
49
51
  return [];
@@ -149,7 +151,7 @@ export const findWebpackDependenciesFromConfig = async (config, options) => {
149
151
  if (alias.length > 1)
150
152
  inputs.add(toAlias(alias, prefixes));
151
153
  for (const prefix of prefixes) {
152
- inputs.add(toAlias(addStar(alias), [addStar(toAbsolute(prefix, options.configFileDir))]));
154
+ inputs.add(toAlias(addStar(alias), [addStar(prefix)], { dir: options.configFileDir }));
153
155
  }
154
156
  }
155
157
  }
@@ -22,10 +22,8 @@ const resolveConfig = config => {
22
22
  if (config.packageExtensions) {
23
23
  for (const extension of Object.values(config.packageExtensions)) {
24
24
  if (extension.peerDependencies) {
25
- for (const dep of Object.keys(extension.peerDependencies)) {
26
- const optional = extension.peerDependenciesMeta?.[dep]?.optional === true;
27
- inputs.push(optional ? toDependency(dep, { optional: true }) : toDependency(dep));
28
- }
25
+ for (const dep of Object.keys(extension.peerDependencies))
26
+ inputs.push(toDependency(dep, { optional: true }));
29
27
  }
30
28
  }
31
29
  }
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ report, issues, cwd }: ReporterOptions): Promise<void>;
3
+ declare function _default({ report, issues, cwd, write }: InternalReporterOptions): Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { toRelative } from '../util/path.js';
3
3
  import { flattenIssues, getIssueDescription, getIssuePrefix, getIssueTypeTitle } from './util/util.js';
4
- export default async ({ report, issues, cwd }) => {
4
+ export default async ({ report, issues, cwd, write }) => {
5
5
  const entries = [];
6
6
  for (const [type, isReportType] of Object.entries(report)) {
7
7
  if (!isReportType) {
@@ -33,9 +33,7 @@ export default async ({ report, issues, cwd }) => {
33
33
  }
34
34
  }
35
35
  }
36
- const output = JSON.stringify(entries);
37
- process.stdout._handle?.setBlocking?.(true);
38
- process.stdout.write(`${output}\n`);
36
+ write(JSON.stringify(entries));
39
37
  };
40
38
  function convertSeverity(severity) {
41
39
  switch (severity) {
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ report, issues, isShowProgress, options, cwd }: ReporterOptions): void;
3
+ declare function _default({ report, issues, isShowProgress, options, cwd, write }: InternalReporterOptions): void;
@@ -1,13 +1,12 @@
1
1
  import { createOwnershipEngine } from '../util/codeowners.js';
2
2
  import { relative, resolve } from '../util/path.js';
3
3
  import { getColoredTitle, getIssueLine, getIssueTypeTitle } from './util/util.js';
4
- const logIssueRecord = (issues, cwd) => {
4
+ const getIssueRecordLines = (issues, cwd) => {
5
5
  const sortedByFilePath = issues.sort((a, b) => (a.owner < b.owner ? -1 : 1));
6
- for (const { filePath, symbols, owner, parentSymbol } of sortedByFilePath) {
7
- console.log(getIssueLine({ owner, filePath, symbols, parentSymbol }, cwd));
8
- }
6
+ return sortedByFilePath.map(({ filePath, symbols, owner, parentSymbol }) => getIssueLine({ owner, filePath, symbols, parentSymbol }, cwd));
9
7
  };
10
- export default ({ report, issues, isShowProgress, options, cwd }) => {
8
+ export default ({ report, issues, isShowProgress, options, cwd, write }) => {
9
+ const lines = [];
11
10
  let opts = {};
12
11
  try {
13
12
  opts = options ? JSON.parse(options) : opts;
@@ -36,14 +35,15 @@ export default ({ report, issues, isShowProgress, options, cwd }) => {
36
35
  });
37
36
  if (issuesForType.length > 0) {
38
37
  if (totalIssues)
39
- console.log();
40
- title && console.log(getColoredTitle(title, issuesForType.length));
41
- logIssueRecord(issuesForType, cwd);
38
+ lines.push('');
39
+ title && lines.push(getColoredTitle(title, issuesForType.length));
40
+ lines.push(...getIssueRecordLines(issuesForType, cwd));
42
41
  }
43
42
  totalIssues = totalIssues + issuesForType.length;
44
43
  }
45
44
  }
46
45
  if (totalIssues === 0 && isShowProgress) {
47
- console.log('✂️ Excellent, Knip found no issues.');
46
+ lines.push('✂️ Excellent, Knip found no issues.');
48
47
  }
48
+ write(lines.join('\n'));
49
49
  };
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ report, issues, isShowProgress, cwd }: ReporterOptions): void;
3
+ declare function _default({ report, issues, isShowProgress, cwd, write }: InternalReporterOptions): void;
@@ -1,10 +1,10 @@
1
1
  import { flattenIssues, getColoredTitle, getIssueLine, getIssueTypeTitle } from './util/util.js';
2
- const logIssueRecord = (issues, cwd) => {
2
+ const getIssueRecordLines = (issues, cwd) => {
3
3
  const sortedByFilePath = issues.sort((a, b) => (a.filePath > b.filePath ? 1 : -1));
4
- for (const issue of sortedByFilePath)
5
- console.log(getIssueLine(issue, cwd));
4
+ return sortedByFilePath.map(issue => getIssueLine(issue, cwd));
6
5
  };
7
- export default ({ report, issues, isShowProgress, cwd }) => {
6
+ export default ({ report, issues, isShowProgress, cwd, write }) => {
7
+ const lines = [];
8
8
  let totalIssues = 0;
9
9
  for (const [reportType, isReportType] of Object.entries(report)) {
10
10
  if (isReportType) {
@@ -18,13 +18,14 @@ export default ({ report, issues, isShowProgress, cwd }) => {
18
18
  return { ...items[0], symbols: items };
19
19
  });
20
20
  if (issuesForType.length > 0) {
21
- title && console.log(getColoredTitle(title, issuesForType.length));
22
- logIssueRecord(issuesForType, cwd);
21
+ title && lines.push(getColoredTitle(title, issuesForType.length));
22
+ lines.push(...getIssueRecordLines(issuesForType, cwd));
23
23
  }
24
24
  totalIssues = totalIssues + issuesForType.length;
25
25
  }
26
26
  }
27
27
  if (totalIssues === 0 && isShowProgress) {
28
- console.log('✂️ Excellent, Knip found no issues.');
28
+ lines.push('✂️ Excellent, Knip found no issues.');
29
29
  }
30
+ write(lines.join('\n'));
30
31
  };
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ cwd, issues, isShowProgress }: ReporterOptions): void;
3
+ declare function _default({ cwd, issues, isShowProgress, write }: InternalReporterOptions): void;
@@ -35,14 +35,14 @@ const sortByFilePath = (cwd) => (a, b) => {
35
35
  const rootLocation = getIssueRootLocation(a, cwd).localeCompare(getIssueRootLocation(b, cwd));
36
36
  return rootLocation === 0 ? a.symbol.localeCompare(b.symbol) : rootLocation;
37
37
  };
38
- export default ({ cwd, issues, isShowProgress }) => {
38
+ export default ({ cwd, issues, isShowProgress, write }) => {
39
39
  const cycles = flattenIssues(issues.cycles).sort(sortByFilePath(cwd));
40
40
  if (cycles.length === 0) {
41
41
  if (isShowProgress)
42
- console.log('✂️ No circular dependencies found.');
42
+ write('✂️ No circular dependencies found.');
43
43
  return;
44
44
  }
45
- console.log(getColoredTitle(getIssueTypeTitle('cycles'), cycles.length));
45
+ const lines = [getColoredTitle(getIssueTypeTitle('cycles'), cycles.length)];
46
46
  const rootCounts = new Map();
47
47
  for (const issue of cycles) {
48
48
  const files = issue.symbols ?? issue.symbol.split(' → ').map(symbol => ({ symbol }));
@@ -62,18 +62,19 @@ export default ({ cwd, issues, isShowProgress }) => {
62
62
  if (rootLocation !== previousRoot) {
63
63
  const count = rootCounts.get(rootLocation) ?? 0;
64
64
  const countLabel = count > 1 ? st.dim(` (${count} cycles)`) : '';
65
- console.log(`\n${formatFile(root)}${countLabel}`);
65
+ lines.push(`\n${formatFile(root)}${countLabel}`);
66
66
  previousRoot = rootLocation;
67
67
  }
68
68
  else {
69
- console.log('');
69
+ lines.push('');
70
70
  }
71
71
  for (let depth = 1; depth <= files.length; depth++) {
72
72
  const isClose = depth === files.length;
73
73
  const edge = files[depth - 1];
74
74
  const file = isClose ? root : files[depth];
75
75
  const connector = st.dim(`${' '.repeat(depth - 1)}└── `);
76
- console.log(`${connector}${formatEdge(edge)}${formatFile(file)}${isClose ? st.dim(' ↩') : ''}`);
76
+ lines.push(`${connector}${formatEdge(edge)}${formatFile(file)}${isClose ? st.dim(' ↩') : ''}`);
77
77
  }
78
78
  }
79
+ write(lines.join('\n'));
79
80
  };
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ report, issues, cwd }: ReporterOptions): void;
3
+ declare function _default({ report, issues, cwd, write }: InternalReporterOptions): void;
@@ -1,15 +1,17 @@
1
1
  import { flattenIssues, getIssueTypeTitle, getTableForType } from './util/util.js';
2
- export default ({ report, issues, cwd }) => {
2
+ export default ({ report, issues, cwd, write }) => {
3
3
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
4
+ const lines = [];
4
5
  for (const [reportType, isReportType] of Object.entries(report)) {
5
6
  if (isReportType) {
6
7
  const title = reportMultipleGroups ? getIssueTypeTitle(reportType) : undefined;
7
8
  const issuesForType = flattenIssues(issues[reportType]);
8
9
  if (issuesForType.length > 0) {
9
- console.log(`<details>\n${title ? `<summary>${title} (${issuesForType.length})</summary>\n` : ''}\n\`\`\``);
10
- console.log(getTableForType(issuesForType, cwd, { isUseColors: false }).toString());
11
- console.log('```\n\n</details>\n');
10
+ lines.push(`<details>\n${title ? `<summary>${title} (${issuesForType.length})</summary>\n` : ''}\n\`\`\``);
11
+ lines.push(getTableForType(issuesForType, cwd, { isUseColors: false }).toString());
12
+ lines.push('```\n\n</details>\n');
12
13
  }
13
14
  }
14
15
  }
16
+ write(lines.join('\n'));
15
17
  };
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ report, issues, cwd, configurationHints, tagHints, isDisableConfigHints, isDisableTagHints, isTreatConfigHintsAsErrors, isTreatTagHintsAsErrors, configFilePath, }: ReporterOptions): void;
3
+ declare function _default({ report, issues, cwd, configurationHints, tagHints, isDisableConfigHints, isDisableTagHints, isTreatConfigHintsAsErrors, isTreatTagHintsAsErrors, configFilePath, write, }: InternalReporterOptions): void;
@@ -3,7 +3,7 @@ import { relative } from '../util/path.js';
3
3
  import { compareStrings } from '../util/string.js';
4
4
  import { hintPrinters } from './util/configuration-hints.js';
5
5
  import { flattenIssues, getIssueTypeTitle } from './util/util.js';
6
- const createGitHubActionsLogger = () => {
6
+ const createGitHubActionsLogger = (lines) => {
7
7
  const formatAnnotation = (level, message, options) => {
8
8
  const params = [`file=${options.file}`];
9
9
  if (options.startLine != null)
@@ -16,17 +16,18 @@ const createGitHubActionsLogger = () => {
16
16
  params.push(`endColumn=${options.endColumn}`);
17
17
  params.push(`title=✂️ Knip${options.title ? ` / ${options.title}` : ''}`);
18
18
  const paramString = params.join(',');
19
- console.log(`::${level} ${paramString}::${message}`);
19
+ lines.push(`::${level} ${paramString}::${message}`);
20
20
  };
21
21
  return {
22
- info: (message) => console.log(message),
22
+ info: (message) => lines.push(message),
23
23
  error: (message, options) => formatAnnotation('error', message, options),
24
24
  warning: (message, options) => formatAnnotation('warning', message, options),
25
25
  notice: (message, options) => formatAnnotation('notice', message, options),
26
26
  };
27
27
  };
28
- export default ({ report, issues, cwd, configurationHints, tagHints, isDisableConfigHints, isDisableTagHints, isTreatConfigHintsAsErrors, isTreatTagHintsAsErrors, configFilePath, }) => {
29
- const core = createGitHubActionsLogger();
28
+ export default ({ report, issues, cwd, configurationHints, tagHints, isDisableConfigHints, isDisableTagHints, isTreatConfigHintsAsErrors, isTreatTagHintsAsErrors, configFilePath, write, }) => {
29
+ const lines = [];
30
+ const core = createGitHubActionsLogger(lines);
30
31
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
31
32
  for (const [reportType, isReportType] of Object.entries(report)) {
32
33
  if (isReportType) {
@@ -111,4 +112,5 @@ export default ({ report, issues, cwd, configurationHints, tagHints, isDisableCo
111
112
  });
112
113
  }
113
114
  }
115
+ write(lines.join('\n'));
114
116
  };
@@ -1,13 +1,13 @@
1
1
  declare const _default: {
2
- symbols: (options: import("../types.ts").ReporterOptions) => void;
3
- compact: ({ report, issues, isShowProgress, cwd }: import("../types.ts").ReporterOptions) => void;
4
- codeowners: ({ report, issues, isShowProgress, options, cwd }: import("../types.ts").ReporterOptions) => void;
5
- cycles: ({ cwd, issues, isShowProgress }: import("../types.ts").ReporterOptions) => void;
6
- disclosure: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => void;
7
- codeclimate: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => Promise<void>;
8
- json: ({ report, issues, options, cwd }: import("../types.ts").ReporterOptions) => Promise<void>;
9
- markdown: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => void;
10
- sarif: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => void;
11
- 'github-actions': ({ report, issues, cwd, configurationHints, tagHints, isDisableConfigHints, isDisableTagHints, isTreatConfigHintsAsErrors, isTreatTagHintsAsErrors, configFilePath, }: import("../types.ts").ReporterOptions) => void;
2
+ symbols: (options: import("../types/issues.ts").InternalReporterOptions) => void;
3
+ compact: ({ report, issues, isShowProgress, cwd, write }: import("../types/issues.ts").InternalReporterOptions) => void;
4
+ codeowners: ({ report, issues, isShowProgress, options, cwd, write }: import("../types/issues.ts").InternalReporterOptions) => void;
5
+ cycles: ({ cwd, issues, isShowProgress, write }: import("../types/issues.ts").InternalReporterOptions) => void;
6
+ disclosure: ({ report, issues, cwd, write }: import("../types/issues.ts").InternalReporterOptions) => void;
7
+ codeclimate: ({ report, issues, cwd, write }: import("../types/issues.ts").InternalReporterOptions) => Promise<void>;
8
+ json: ({ report, issues, options, cwd, write }: import("../types/issues.ts").InternalReporterOptions) => Promise<void>;
9
+ markdown: ({ report, issues, cwd, write }: import("../types/issues.ts").InternalReporterOptions) => void;
10
+ sarif: ({ report, issues, cwd, write }: import("../types/issues.ts").InternalReporterOptions) => void;
11
+ 'github-actions': ({ report, issues, cwd, configurationHints, tagHints, isDisableConfigHints, isDisableTagHints, isTreatConfigHintsAsErrors, isTreatTagHintsAsErrors, configFilePath, write, }: import("../types/issues.ts").InternalReporterOptions) => void;
12
12
  };
13
13
  export default _default;
@@ -1,4 +1,4 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export interface JSONReportNamedItem {
3
3
  name: string;
4
4
  }
@@ -35,4 +35,4 @@ export type JSONReport = {
35
35
  issues: Array<JSONReportEntry>;
36
36
  };
37
37
  export default _default;
38
- declare function _default({ report, issues, options, cwd }: ReporterOptions): Promise<void>;
38
+ declare function _default({ report, issues, options, cwd, write }: InternalReporterOptions): Promise<void>;
@@ -2,7 +2,7 @@ import { createOwnershipEngine } from '../util/codeowners.js';
2
2
  import { isFile } from '../util/fs.js';
3
3
  import { relative, resolve } from '../util/path.js';
4
4
  import { convert, flattenIssues } from './util/util.js';
5
- export default async ({ report, issues, options, cwd }) => {
5
+ export default async ({ report, issues, options, cwd, write }) => {
6
6
  let opts = {};
7
7
  try {
8
8
  opts = options ? JSON.parse(options) : opts;
@@ -56,7 +56,5 @@ export default async ({ report, issues, options, cwd }) => {
56
56
  }
57
57
  }
58
58
  const jsonReport = { issues: Object.values(json) };
59
- const output = JSON.stringify(jsonReport);
60
- process.stdout._handle?.setBlocking?.(true);
61
- process.stdout.write(`${output}\n`);
59
+ write(JSON.stringify(jsonReport));
62
60
  };
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ report, issues, cwd }: ReporterOptions): void;
3
+ declare function _default({ report, issues, cwd, write }: InternalReporterOptions): void;
@@ -1,32 +1,34 @@
1
1
  import { relative } from '../util/path.js';
2
2
  import { flattenIssues, getIssueTypeTitle } from './util/util.js';
3
- export default ({ report, issues, cwd }) => {
4
- console.log('# Knip report\n');
3
+ export default ({ report, issues, cwd, write }) => {
4
+ const lines = ['# Knip report\n'];
5
5
  const getFilePath = (issue) => {
6
6
  if (!(issue.line && issue.col))
7
7
  return relative(cwd, issue.filePath);
8
8
  return `${relative(cwd, issue.filePath)}:${issue.line}:${issue.col}`;
9
9
  };
10
- const sortLongestSymbol = (a, b) => b.symbol.length - a.symbol.length;
10
+ const getSymbol = (issue) => issue.symbol.replaceAll('|', '\\|');
11
+ const sortLongestSymbol = (a, b) => getSymbol(b).length - getSymbol(a).length;
11
12
  const sortLongestFilePath = (a, b) => getFilePath(b).length - getFilePath(a).length;
12
13
  for (const [reportType, isReportType] of Object.entries(report)) {
13
14
  if (isReportType) {
14
15
  const title = getIssueTypeTitle(reportType);
15
16
  const issuesForType = flattenIssues(issues[reportType]);
16
17
  if (issuesForType.length > 0) {
17
- console.log(`## ${title} (${issuesForType.length})\n`);
18
- const longestSymbol = issuesForType.sort(sortLongestSymbol)[0].symbol.length;
18
+ lines.push(`## ${title} (${issuesForType.length})\n`);
19
+ const longestSymbol = getSymbol(issuesForType.sort(sortLongestSymbol)[0]).length;
19
20
  const sortedByFilePath = issuesForType.sort(sortLongestFilePath);
20
21
  const longestFilePath = getFilePath(sortedByFilePath[0]).length;
21
22
  const nameWidth = Math.max(longestSymbol, 'Name'.length);
22
23
  const locationWidth = Math.max(longestFilePath, 'Location'.length);
23
- console.log(`| ${'Name'.padEnd(nameWidth)} | ${'Location'.padEnd(locationWidth)} | Severity |`);
24
- console.log(`| :${'-'.repeat(nameWidth - 1)} | :${'-'.repeat(locationWidth - 1)} | :------- |`);
24
+ lines.push(`| ${'Name'.padEnd(nameWidth)} | ${'Location'.padEnd(locationWidth)} | Severity |`);
25
+ lines.push(`| :${'-'.repeat(nameWidth - 1)} | :${'-'.repeat(locationWidth - 1)} | :------- |`);
25
26
  for (const issue of sortedByFilePath) {
26
- console.log(`| ${issue.symbol.padEnd(nameWidth)} | ${getFilePath(issue).padEnd(locationWidth)} | ${(issue.severity ?? '').padEnd(8)} |`);
27
+ lines.push(`| ${getSymbol(issue).padEnd(nameWidth)} | ${getFilePath(issue).padEnd(locationWidth)} | ${(issue.severity ?? '').padEnd(8)} |`);
27
28
  }
28
- console.log('');
29
+ lines.push('');
29
30
  }
30
31
  }
31
32
  }
33
+ write(lines.join('\n'));
32
34
  };
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default({ report, issues, cwd }: ReporterOptions): void;
3
+ declare function _default({ report, issues, cwd, write }: InternalReporterOptions): void;
@@ -28,7 +28,7 @@ const sortByLocation = (a, b) => a.filePath.localeCompare(b.filePath) ||
28
28
  (a.line ?? 0) - (b.line ?? 0) ||
29
29
  (a.col ?? 0) - (b.col ?? 0) ||
30
30
  a.symbol.localeCompare(b.symbol);
31
- export default ({ report, issues, cwd }) => {
31
+ export default ({ report, issues, cwd, write }) => {
32
32
  const groups = [];
33
33
  for (const [type, isReportType] of Object.entries(report)) {
34
34
  if (!isReportType)
@@ -74,6 +74,5 @@ export default ({ report, issues, cwd }) => {
74
74
  },
75
75
  ],
76
76
  });
77
- process.stdout._handle?.setBlocking?.(true);
78
- process.stdout.write(`${output}\n`);
77
+ write(output);
79
78
  };
@@ -1,3 +1,3 @@
1
- import type { ReporterOptions } from '../types/issues.ts';
1
+ import type { InternalReporterOptions } from '../types/issues.ts';
2
2
  export default _default;
3
- declare function _default(options: ReporterOptions): void;
3
+ declare function _default(options: InternalReporterOptions): void;
@@ -2,24 +2,26 @@ import { printConfigurationHints, printTagHints } from './util/configuration-hin
2
2
  import { dim, flattenIssues, getColoredTitle, getIssueTypeTitle, getTableForType } from './util/util.js';
3
3
  export default (options) => {
4
4
  const { report, issues, isDisableConfigHints, isDisableTagHints, isShowProgress } = options;
5
+ const lines = [];
5
6
  let totalIssues = 0;
6
7
  for (const [reportType, isReportType] of Object.entries(report)) {
7
8
  if (isReportType) {
8
9
  const title = getIssueTypeTitle(reportType);
9
10
  const issuesForType = flattenIssues(issues[reportType]);
10
11
  if (issuesForType.length > 0) {
11
- title && console.log(getColoredTitle(title, issuesForType.length));
12
+ title && lines.push(getColoredTitle(title, issuesForType.length));
12
13
  const issues = typeof options.maxShowIssues === 'number'
13
14
  ? Array.from(issuesForType).slice(0, options.maxShowIssues)
14
15
  : issuesForType;
15
16
  if (issues.length > 0)
16
- console.log(getTableForType(issues, options.cwd).toString());
17
+ lines.push(getTableForType(issues, options.cwd).toString());
17
18
  if (issues.length !== issuesForType.length)
18
- console.log(dim(`…${issuesForType.length - issues.length} more items`));
19
+ lines.push(dim(`…${issuesForType.length - issues.length} more items`));
19
20
  totalIssues = totalIssues + issuesForType.length;
20
21
  }
21
22
  }
22
23
  }
24
+ options.write(lines.join('\n'));
23
25
  if (!isDisableConfigHints) {
24
26
  printConfigurationHints(options);
25
27
  }
@@ -30,6 +32,6 @@ export default (options) => {
30
32
  isShowProgress &&
31
33
  (!options.isTreatConfigHintsAsErrors || options.configurationHints.length === 0) &&
32
34
  (!options.isTreatTagHintsAsErrors || options.tagHints.size === 0)) {
33
- console.log('✂️ Excellent, Knip found no issues.');
35
+ options.write('✂️ Excellent, Knip found no issues.');
34
36
  }
35
37
  };
package/dist/run.d.ts CHANGED
@@ -15,7 +15,6 @@ export declare const run: (options: MainOptions) => Promise<{
15
15
  };
16
16
  };
17
17
  session: {
18
- listener: import("node:fs").WatchListener<string | Buffer<ArrayBufferLike>>;
19
18
  handleFileChanges: (changes: import("./util/watch.ts").WatchChange[]) => Promise<{
20
19
  duration: number;
21
20
  mem: number;
@@ -29,6 +28,7 @@ export declare const run: (options: MainOptions) => Promise<{
29
28
  configurationHints: import("./types/issues.ts").ConfigurationHint[];
30
29
  hasConfigLoadErrors: boolean;
31
30
  };
31
+ configurationFiles: import("./session/configuration.ts").ConfigurationFiles | undefined;
32
32
  } | undefined;
33
33
  streamer: ConsoleStreamer;
34
34
  }>;
package/dist/run.js CHANGED
@@ -1,4 +1,3 @@
1
- import { watch } from 'node:fs';
2
1
  import { createScriptParserContext } from './binaries/create-script-parser-context.js';
3
2
  import { _getInputsFromScripts } from './binaries/index.js';
4
3
  import { CatalogCounselor } from './CatalogCounselor.js';
@@ -9,7 +8,6 @@ import { analyze } from './graph/analyze.js';
9
8
  import { build } from './graph/build.js';
10
9
  import { IssueCollector } from './IssueCollector.js';
11
10
  import { ProjectPrincipal } from './ProjectPrincipal.js';
12
- import watchReporter from './reporters/watch.js';
13
11
  import { debugLogObject } from './util/debug.js';
14
12
  import { flushGitignoreCache, initGitignoreCache } from './util/gitignore-cache.js';
15
13
  import { flushGlobCache, initGlobCache } from './util/glob-cache.js';
@@ -68,7 +66,7 @@ export const run = async (options) => {
68
66
  collector.setIgnoreIssues(chief.getIgnoreIssues());
69
67
  debugLogObject('*', 'Included workspaces', () => workspaces.map(w => w.pkgName));
70
68
  debugLogObject('*', 'Included workspace configs', () => workspaces.map(w => ({ pkgName: w.pkgName, name: w.name, config: w.config, ancestors: w.ancestors })));
71
- const { graph, entryPaths, analyzedFiles, unreferencedFiles, analyzeSourceFile, enabledPluginsStore } = await build({
69
+ const { graph, entryPaths, analyzedFiles, unreferencedFiles, analyzeSourceFile, enabledPluginsStore, configurationFiles, } = await build({
72
70
  chief,
73
71
  collector,
74
72
  counselor,
@@ -93,13 +91,10 @@ export const run = async (options) => {
93
91
  options,
94
92
  });
95
93
  let session;
96
- if (options.isWatch || options.isSession) {
94
+ if (options.isSession) {
97
95
  const isIgnored = (filePath) => (!!options.cacheLocation && filePath.startsWith(options.cacheLocation)) ||
98
96
  filePath.includes('/.git/') ||
99
97
  isGitIgnored(filePath);
100
- const onFileChange = options.isWatch
101
- ? ({ issues, duration }) => watchReporter(options, { issues, streamer, size: analyzedFiles.size, duration })
102
- : undefined;
103
98
  session = await getSessionHandler(options, {
104
99
  analyzedFiles,
105
100
  analyzeSourceFile,
@@ -108,13 +103,11 @@ export const run = async (options) => {
108
103
  analyze: reAnalyze,
109
104
  principal,
110
105
  graph,
106
+ configurationFiles,
111
107
  isIgnored,
112
- onFileChange,
113
108
  unreferencedFiles,
114
109
  entryPaths,
115
110
  });
116
- if (options.isWatch)
117
- watch(options.cwd, { recursive: true }, session.listener);
118
111
  }
119
112
  const { issues, counters, tagHints, configurationHints, hasConfigLoadErrors } = collector.getIssues();
120
113
  if (!options.isWatch)