knip 6.29.0 → 6.30.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 (105) hide show
  1. package/dist/CatalogCounselor.d.ts +5 -2
  2. package/dist/CatalogCounselor.js +26 -8
  3. package/dist/ConfigurationChief.d.ts +1 -1
  4. package/dist/ConfigurationChief.js +29 -36
  5. package/dist/DependencyDeputy.d.ts +8 -1
  6. package/dist/DependencyDeputy.js +5 -5
  7. package/dist/PackagePeeker.d.ts +5 -0
  8. package/dist/PackagePeeker.js +31 -3
  9. package/dist/WorkspaceWorker.d.ts +1 -1
  10. package/dist/WorkspaceWorker.js +11 -7
  11. package/dist/binaries/bash-parser.js +3 -3
  12. package/dist/binaries/create-script-parser-context.d.ts +7 -0
  13. package/dist/binaries/create-script-parser-context.js +17 -0
  14. package/dist/binaries/resolvers/pnpx.js +10 -5
  15. package/dist/compilers/index.d.ts +5 -5
  16. package/dist/compilers/scss.js +32 -5
  17. package/dist/compilers/shared.d.ts +1 -0
  18. package/dist/compilers/shared.js +1 -1
  19. package/dist/compilers/svelte.d.ts +2 -0
  20. package/dist/compilers/svelte.js +22 -0
  21. package/dist/constants.d.ts +4 -1
  22. package/dist/constants.js +4 -0
  23. package/dist/graph/analyze.js +5 -2
  24. package/dist/graph/build.d.ts +3 -1
  25. package/dist/graph/build.js +38 -19
  26. package/dist/graph-explorer/operations/build-exports-tree.js +2 -1
  27. package/dist/graph-explorer/operations/is-referenced.js +7 -4
  28. package/dist/graph-explorer/utils.js +2 -2
  29. package/dist/plugins/_template/index.js +1 -1
  30. package/dist/plugins/astro-markdoc/index.js +3 -2
  31. package/dist/plugins/eleventy/index.js +1 -1
  32. package/dist/plugins/esbuild/index.js +1 -1
  33. package/dist/plugins/eslint/helpers.js +2 -1
  34. package/dist/plugins/gatsby/index.js +2 -2
  35. package/dist/plugins/jest/helpers.js +1 -1
  36. package/dist/plugins/metro/index.js +1 -1
  37. package/dist/plugins/nest/index.js +1 -1
  38. package/dist/plugins/node/index.js +11 -2
  39. package/dist/plugins/nx/index.js +4 -3
  40. package/dist/plugins/openclaw/index.js +1 -1
  41. package/dist/plugins/oxlint/index.js +9 -2
  42. package/dist/plugins/remark/helpers.d.ts +3 -0
  43. package/dist/plugins/remark/helpers.js +42 -0
  44. package/dist/plugins/remark/index.js +4 -5
  45. package/dist/plugins/rolldown/index.js +1 -1
  46. package/dist/plugins/rollup/index.js +1 -1
  47. package/dist/plugins/rslib/index.js +1 -1
  48. package/dist/plugins/stryker/index.js +6 -1
  49. package/dist/plugins/svelte/compiler.js +7 -5
  50. package/dist/plugins/tsdown/index.js +2 -2
  51. package/dist/plugins/tsup/index.js +1 -1
  52. package/dist/plugins/vitest/index.js +1 -1
  53. package/dist/plugins/vitest/types.d.ts +1 -1
  54. package/dist/reporters/codeclimate.js +1 -5
  55. package/dist/reporters/github-actions.js +5 -3
  56. package/dist/reporters/index.d.ts +1 -0
  57. package/dist/reporters/index.js +2 -0
  58. package/dist/reporters/json.d.ts +1 -0
  59. package/dist/reporters/json.js +1 -0
  60. package/dist/reporters/sarif.d.ts +3 -0
  61. package/dist/reporters/sarif.js +79 -0
  62. package/dist/reporters/trace.js +3 -2
  63. package/dist/reporters/util/util.d.ts +2 -1
  64. package/dist/reporters/util/util.js +6 -1
  65. package/dist/run.d.ts +1 -1
  66. package/dist/run.js +30 -0
  67. package/dist/schema/configuration.d.ts +6 -6
  68. package/dist/schema/configuration.js +1 -0
  69. package/dist/session/build-maps.js +2 -1
  70. package/dist/types/issues.d.ts +1 -0
  71. package/dist/types/package-json.d.ts +10 -0
  72. package/dist/typescript/get-imports-and-exports.js +3 -2
  73. package/dist/typescript/get-published-type-dependencies.d.ts +13 -0
  74. package/dist/typescript/get-published-type-dependencies.js +155 -0
  75. package/dist/typescript/visitors/calls.js +8 -0
  76. package/dist/util/catalog.d.ts +6 -1
  77. package/dist/util/catalog.js +16 -2
  78. package/dist/util/cli-arguments.d.ts +1 -1
  79. package/dist/util/cli-arguments.js +3 -3
  80. package/dist/util/codeowners.js +1 -1
  81. package/dist/util/create-input-handler.js +8 -2
  82. package/dist/util/create-options.d.ts +6 -5
  83. package/dist/util/disk-cache.js +1 -1
  84. package/dist/util/errors.js +3 -2
  85. package/dist/util/file-entry-cache.js +5 -1
  86. package/dist/util/fs.js +2 -2
  87. package/dist/util/get-included-issue-types.js +2 -1
  88. package/dist/util/gitignore-cache.js +4 -1
  89. package/dist/util/glob-cache.js +2 -2
  90. package/dist/util/glob-core.js +3 -1
  91. package/dist/util/input.d.ts +7 -1
  92. package/dist/util/input.js +6 -0
  93. package/dist/util/package-json.d.ts +346 -0
  94. package/dist/util/package-json.js +123 -0
  95. package/dist/util/path.d.ts +8 -7
  96. package/dist/util/resolve.d.ts +6 -0
  97. package/dist/util/resolve.js +24 -0
  98. package/dist/util/string.d.ts +2 -0
  99. package/dist/util/string.js +6 -0
  100. package/dist/util/table.js +2 -2
  101. package/dist/util/to-source-path.js +1 -1
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/package.json +5 -5
  105. package/schema.json +4 -0
@@ -38,8 +38,8 @@ const resolveConfig = async (config) => {
38
38
  return [...entryPatterns, ...externalDependencies];
39
39
  };
40
40
  const resolveFromAST = program => [
41
- ...[...collectPropertyValues(program, 'entry')].map(id => toProductionEntry(id, { allowIncludeExports: true })),
42
- ...[...collectPropertyValues(program, 'neverBundle')].map(id => toDependency(id, { optional: true })),
41
+ ...Array.from(collectPropertyValues(program, 'entry'), id => toProductionEntry(id, { allowIncludeExports: true })),
42
+ ...Array.from(collectPropertyValues(program, 'neverBundle'), id => toDependency(id, { optional: true })),
43
43
  ];
44
44
  const args = {
45
45
  config: true,
@@ -21,7 +21,7 @@ const resolveConfig = async (config) => {
21
21
  .map(id => toProductionEntry(id, { allowIncludeExports: true }));
22
22
  return entryPatterns;
23
23
  };
24
- const resolveFromAST = program => [...collectPropertyValues(program, 'entry')].map(id => toProductionEntry(id, { allowIncludeExports: true }));
24
+ const resolveFromAST = program => Array.from(collectPropertyValues(program, 'entry'), id => toProductionEntry(id, { allowIncludeExports: true }));
25
25
  const args = {
26
26
  config: true,
27
27
  };
@@ -70,7 +70,7 @@ const getConfigs = async (localConfig) => {
70
70
  for (const config of [localConfig].flat()) {
71
71
  if (config && typeof config !== 'string') {
72
72
  if (typeof config === 'function') {
73
- for (const command of ['dev', 'serve', 'build']) {
73
+ for (const command of ['serve', 'build']) {
74
74
  for (const mode of ['development', 'production']) {
75
75
  const cfg = await config({ command, mode, ssrBuild: undefined });
76
76
  configs.push(cfg);
@@ -58,7 +58,7 @@ export interface ViteConfig extends VitestConfig {
58
58
  extensions?: string[];
59
59
  };
60
60
  }
61
- export type COMMAND = 'dev' | 'serve' | 'build';
61
+ export type COMMAND = 'serve' | 'build';
62
62
  export type MODE = 'development' | 'production';
63
63
  interface Options {
64
64
  command: COMMAND;
@@ -1,6 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { toRelative } from '../util/path.js';
3
- import { flattenIssues, getIssuePrefix, getIssueTypeTitle } from './util/util.js';
3
+ import { flattenIssues, getIssueDescription, getIssuePrefix, getIssueTypeTitle } from './util/util.js';
4
4
  export default async ({ report, issues, cwd }) => {
5
5
  const entries = [];
6
6
  for (const [type, isReportType] of Object.entries(report)) {
@@ -47,10 +47,6 @@ function convertSeverity(severity) {
47
47
  return 'info';
48
48
  }
49
49
  }
50
- function getIssueDescription({ type, symbol, symbols, parentSymbol }) {
51
- const symbolDescription = symbols ? `${symbols.map(s => s.symbol).join(', ')}` : symbol;
52
- return `${getIssuePrefix(type)}: ${symbolDescription}${parentSymbol ? ` (${parentSymbol})` : ''}`;
53
- }
54
50
  function getSymbolDescription({ type, symbol, parentSymbol, }) {
55
51
  return `${getIssuePrefix(type)}: ${symbol.symbol}${parentSymbol ? ` (${parentSymbol})` : ''}`;
56
52
  }
@@ -1,5 +1,6 @@
1
1
  import { ISSUE_TYPE_TITLE } from '../constants.js';
2
2
  import { relative } from '../util/path.js';
3
+ import { compareStrings } from '../util/string.js';
3
4
  import { hintPrinters } from './util/configuration-hints.js';
4
5
  import { flattenIssues, getIssueTypeTitle } from './util/util.js';
5
6
  const createGitHubActionsLogger = () => {
@@ -31,7 +32,7 @@ export default ({ report, issues, cwd, configurationHints, tagHints, isDisableCo
31
32
  if (isReportType) {
32
33
  const title = reportMultipleGroups && getIssueTypeTitle(reportType);
33
34
  const issuesForType = flattenIssues(issues[reportType]);
34
- issuesForType.sort((a, b) => a.filePath.localeCompare(b.filePath) || (a.line ?? 0) - (b.line ?? 0));
35
+ issuesForType.sort((a, b) => compareStrings(a.filePath, b.filePath) || (a.line ?? 0) - (b.line ?? 0));
35
36
  if (issuesForType.length > 0) {
36
37
  title && core.info(`${title} (${issuesForType.length})`);
37
38
  for (const issue of issuesForType) {
@@ -55,7 +56,7 @@ export default ({ report, issues, cwd, configurationHints, tagHints, isDisableCo
55
56
  if (!isDisableConfigHints && configurationHints.length > 0) {
56
57
  const CONFIG_HINTS_TITLE = 'Configuration hints';
57
58
  core.info(`${CONFIG_HINTS_TITLE} (${configurationHints.length})`);
58
- const sortedHints = [...configurationHints].sort((a, b) => (a.filePath ?? '').localeCompare(b.filePath ?? ''));
59
+ const sortedHints = configurationHints.toSorted((a, b) => compareStrings(a.filePath ?? '', b.filePath ?? ''));
59
60
  for (const hint of sortedHints) {
60
61
  const hintPrinter = hintPrinters.get(hint.type);
61
62
  const message = hintPrinter?.print({
@@ -94,7 +95,8 @@ export default ({ report, issues, cwd, configurationHints, tagHints, isDisableCo
94
95
  if (!isDisableTagHints && tagHints.size > 0) {
95
96
  const TAG_HINTS_TITLE = 'Tag hints';
96
97
  core.info(`${TAG_HINTS_TITLE} (${tagHints.size})`);
97
- const sortedHints = [...tagHints].sort((a, b) => a.filePath.localeCompare(b.filePath));
98
+ const sortedHints = Array.from(tagHints);
99
+ sortedHints.sort((a, b) => compareStrings(a.filePath, b.filePath));
98
100
  for (const hint of sortedHints) {
99
101
  const file = relative(cwd, hint.filePath);
100
102
  const hintMessage = `Unused tag in ${file}: ${hint.identifier} → ${hint.tagName}`;
@@ -7,6 +7,7 @@ declare const _default: {
7
7
  codeclimate: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => Promise<void>;
8
8
  json: ({ report, issues, options, cwd }: import("../types.ts").ReporterOptions) => Promise<void>;
9
9
  markdown: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => void;
10
+ sarif: ({ report, issues, cwd }: import("../types.ts").ReporterOptions) => void;
10
11
  'github-actions': ({ report, issues, cwd, configurationHints, tagHints, isDisableConfigHints, isDisableTagHints, isTreatConfigHintsAsErrors, isTreatTagHintsAsErrors, configFilePath, }: import("../types.ts").ReporterOptions) => void;
11
12
  };
12
13
  export default _default;
@@ -6,6 +6,7 @@ import disclosure from './disclosure.js';
6
6
  import githubActions from './github-actions.js';
7
7
  import json from './json.js';
8
8
  import markdown from './markdown.js';
9
+ import sarif from './sarif.js';
9
10
  import symbols from './symbols.js';
10
11
  export default {
11
12
  symbols,
@@ -16,5 +17,6 @@ export default {
16
17
  codeclimate,
17
18
  json,
18
19
  markdown,
20
+ sarif,
19
21
  'github-actions': githubActions,
20
22
  };
@@ -15,6 +15,7 @@ export type JSONReportEntry = {
15
15
  owners?: Array<JSONReportNamedItem>;
16
16
  binaries?: Array<JSONReportNamedItem>;
17
17
  catalog?: Array<JSONReportItem>;
18
+ catalogReferences?: Array<JSONReportItem>;
18
19
  cycles?: Array<Array<JSONReportItem>>;
19
20
  dependencies?: Array<JSONReportItem>;
20
21
  devDependencies?: Array<JSONReportItem>;
@@ -20,6 +20,7 @@ export default async ({ report, issues, options, cwd }) => {
20
20
  ...(findOwners && { owners: findOwners(file).map(name => ({ name })) }),
21
21
  ...(report.binaries && { binaries: [] }),
22
22
  ...(report.catalog && { catalog: [] }),
23
+ ...(report.catalogReferences && { catalogReferences: [] }),
23
24
  ...(report.cycles && { cycles: [] }),
24
25
  ...(report.dependencies && { dependencies: [] }),
25
26
  ...(report.devDependencies && { devDependencies: [] }),
@@ -0,0 +1,3 @@
1
+ import type { ReporterOptions } from '../types/issues.ts';
2
+ export default _default;
3
+ declare function _default({ report, issues, cwd }: ReporterOptions): void;
@@ -0,0 +1,79 @@
1
+ import { ISSUE_TYPE_TITLE } from '../constants.js';
2
+ import { toPosix, toRelative } from '../util/path.js';
3
+ import { version } from '../version.js';
4
+ import { flattenIssues, getIssueDescription } from './util/util.js';
5
+ const schema = 'https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json';
6
+ const getLevel = (severity) => severity === 'error' ? 'error' : severity === 'warn' ? 'warning' : 'note';
7
+ const getProblemSeverity = (severity) => severity === 'error' ? 'error' : severity === 'warn' ? 'warning' : 'recommendation';
8
+ const getRuleId = (type) => `knip/${type}`;
9
+ const getUri = (filePath, cwd) => toPosix(toRelative(filePath, cwd))
10
+ .split('/')
11
+ .map(segment => encodeURIComponent(segment))
12
+ .join('/');
13
+ const getLocation = ({ filePath, line, col, symbol }, cwd) => ({
14
+ physicalLocation: {
15
+ artifactLocation: { uri: getUri(filePath, cwd) },
16
+ ...(line !== undefined && {
17
+ region: {
18
+ startLine: Math.max(line, 1),
19
+ ...(col !== undefined && {
20
+ startColumn: Math.max(col, 1),
21
+ endColumn: Math.max(col, 1) + Math.max(symbol.length, 1),
22
+ }),
23
+ },
24
+ }),
25
+ },
26
+ });
27
+ const sortByLocation = (a, b) => a.filePath.localeCompare(b.filePath) ||
28
+ (a.line ?? 0) - (b.line ?? 0) ||
29
+ (a.col ?? 0) - (b.col ?? 0) ||
30
+ a.symbol.localeCompare(b.symbol);
31
+ export default ({ report, issues, cwd }) => {
32
+ const groups = [];
33
+ for (const [type, isReportType] of Object.entries(report)) {
34
+ if (!isReportType)
35
+ continue;
36
+ const issuesForType = flattenIssues(issues[type]).sort(sortByLocation);
37
+ if (issuesForType.length > 0)
38
+ groups.push({ type, issues: issuesForType });
39
+ }
40
+ const rules = groups.map(({ type, issues }) => {
41
+ const severity = issues[0].severity;
42
+ const title = ISSUE_TYPE_TITLE[type];
43
+ return {
44
+ id: getRuleId(type),
45
+ name: type,
46
+ shortDescription: { text: title },
47
+ helpUri: 'https://knip.dev/reference/issue-types',
48
+ defaultConfiguration: { level: getLevel(severity) },
49
+ properties: { 'problem.severity': getProblemSeverity(severity) },
50
+ };
51
+ });
52
+ const results = groups.flatMap(({ type, issues }, ruleIndex) => issues.map(issue => ({
53
+ ruleId: getRuleId(type),
54
+ ruleIndex,
55
+ level: getLevel(issue.severity),
56
+ message: { text: getIssueDescription(issue) },
57
+ locations: [getLocation(issue, cwd)],
58
+ })));
59
+ const output = JSON.stringify({
60
+ $schema: schema,
61
+ version: '2.1.0',
62
+ runs: [
63
+ {
64
+ tool: {
65
+ driver: {
66
+ name: 'knip',
67
+ version,
68
+ semanticVersion: version,
69
+ informationUri: 'https://knip.dev',
70
+ rules,
71
+ },
72
+ },
73
+ results,
74
+ },
75
+ ],
76
+ });
77
+ process.stdout._handle?.setBlocking?.(true);
78
+ process.stdout.write(`${output}\n`);
79
+ };
@@ -1,6 +1,7 @@
1
1
  import st from '../util/colors.js';
2
2
  import { toRelative } from '../util/path.js';
3
3
  import { toRegexOrString } from '../util/regex.js';
4
+ import { compareStrings } from '../util/string.js';
4
5
  import { Table } from '../util/table.js';
5
6
  import { formatTrace } from '../util/trace.js';
6
7
  export default ({ graph, explorer, options, workspaceFilePathFilter, issues }) => {
@@ -11,7 +12,7 @@ export default ({ graph, explorer, options, workspaceFilePathFilter, issues }) =
11
12
  const seen = new Set();
12
13
  for (const [packageName, { imports }] of explorer.getDependencyUsage(pattern)) {
13
14
  const filtered = imports.filter(i => workspaceFilePathFilter(i.filePath));
14
- filtered.sort((a, b) => a.filePath.localeCompare(b.filePath) || (a.line ?? 0) - (b.line ?? 0));
15
+ filtered.sort((a, b) => compareStrings(a.filePath, b.filePath) || (a.line ?? 0) - (b.line ?? 0));
15
16
  for (const _import of filtered) {
16
17
  const pos = _import.line ? `:${_import.line}:${_import.col}` : '';
17
18
  const key = `${_import.filePath}${pos}:${packageName}`;
@@ -54,7 +55,7 @@ export default ({ graph, explorer, options, workspaceFilePathFilter, issues }) =
54
55
  }
55
56
  }
56
57
  }
57
- nodes.sort((a, b) => a.filePath.localeCompare(b.filePath) || a.identifier.localeCompare(b.identifier));
58
+ nodes.sort((a, b) => compareStrings(a.filePath, b.filePath) || compareStrings(a.identifier, b.identifier));
58
59
  const toRel = (path) => toRelative(path, options.cwd);
59
60
  if (nodes.length === 0) {
60
61
  if (options.traceFile && !graph.has(options.traceFile)) {
@@ -3,7 +3,7 @@ import type { Issue, IssueRecords, IssueSeverity, IssueSymbol, IssueType } from
3
3
  import { Table } from '../../util/table.ts';
4
4
  export declare const dim: (text: string | number | null | undefined) => string;
5
5
  export declare const bright: (text: string | number | null | undefined) => string;
6
- export declare const getIssueTypeTitle: (reportType: keyof typeof ISSUE_TYPE_TITLE) => "Circular dependencies" | "Duplicate exports" | "Exported types in used namespace" | "Exports in used namespace" | "Referenced optional peerDependencies" | "Unlisted binaries" | "Unlisted dependencies" | "Unresolved imports" | "Unused catalog entries" | "Unused dependencies" | "Unused devDependencies" | "Unused exported enum members" | "Unused exported namespace members" | "Unused exported types" | "Unused exports" | "Unused files";
6
+ export declare const getIssueTypeTitle: (reportType: keyof typeof ISSUE_TYPE_TITLE) => "Circular dependencies" | "Duplicate exports" | "Exported types in used namespace" | "Exports in used namespace" | "Referenced optional peerDependencies" | "Unlisted binaries" | "Unlisted dependencies" | "Unresolved catalog references" | "Unresolved imports" | "Unused catalog entries" | "Unused dependencies" | "Unused devDependencies" | "Unused exported enum members" | "Unused exported namespace members" | "Unused exported types" | "Unused exports" | "Unused files";
7
7
  export declare const getColoredTitle: (title: string, count: number) => string;
8
8
  export declare const getDimmedTitle: (title: string, count: number) => string;
9
9
  type LogIssueLine = {
@@ -28,4 +28,5 @@ export declare const getTableForType: (issues: Issue[], cwd: string, options?: {
28
28
  }) => Table;
29
29
  export declare const flattenIssues: (issues: IssueRecords) => Issue[];
30
30
  export declare const getIssuePrefix: (type: IssueType) => string;
31
+ export declare const getIssueDescription: ({ type, symbol, symbols, parentSymbol }: Issue) => string;
31
32
  export {};
@@ -1,6 +1,7 @@
1
1
  import { ISSUE_TYPE_TITLE, SYMBOL_TYPE } from '../../constants.js';
2
2
  import st from '../../util/colors.js';
3
3
  import { relative } from '../../util/path.js';
4
+ import { compareStrings } from '../../util/string.js';
4
5
  import { Table } from '../../util/table.js';
5
6
  const plain = (text) => text;
6
7
  export const dim = st.gray;
@@ -25,7 +26,7 @@ export const convert = (issue) => ({
25
26
  });
26
27
  const sortByPos = (a, b) => {
27
28
  if (a.filePath !== b.filePath)
28
- return a.filePath.localeCompare(b.filePath);
29
+ return compareStrings(a.filePath, b.filePath);
29
30
  if (a.line !== b.line)
30
31
  return (a.line ?? 0) - (b.line ?? 0);
31
32
  return (a.col ?? 0) - (b.col ?? 0);
@@ -63,3 +64,7 @@ export const getTableForType = (issues, cwd, options = { isUseColors: true }) =>
63
64
  };
64
65
  export const flattenIssues = (issues) => Object.values(issues).flatMap(Object.values);
65
66
  export const getIssuePrefix = (type) => ISSUE_TYPE_TITLE[type].replace(/ies$/, 'y').replace(/s$/, '');
67
+ export const getIssueDescription = ({ type, symbol, symbols, parentSymbol }) => {
68
+ const description = symbols ? symbols.map(item => item.symbol).join(', ') : symbol;
69
+ return `${getIssuePrefix(type)}: ${description}${parentSymbol ? ` (${parentSymbol})` : ''}`;
70
+ };
package/dist/run.d.ts CHANGED
@@ -14,7 +14,7 @@ export declare const run: (options: MainOptions) => Promise<{
14
14
  };
15
15
  };
16
16
  session: {
17
- listener: import("fs").WatchListener<string | Buffer<ArrayBufferLike>>;
17
+ listener: import("node:fs").WatchListener<string | Buffer<ArrayBufferLike>>;
18
18
  handleFileChanges: (changes: import("./util/watch.ts").WatchChange[]) => Promise<{
19
19
  duration: number;
20
20
  mem: number;
package/dist/run.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { watch } from 'node:fs';
2
+ import { createScriptParserContext } from './binaries/create-script-parser-context.js';
3
+ import { _getInputsFromScripts } from './binaries/index.js';
2
4
  import { CatalogCounselor } from './CatalogCounselor.js';
3
5
  import { ConfigurationChief } from './ConfigurationChief.js';
4
6
  import { ConsoleStreamer } from './ConsoleStreamer.js';
@@ -12,6 +14,8 @@ import { debugLogObject } from './util/debug.js';
12
14
  import { flushGitignoreCache, initGitignoreCache } from './util/gitignore-cache.js';
13
15
  import { flushGlobCache, initGlobCache } from './util/glob-cache.js';
14
16
  import { getGitIgnoredHandler } from './util/glob-core.js';
17
+ import { isCatalog } from './util/input.js';
18
+ import { createManifest } from './util/package-json.js';
15
19
  import { getModuleSourcePathHandler, getWorkspacePackageTargetHandler } from './util/to-source-path.js';
16
20
  import { getSessionHandler } from './util/watch.js';
17
21
  export const run = async (options) => {
@@ -28,6 +32,31 @@ export const run = async (options) => {
28
32
  const counselor = new CatalogCounselor(options);
29
33
  streamer.cast('Reading workspace configuration');
30
34
  const workspaces = await chief.getWorkspaces();
35
+ const includedWorkspaceNames = new Set(workspaces.map(workspace => workspace.name));
36
+ const scriptParserContext = createScriptParserContext(chief);
37
+ const { rootManifest, getManifest } = scriptParserContext;
38
+ for (const name of chief.availableWorkspaceNames) {
39
+ const workspace = chief.workspacePackages.get(name);
40
+ if (!workspace)
41
+ continue;
42
+ counselor.addWorkspace(workspace);
43
+ if (includedWorkspaceNames.has(name))
44
+ continue;
45
+ const manifest = createManifest(workspace.manifest);
46
+ const inputs = _getInputsFromScripts(Object.values(manifest.scripts ?? {}), {
47
+ cwd: workspace.dir,
48
+ rootCwd: options.cwd,
49
+ containingFilePath: workspace.manifestPath,
50
+ manifest,
51
+ rootManifest,
52
+ getManifest,
53
+ });
54
+ for (const input of inputs) {
55
+ if (isCatalog(input)) {
56
+ counselor.addReference({ catalogName: input.catalogName, packageName: input.specifier });
57
+ }
58
+ }
59
+ }
31
60
  const isGitIgnored = await getGitIgnoredHandler(options, new Set(workspaces.map(w => w.dir)));
32
61
  const toSourceFilePath = getModuleSourcePathHandler(chief);
33
62
  const findWorkspacePackageTarget = getWorkspacePackageTargetHandler(chief);
@@ -44,6 +73,7 @@ export const run = async (options) => {
44
73
  deputy,
45
74
  principal,
46
75
  isGitIgnored,
76
+ scriptParserContext,
47
77
  streamer,
48
78
  workspaces,
49
79
  options,
@@ -903,7 +903,7 @@ export declare const workspaceConfigurationSchema: z.ZodMiniObject<{
903
903
  ignoreExportsUsedInFile: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniObject<{
904
904
  [x: string]: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
905
905
  }, z.core.$strict>]>>;
906
- 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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"cycles">]>>>>;
906
+ 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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"catalogReferences">, z.ZodMiniLiteral<"cycles">]>>>>;
907
907
  includeEntryExports: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
908
908
  }, z.core.$strict>;
909
909
  export declare const knipConfigurationSchema: z.ZodMiniObject<{
@@ -1798,7 +1798,7 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
1798
1798
  project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
1799
1799
  }, z.core.$strip>]>>;
1800
1800
  $schema: z.ZodMiniOptional<z.ZodMiniString<string>>;
1801
- rules: z.ZodMiniOptional<z.ZodMiniRecord<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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"cycles">]> & z.core.$partial, z.ZodMiniEnum<{
1801
+ rules: z.ZodMiniOptional<z.ZodMiniRecord<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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"catalogReferences">, z.ZodMiniLiteral<"cycles">]> & z.core.$partial, z.ZodMiniEnum<{
1802
1802
  error: "error";
1803
1803
  off: "off";
1804
1804
  warn: "warn";
@@ -1815,7 +1815,7 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
1815
1815
  ignoreExportsUsedInFile: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniObject<{
1816
1816
  [x: string]: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
1817
1817
  }, z.core.$strict>]>>;
1818
- 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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"cycles">]>>>>;
1818
+ 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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"catalogReferences">, z.ZodMiniLiteral<"cycles">]>>>>;
1819
1819
  cycles: z.ZodMiniOptional<z.ZodMiniObject<{
1820
1820
  allow: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniArray<z.ZodMiniString<string>>>>;
1821
1821
  dynamicImports: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
@@ -1828,8 +1828,8 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
1828
1828
  tags: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
1829
1829
  treatConfigHintsAsErrors: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
1830
1830
  treatTagHintsAsErrors: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
1831
- include: z.ZodMiniOptional<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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"cycles">]>>>;
1832
- exclude: z.ZodMiniOptional<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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"cycles">]>>>;
1831
+ include: z.ZodMiniOptional<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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"catalogReferences">, z.ZodMiniLiteral<"cycles">]>>>;
1832
+ exclude: z.ZodMiniOptional<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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"catalogReferences">, z.ZodMiniLiteral<"cycles">]>>>;
1833
1833
  workspaces: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniObject<{
1834
1834
  angular: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
1835
1835
  config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
@@ -2733,7 +2733,7 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
2733
2733
  ignoreExportsUsedInFile: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniObject<{
2734
2734
  [x: string]: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
2735
2735
  }, z.core.$strict>]>>;
2736
- 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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"cycles">]>>>>;
2736
+ 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<"namespaceMembers">, z.ZodMiniLiteral<"catalog">, z.ZodMiniLiteral<"catalogReferences">, z.ZodMiniLiteral<"cycles">]>>>>;
2737
2737
  includeEntryExports: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
2738
2738
  }, z.core.$strict>>>;
2739
2739
  }, z.core.$strict>;
@@ -23,6 +23,7 @@ const issueTypeSchema = z.union([
23
23
  z.literal('enumMembers'),
24
24
  z.literal('namespaceMembers'),
25
25
  z.literal('catalog'),
26
+ z.literal('catalogReferences'),
26
27
  z.literal('cycles'),
27
28
  ]);
28
29
  const rulesSchema = z.partialRecord(issueTypeSchema, z.enum(['error', 'warn', 'off']));
@@ -1,6 +1,7 @@
1
1
  import { IMPORT_STAR } from '../constants.js';
2
2
  import { getExportedIdentifiers } from '../graph-explorer/utils.js';
3
3
  import { forEachAliasReExport, forEachNamespaceReExport, forEachPassThroughReExport, getStarReExportSources, } from '../graph-explorer/visitors.js';
4
+ import { compareStrings } from '../util/string.js';
4
5
  const FALLBACK_LOCATION = { identifier: undefined, pos: 0, line: 0, col: 0 };
5
6
  export const buildImportLookup = (fileNode) => {
6
7
  const imports = new Map();
@@ -43,7 +44,7 @@ export const buildExportsMap = (fileNode, filePath, graph, entryPaths, explorer,
43
44
  col,
44
45
  importLocations: usage.locations
45
46
  .filter(excludeReExports)
46
- .sort((a, b) => a.filePath.localeCompare(b.filePath) || a.line - b.line || a.col - b.col),
47
+ .sort((a, b) => compareStrings(a.filePath, b.filePath) || a.line - b.line || a.col - b.col),
47
48
  entryPaths: usageEntryPaths,
48
49
  exports: childExports,
49
50
  });
@@ -42,6 +42,7 @@ export type Issues = {
42
42
  enumMembers: IssueRecords;
43
43
  namespaceMembers: IssueRecords;
44
44
  catalog: IssueRecords;
45
+ catalogReferences: IssueRecords;
45
46
  cycles: IssueRecords;
46
47
  };
47
48
  export type IssueType = keyof Issues;
@@ -25,6 +25,7 @@ export type Scripts = Record<string, string>;
25
25
  export type Catalog = Record<string, string>;
26
26
  export type Catalogs = Record<string, Catalog>;
27
27
  type Dependencies = Record<string, string>;
28
+ type TypesVersions = Record<string, Record<string, string[]>>;
28
29
  export type PackageExtensions = Record<string, {
29
30
  peerDependencies?: Dependencies;
30
31
  peerDependenciesMeta?: Record<string, {
@@ -57,6 +58,15 @@ export type PackageJson = {
57
58
  browser?: string;
58
59
  types?: string;
59
60
  typings?: string;
61
+ typesVersions?: TypesVersions;
62
+ publishConfig?: {
63
+ directory?: string;
64
+ main?: string;
65
+ exports?: Exports;
66
+ types?: string;
67
+ typings?: string;
68
+ typesVersions?: TypesVersions;
69
+ };
60
70
  catalog?: Catalog;
61
71
  catalogs?: Catalogs;
62
72
  packageManager?: string;
@@ -1,5 +1,5 @@
1
1
  import { isBuiltin } from 'node:module';
2
- import { IMPORT_FLAGS, IMPORT_STAR, OPAQUE, PROTOCOL_VIRTUAL, SIDE_EFFECTS } from '../constants.js';
2
+ import { IMPORT_FLAGS, IMPORT_STAR, LOADER_DEFAULT, OPAQUE, PROTOCOL_VIRTUAL, SIDE_EFFECTS } from '../constants.js';
3
3
  import { addNsValue, addValue, createImports } from '../util/module-graph.js';
4
4
  import { getPackageNameFromFilePath, getPackageNameFromModuleSpecifier, isStartsLikePackageName, sanitizeSpecifier, } from '../util/modules.js';
5
5
  import { timerify } from '../util/Performance.js';
@@ -49,7 +49,8 @@ const getImportsAndExports = (filePath, sourceText, resolveModule, options, igno
49
49
  };
50
50
  const addInternalImport = (opts) => {
51
51
  const { filePath: importFilePath, namespace, specifier, modifiers } = opts;
52
- const identifier = opts.identifier ?? (modifiers & IMPORT_FLAGS.OPAQUE ? OPAQUE : SIDE_EFFECTS);
52
+ const identifier = opts.identifier ??
53
+ (modifiers & IMPORT_FLAGS.OPAQUE ? OPAQUE : modifiers & IMPORT_FLAGS.LOADER ? LOADER_DEFAULT : SIDE_EFFECTS);
53
54
  const isStar = identifier === IMPORT_STAR;
54
55
  imports.add({
55
56
  filePath: importFilePath,
@@ -0,0 +1,13 @@
1
+ import type { Workspace } from '../ConfigurationChief.ts';
2
+ import type { PackageJson } from '../types/package-json.ts';
3
+ interface PublishedTypeDependency {
4
+ containingFilePath: string;
5
+ packageName: string;
6
+ specifier: string;
7
+ pos: number;
8
+ line: number;
9
+ col: number;
10
+ isResolved: boolean;
11
+ }
12
+ export declare const createPublishedTypeDependencyAnalyzer: () => (workspace: Workspace, manifest: PackageJson) => PublishedTypeDependency[];
13
+ export {};