knip 6.43.0 → 6.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/README.md +2 -4
  2. package/dist/CacheConsultant.d.ts +1 -0
  3. package/dist/CacheConsultant.js +2 -0
  4. package/dist/CatalogCounselor.d.ts +1 -3
  5. package/dist/CatalogCounselor.js +18 -15
  6. package/dist/ConfigurationChief.d.ts +24 -0
  7. package/dist/DependencyDeputy.d.ts +2 -1
  8. package/dist/DependencyDeputy.js +11 -6
  9. package/dist/IssueCollector.js +1 -0
  10. package/dist/ProjectPrincipal.d.ts +4 -2
  11. package/dist/ProjectPrincipal.js +32 -10
  12. package/dist/WorkspaceWorker.d.ts +5 -2
  13. package/dist/WorkspaceWorker.js +20 -7
  14. package/dist/binaries/resolvers/bun.js +7 -2
  15. package/dist/binaries/util.js +2 -1
  16. package/dist/cli.js +6 -1
  17. package/dist/compilers/index.d.ts +5 -0
  18. package/dist/compilers/index.js +1 -1
  19. package/dist/constants.d.ts +2 -0
  20. package/dist/constants.js +2 -0
  21. package/dist/graph/analyze.js +3 -2
  22. package/dist/graph/build.d.ts +2 -0
  23. package/dist/graph/build.js +37 -22
  24. package/dist/graph-explorer/cache.d.ts +2 -1
  25. package/dist/graph-explorer/cache.js +5 -1
  26. package/dist/graph-explorer/explorer.d.ts +3 -5
  27. package/dist/graph-explorer/explorer.js +24 -3
  28. package/dist/plugins/babel/index.js +6 -1
  29. package/dist/plugins/biome/index.js +1 -1
  30. package/dist/plugins/cspell/index.js +10 -2
  31. package/dist/plugins/dependency-cruiser/index.js +2 -2
  32. package/dist/plugins/docusaurus/helpers.js +4 -4
  33. package/dist/plugins/electron-vite/index.js +2 -2
  34. package/dist/plugins/eleventy/index.js +2 -2
  35. package/dist/plugins/expressive-code/index.d.ts +1 -1
  36. package/dist/plugins/expressive-code/index.js +2 -2
  37. package/dist/plugins/gatsby/index.js +6 -6
  38. package/dist/plugins/gatsby/types.d.ts +1 -1
  39. package/dist/plugins/github-actions/index.js +1 -1
  40. package/dist/plugins/i18next-parser/index.js +2 -2
  41. package/dist/plugins/index.d.ts +5 -1
  42. package/dist/plugins/index.js +8 -0
  43. package/dist/plugins/jasmine/index.js +2 -2
  44. package/dist/plugins/karma/index.js +4 -4
  45. package/dist/plugins/kysely-codegen/index.d.ts +3 -0
  46. package/dist/plugins/kysely-codegen/index.js +20 -0
  47. package/dist/plugins/lefthook/index.js +2 -2
  48. package/dist/plugins/lingui/index.d.ts +3 -0
  49. package/dist/plugins/lingui/index.js +16 -0
  50. package/dist/plugins/lockfile-lint/index.js +2 -2
  51. package/dist/plugins/lost-pixel/index.js +2 -2
  52. package/dist/plugins/lunaria/index.js +2 -2
  53. package/dist/plugins/marko/index.js +5 -6
  54. package/dist/plugins/mastra/index.d.ts +3 -0
  55. package/dist/plugins/mastra/index.js +57 -0
  56. package/dist/plugins/mcp/index.js +1 -1
  57. package/dist/plugins/mise/index.js +0 -3
  58. package/dist/plugins/mocha/index.js +43 -4
  59. package/dist/plugins/mocha/types.d.ts +1 -0
  60. package/dist/plugins/npm-package-json-lint/index.js +1 -1
  61. package/dist/plugins/npm-package-json-lint/types.d.ts +1 -1
  62. package/dist/plugins/nx/index.js +3 -8
  63. package/dist/plugins/nyc/index.js +1 -1
  64. package/dist/plugins/openapi-ts/index.js +2 -2
  65. package/dist/plugins/oxfmt/index.js +2 -2
  66. package/dist/plugins/playwright/index.js +6 -11
  67. package/dist/plugins/pnpm/index.js +2 -4
  68. package/dist/plugins/purgecss/index.d.ts +3 -0
  69. package/dist/plugins/purgecss/index.js +16 -0
  70. package/dist/plugins/railway/index.js +1 -4
  71. package/dist/plugins/relay/index.js +1 -1
  72. package/dist/plugins/release-it/index.js +1 -1
  73. package/dist/plugins/remix/index.js +1 -1
  74. package/dist/plugins/rsbuild/index.js +29 -1
  75. package/dist/plugins/rsbuild/types.d.ts +8 -0
  76. package/dist/plugins/rstest/index.js +2 -2
  77. package/dist/plugins/serverless-framework/index.js +1 -1
  78. package/dist/plugins/storybook/index.js +5 -5
  79. package/dist/plugins/sveltekit/resolveFromAST.js +1 -1
  80. package/dist/plugins/svgr/index.js +2 -1
  81. package/dist/plugins/swc/index.js +8 -3
  82. package/dist/plugins/syncpack/index.js +2 -2
  83. package/dist/plugins/tanstack-router/index.js +3 -2
  84. package/dist/plugins/taskfile/index.js +4 -7
  85. package/dist/plugins/textlint/helpers.js +2 -2
  86. package/dist/plugins/typescript/index.js +7 -3
  87. package/dist/plugins/unocss/index.js +2 -2
  88. package/dist/plugins/vite-plugin-pwa/index.js +1 -4
  89. package/dist/plugins/vite-plugin-pwa/resolveFromAST.d.ts +0 -2
  90. package/dist/plugins/vite-plugin-pwa/resolveFromAST.js +2 -2
  91. package/dist/plugins/vite-pwa-assets-generator/index.js +2 -2
  92. package/dist/plugins/vitest/helpers.js +4 -7
  93. package/dist/plugins/vitest/index.js +1 -1
  94. package/dist/plugins/webpack/index.d.ts +2 -0
  95. package/dist/plugins/webpack/index.js +11 -6
  96. package/dist/plugins/yarn/index.js +2 -4
  97. package/dist/reporters/codeclimate.d.ts +2 -2
  98. package/dist/reporters/codeclimate.js +2 -4
  99. package/dist/reporters/codeowners.d.ts +2 -2
  100. package/dist/reporters/codeowners.js +9 -9
  101. package/dist/reporters/compact.d.ts +2 -2
  102. package/dist/reporters/compact.js +8 -7
  103. package/dist/reporters/cycles.d.ts +2 -2
  104. package/dist/reporters/cycles.js +7 -6
  105. package/dist/reporters/disclosure.d.ts +2 -2
  106. package/dist/reporters/disclosure.js +6 -4
  107. package/dist/reporters/github-actions.d.ts +2 -2
  108. package/dist/reporters/github-actions.js +7 -5
  109. package/dist/reporters/index.d.ts +10 -10
  110. package/dist/reporters/json.d.ts +2 -2
  111. package/dist/reporters/json.js +2 -4
  112. package/dist/reporters/markdown.d.ts +2 -2
  113. package/dist/reporters/markdown.js +11 -9
  114. package/dist/reporters/sarif.d.ts +2 -2
  115. package/dist/reporters/sarif.js +2 -3
  116. package/dist/reporters/symbols.d.ts +2 -2
  117. package/dist/reporters/symbols.js +6 -4
  118. package/dist/run.d.ts +1 -1
  119. package/dist/run.js +3 -10
  120. package/dist/schema/configuration.d.ts +60 -0
  121. package/dist/schema/plugins.d.ts +20 -0
  122. package/dist/schema/plugins.js +4 -0
  123. package/dist/session/configuration.d.ts +15 -0
  124. package/dist/session/configuration.js +62 -0
  125. package/dist/session/incremental.d.ts +54 -0
  126. package/dist/session/incremental.js +49 -0
  127. package/dist/session/session.d.ts +1 -1
  128. package/dist/session/session.js +63 -27
  129. package/dist/session/watch.d.ts +2 -0
  130. package/dist/session/watch.js +41 -0
  131. package/dist/types/PluginNames.d.ts +2 -2
  132. package/dist/types/PluginNames.js +4 -0
  133. package/dist/types/config.d.ts +1 -0
  134. package/dist/types/issues.d.ts +4 -0
  135. package/dist/types/package-json.d.ts +0 -3
  136. package/dist/typescript/get-imports-and-exports.js +2 -0
  137. package/dist/typescript/visitors/calls.js +15 -11
  138. package/dist/typescript/visitors/imports.d.ts +3 -1
  139. package/dist/typescript/visitors/imports.js +77 -53
  140. package/dist/typescript/visitors/members.js +23 -26
  141. package/dist/typescript/visitors/walk.d.ts +3 -0
  142. package/dist/typescript/visitors/walk.js +43 -2
  143. package/dist/util/cli-arguments.d.ts +2 -1
  144. package/dist/util/cli-arguments.js +3 -0
  145. package/dist/util/create-input-handler.js +1 -1
  146. package/dist/util/create-options.d.ts +43 -2
  147. package/dist/util/create-options.js +17 -4
  148. package/dist/util/file-entry-cache.d.ts +2 -0
  149. package/dist/util/file-entry-cache.js +19 -1
  150. package/dist/util/gitignore-cache.d.ts +1 -0
  151. package/dist/util/gitignore-cache.js +1 -0
  152. package/dist/util/glob-core.js +4 -2
  153. package/dist/util/glob.d.ts +1 -0
  154. package/dist/util/glob.js +6 -0
  155. package/dist/util/input.d.ts +2 -0
  156. package/dist/util/loader.d.ts +1 -0
  157. package/dist/util/loader.js +29 -1
  158. package/dist/util/modules.js +5 -2
  159. package/dist/util/path.d.ts +1 -0
  160. package/dist/util/path.js +1 -0
  161. package/dist/util/reporter.d.ts +1 -1
  162. package/dist/util/reporter.js +53 -9
  163. package/dist/util/watch.d.ts +5 -11
  164. package/dist/util/watch.js +84 -68
  165. package/dist/version.d.ts +1 -1
  166. package/dist/version.js +1 -1
  167. package/package.json +1 -1
  168. package/schema.json +16 -0
package/README.md CHANGED
@@ -50,8 +50,7 @@ following projects:
50
50
  [2]: https://img.shields.io/npm/v/knip?color=f56e0f
51
51
  [3]: https://img.shields.io/badge/dynamic/json?url=https://npm-gapless.webpro.nl/downloads/range/last-month/knip&query=$.totalCompact&label=downloads&suffix=/month&color=f56e0f
52
52
  [4]: https://github.com/webpro-nl/knip
53
- [5]:
54
- https://img.shields.io/github/stars/webpro-nl/knip?style=flat&color=f56e0f
53
+ [5]: https://img.shields.io/github/stars/webpro-nl/knip?style=flat&color=f56e0f
55
54
  [6]: https://knip.dev
56
55
  [7]: https://www.npmx.dev/package/@knip/create-config
57
56
  [8]: https://www.npmx.dev/package/@knip/language-server
@@ -69,7 +68,6 @@ following projects:
69
68
  [20]: https://github.com/pnpm/pnpm/tree/main/deps/graph-sequencer
70
69
  [21]: https://github.com/pnpm/pnpm/blob/main/LICENSE
71
70
  [22]: https://github.com/jaredwray/cacheable/tree/main/packages/file-entry-cache
72
- [23]:
73
- https://github.com/jaredwray/cacheable/blob/main/packages/file-entry-cache/LICENSE
71
+ [23]: https://github.com/jaredwray/cacheable/blob/main/packages/file-entry-cache/LICENSE
74
72
  [24]: https://github.com/npm/json-parse-even-better-errors
75
73
  [25]: https://github.com/npm/json-parse-even-better-errors/blob/main/LICENSE.md
@@ -5,6 +5,7 @@ export declare class CacheConsultant<T> {
5
5
  getFileDescriptor: (filePath: string) => FileDescriptor<T>;
6
6
  reconcile: () => void;
7
7
  removeEntry: (filePath: string) => void;
8
+ setFileData: (filePath: string, data: T) => void;
8
9
  constructor(name: string, options: MainOptions);
9
10
  getCachedFile(filePath: string): T | undefined;
10
11
  }
@@ -7,6 +7,7 @@ export class CacheConsultant {
7
7
  getFileDescriptor = () => dummyFileDescriptor;
8
8
  reconcile = () => { };
9
9
  removeEntry = () => { };
10
+ setFileData = () => { };
10
11
  constructor(name, options) {
11
12
  if (!options.isCache)
12
13
  return;
@@ -15,6 +16,7 @@ export class CacheConsultant {
15
16
  this.getFileDescriptor = timerify(this.cache.getFileDescriptor.bind(this.cache));
16
17
  this.reconcile = timerify(this.cache.reconcile.bind(this.cache));
17
18
  this.removeEntry = timerify(this.cache.removeEntry.bind(this.cache));
19
+ this.setFileData = this.cache.setFileData.bind(this.cache);
18
20
  }
19
21
  getCachedFile(filePath) {
20
22
  if (!this.cache)
@@ -9,12 +9,10 @@ export type CatalogContainer = {
9
9
  overrides?: Catalog;
10
10
  };
11
11
  export declare class CatalogCounselor {
12
- private filePath;
12
+ private sources;
13
13
  private entries;
14
14
  private referencedEntries;
15
15
  private referenceIssues;
16
- private overrideReferences;
17
- private fileContent?;
18
16
  constructor(options: MainOptions);
19
17
  private addReferencedCatalogEntry;
20
18
  addReference({ catalogName, packageName }: CatalogReference): void;
@@ -6,18 +6,20 @@ import { extractCatalogReferences, getOverrideCatalogReferences, parseCatalog, }
6
6
  import { extname } from './util/path.js';
7
7
  import { YamlCatalogPeeker } from './YamlCatalogPeeker.js';
8
8
  export class CatalogCounselor {
9
- filePath;
9
+ sources = [];
10
10
  entries = new Set();
11
11
  referencedEntries = new Set();
12
12
  referenceIssues = [];
13
- overrideReferences = [];
14
- fileContent;
15
13
  constructor(options) {
16
- this.filePath = options.catalog.filePath;
17
- this.entries = parseCatalog(options.catalog);
18
- this.overrideReferences = getOverrideCatalogReferences(options.catalog.overrides);
19
- for (const reference of this.overrideReferences)
20
- this.addReference(reference);
14
+ for (const container of options.catalog) {
15
+ const entries = parseCatalog(container);
16
+ const overrideReferences = getOverrideCatalogReferences(container.overrides);
17
+ for (const entry of entries)
18
+ this.entries.add(entry);
19
+ for (const reference of overrideReferences)
20
+ this.addReference(reference);
21
+ this.sources.push({ filePath: container.filePath, entries, overrideReferences });
22
+ }
21
23
  }
22
24
  addReferencedCatalogEntry(entryName) {
23
25
  this.referencedEntries.add(entryName);
@@ -52,16 +54,17 @@ export class CatalogCounselor {
52
54
  }
53
55
  }
54
56
  async settleCatalogIssues(options) {
55
- const filePath = this.filePath;
56
57
  const workspace = ROOT_WORKSPACE_NAME;
57
58
  const catalogIssues = [];
58
59
  const overrideReferenceIssues = [];
59
- if (this.entries.size > 0 || this.overrideReferences.length > 0) {
60
- this.fileContent = await readFile(filePath, 'utf-8');
60
+ for (const { filePath, entries, overrideReferences } of this.sources) {
61
+ if (entries.size === 0 && overrideReferences.length === 0)
62
+ continue;
63
+ const fileContent = await readFile(filePath, 'utf-8');
61
64
  const isYaml = ['.yml', '.yaml'].includes(extname(filePath));
62
- const yamlPeeker = isYaml ? new YamlCatalogPeeker(this.fileContent) : undefined;
63
- const peeker = yamlPeeker ?? new JsonCatalogPeeker(this.fileContent);
64
- for (const entry of this.entries.keys()) {
65
+ const yamlPeeker = isYaml ? new YamlCatalogPeeker(fileContent) : undefined;
66
+ const peeker = yamlPeeker ?? new JsonCatalogPeeker(fileContent);
67
+ for (const entry of entries) {
65
68
  if (!this.referencedEntries.has(entry)) {
66
69
  const [parentSymbol, symbol] = entry.split(':');
67
70
  const pos = peeker.getLocation(parentSymbol, symbol);
@@ -71,7 +74,7 @@ export class CatalogCounselor {
71
74
  catalogIssues.push({ type: 'catalog', filePath, workspace, symbol, parentSymbol, fixes, ...pos });
72
75
  }
73
76
  }
74
- for (const { catalogName, packageName, selector } of this.overrideReferences) {
77
+ for (const { catalogName, packageName, selector } of overrideReferences) {
75
78
  if (this.entries.has(`${catalogName}:${packageName}`))
76
79
  continue;
77
80
  const pos = yamlPeeker?.getOverrideCatalogReferenceLocation(selector);
@@ -337,6 +337,11 @@ export declare class ConfigurationChief {
337
337
  entry?: string | string[] | undefined;
338
338
  project?: string | string[] | undefined;
339
339
  } | undefined;
340
+ 'kysely-codegen'?: string | boolean | string[] | {
341
+ config?: string | string[] | undefined;
342
+ entry?: string | string[] | undefined;
343
+ project?: string | string[] | undefined;
344
+ } | undefined;
340
345
  ladle?: string | boolean | string[] | {
341
346
  config?: string | string[] | undefined;
342
347
  entry?: string | string[] | undefined;
@@ -352,6 +357,11 @@ export declare class ConfigurationChief {
352
357
  entry?: string | string[] | undefined;
353
358
  project?: string | string[] | undefined;
354
359
  } | undefined;
360
+ lingui?: string | boolean | string[] | {
361
+ config?: string | string[] | undefined;
362
+ entry?: string | string[] | undefined;
363
+ project?: string | string[] | undefined;
364
+ } | undefined;
355
365
  'lint-staged'?: string | boolean | string[] | {
356
366
  config?: string | string[] | undefined;
357
367
  entry?: string | string[] | undefined;
@@ -392,6 +402,11 @@ export declare class ConfigurationChief {
392
402
  entry?: string | string[] | undefined;
393
403
  project?: string | string[] | undefined;
394
404
  } | undefined;
405
+ mastra?: string | boolean | string[] | {
406
+ config?: string | string[] | undefined;
407
+ entry?: string | string[] | undefined;
408
+ project?: string | string[] | undefined;
409
+ } | undefined;
395
410
  mcp?: string | boolean | string[] | {
396
411
  config?: string | string[] | undefined;
397
412
  entry?: string | string[] | undefined;
@@ -622,6 +637,11 @@ export declare class ConfigurationChief {
622
637
  entry?: string | string[] | undefined;
623
638
  project?: string | string[] | undefined;
624
639
  } | undefined;
640
+ purgecss?: string | boolean | string[] | {
641
+ config?: string | string[] | undefined;
642
+ entry?: string | string[] | undefined;
643
+ project?: string | string[] | undefined;
644
+ } | undefined;
625
645
  quasar?: string | boolean | string[] | {
626
646
  config?: string | string[] | undefined;
627
647
  entry?: string | string[] | undefined;
@@ -1136,9 +1156,11 @@ export declare class ConfigurationChief {
1136
1156
  jest?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1137
1157
  karma?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1138
1158
  knex?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1159
+ "kysely-codegen"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1139
1160
  ladle?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1140
1161
  "laravel-vite-plugin"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1141
1162
  lefthook?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1163
+ lingui?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1142
1164
  "lint-staged"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1143
1165
  linthtml?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1144
1166
  lit?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1147,6 +1169,7 @@ export declare class ConfigurationChief {
1147
1169
  lunaria?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1148
1170
  markdownlint?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1149
1171
  marko?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1172
+ mastra?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1150
1173
  mcp?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1151
1174
  mdx?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1152
1175
  mdxlint?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -1193,6 +1216,7 @@ export declare class ConfigurationChief {
1193
1216
  preconstruct?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1194
1217
  prettier?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1195
1218
  prisma?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1219
+ purgecss?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1196
1220
  quasar?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1197
1221
  qwik?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
1198
1222
  railway?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
@@ -9,6 +9,7 @@ interface DependencyReferenceOptions {
9
9
  isTypeOnly?: boolean;
10
10
  isResolved?: boolean;
11
11
  isPublishedType?: boolean;
12
+ isCaught?: boolean;
12
13
  }
13
14
  export declare class DependencyDeputy {
14
15
  isProduction: boolean;
@@ -63,7 +64,7 @@ export declare class DependencyDeputy {
63
64
  isPeerOptional: boolean;
64
65
  }[];
65
66
  getOptionalPeerDependencies(workspaceName: string): DependencySet;
66
- maybeAddReferencedExternalDependency(workspace: Workspace, packageName: string, { specifier, isDevOnly, isTypeOnly, isResolved, isPublishedType }: DependencyReferenceOptions): boolean;
67
+ maybeAddReferencedExternalDependency(workspace: Workspace, packageName: string, { specifier, isDevOnly, isTypeOnly, isResolved, isPublishedType, isCaught }: DependencyReferenceOptions): boolean;
67
68
  maybeAddReferencedBinary(workspace: Workspace, binaryName: string): Set<string> | undefined;
68
69
  private isInDependencies;
69
70
  settleDependencyIssues(): {
@@ -1,5 +1,5 @@
1
1
  import { isBuiltin } from 'node:module';
2
- import { DT_SCOPE, IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES, IGNORED_RUNTIME_DEPENDENCIES, ROOT_WORKSPACE_NAME, } from './constants.js';
2
+ import { DT_SCOPE, IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES, IGNORED_RUNTIME_DEPENDENCIES, PROTOCOL_CLOUDFLARE, ROOT_WORKSPACE_NAME, } from './constants.js';
3
3
  import { getDependencyMetaData } from './manifest/index.js';
4
4
  import { PackagePeeker } from './PackagePeeker.js';
5
5
  import { getDefinitelyTypedFor, getPackageFromDefinitelyTyped, getPackageNameFromModuleSpecifier, isDefinitelyTyped, } from './util/modules.js';
@@ -124,18 +124,20 @@ export class DependencyDeputy {
124
124
  getOptionalPeerDependencies(workspaceName) {
125
125
  return this._manifests.get(workspaceName)?.optionalPeerDependencies ?? new Set();
126
126
  }
127
- maybeAddReferencedExternalDependency(workspace, packageName, { specifier, isDevOnly, isTypeOnly, isResolved, isPublishedType }) {
127
+ maybeAddReferencedExternalDependency(workspace, packageName, { specifier, isDevOnly, isTypeOnly, isResolved, isPublishedType, isCaught }) {
128
128
  if (!this.isReportDependencies)
129
129
  return true;
130
- if (specifier.startsWith('node:') || isBuiltin(specifier))
130
+ if (specifier.startsWith('node:') || specifier.startsWith(PROTOCOL_CLOUDFLARE) || isBuiltin(specifier))
131
131
  return true;
132
132
  if (IGNORED_RUNTIME_DEPENDENCIES.has(packageName))
133
133
  return true;
134
134
  if (packageName === workspace.pkgName)
135
135
  return true;
136
+ const optionalPeerDependencies = this.getOptionalPeerDependencies(workspace.name);
136
137
  const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...workspace.ancestors.toReversed()];
137
138
  const isDevOrTypeOnly = isDevOnly || (isTypeOnly && !isPublishedType);
138
- const closestWorkspaceName = workspaceNames.find(name => this.isInDependencies(name, packageName, isDevOrTypeOnly));
139
+ const isCaughtOptionalPeer = isCaught && optionalPeerDependencies.has(packageName);
140
+ const closestWorkspaceName = workspaceNames.find(name => this.isInDependencies(name, packageName, isDevOrTypeOnly, isCaughtOptionalPeer));
139
141
  const typesPackageName = !isDefinitelyTyped(packageName) && getDefinitelyTypedFor(packageName);
140
142
  const closestWorkspaceNameForTypes = typesPackageName && workspaceNames.find(name => this.isInDependencies(name, typesPackageName, isDevOrTypeOnly));
141
143
  if (closestWorkspaceNameForTypes && !this.hasTypesIncluded.get(closestWorkspaceNameForTypes)?.has(packageName))
@@ -199,12 +201,15 @@ export class DependencyDeputy {
199
201
  return optionalDependencies;
200
202
  return;
201
203
  }
202
- isInDependencies(workspaceName, packageName, isDevOnly) {
204
+ isInDependencies(workspaceName, packageName, isDevOnly, isCaughtOptionalPeer) {
203
205
  const manifest = this._manifests.get(workspaceName);
204
206
  if (!manifest)
205
207
  return false;
206
- if (this.isStrict && !isDevOnly)
208
+ if (this.isStrict && !isDevOnly) {
209
+ if (isCaughtOptionalPeer && manifest.optionalPeerDependencies.has(packageName))
210
+ return true;
207
211
  return this.getProductionDependencies(workspaceName).includes(packageName);
212
+ }
208
213
  return manifest.allDependencies.has(packageName);
209
214
  }
210
215
  settleDependencyIssues() {
@@ -172,6 +172,7 @@ export class IssueCollector {
172
172
  }
173
173
  this.issues = initIssues();
174
174
  this.counters = initCounters();
175
+ this.tagHints.clear();
175
176
  return unusedFiles;
176
177
  }
177
178
  getIssues() {
@@ -2,7 +2,8 @@ import type { ParseResult } from 'oxc-parser';
2
2
  import { CacheConsultant } from './CacheConsultant.ts';
3
3
  import type { Compilers } from './compilers/types.ts';
4
4
  import type { GetImportsAndExportsOptions, IgnoreExportsUsedInFile, PluginVisitorContext, PluginVisitorObject } from './types/config.ts';
5
- import type { FileNode, ModuleGraph } from './types/module-graph.ts';
5
+ import type { ConfigurationFiles } from './session/configuration.ts';
6
+ import type { FileNode } from './types/module-graph.ts';
6
7
  import type { Paths } from './types/project.ts';
7
8
  import type { ResolveGlobPattern } from './typescript/resolve-module-names.ts';
8
9
  import { SourceFileManager } from './typescript/SourceFileManager.ts';
@@ -39,6 +40,7 @@ export declare class ProjectPrincipal {
39
40
  addCompilers(workspaceName: string, compilers: Compilers): void;
40
41
  addPaths(paths: Paths, basePath: string, scope: string): void;
41
42
  addRootDirs(rootDirs: string[] | undefined, scope: string): void;
43
+ collectConfigurationImports(configurationFiles: ConfigurationFiles): void;
42
44
  init(): void;
43
45
  private hasAcceptedExtension;
44
46
  addEntryPath(filePath: string, options?: {
@@ -57,5 +59,5 @@ export declare class ProjectPrincipal {
57
59
  private getCachedFile;
58
60
  analyzeSourceFile(filePath: string, sourceText: string, options: GetImportsAndExportsOptions, ignoreExportsUsedInFile: IgnoreExportsUsedInFile, parseResult?: ParseResult, cachedFile?: FileNode): FileNode;
59
61
  invalidateFile(filePath: string): void;
60
- reconcileCache(graph: ModuleGraph): void;
62
+ reconcileCache(): void;
61
63
  }
@@ -10,6 +10,14 @@ import { SourceFileManager } from './typescript/SourceFileManager.js';
10
10
  import { compact } from './util/array.js';
11
11
  import { timerify } from './util/Performance.js';
12
12
  import { extname, isInNodeModules, toAbsolute } from './util/path.js';
13
+ const copyFileNode = (file) => ({
14
+ ...file,
15
+ imports: {
16
+ ...file.imports,
17
+ external: new Set(file.imports.external),
18
+ externalRefs: new Set(file.imports.externalRefs),
19
+ },
20
+ });
13
21
  export class ProjectPrincipal {
14
22
  entryPaths = new Set();
15
23
  projectPaths = new Set();
@@ -55,7 +63,7 @@ export class ProjectPrincipal {
55
63
  this.pluginVisitorObjects.push(createBunShellVisitor(this.pluginCtx));
56
64
  this.fileManager = new SourceFileManager({
57
65
  compilers: this.compilers,
58
- isSession: options.isSession || options.isWatch,
66
+ isSession: options.isSession,
59
67
  });
60
68
  this.walkAndAnalyze = timerify(this.walkAndAnalyze.bind(this), 'walkAndAnalyze');
61
69
  }
@@ -92,6 +100,23 @@ export class ProjectPrincipal {
92
100
  const scoped = this.rootDirs.get(scope) ?? [];
93
101
  this.rootDirs.set(scope, compact([...scoped, ...rootDirs]));
94
102
  }
103
+ collectConfigurationImports(configurationFiles) {
104
+ for (const filePath of configurationFiles.paths) {
105
+ if (!DEFAULT_EXTENSIONS.has(extname(filePath)))
106
+ continue;
107
+ const source = this.fileManager.readRawFile(filePath);
108
+ if (source === undefined)
109
+ continue;
110
+ try {
111
+ for (const specifier of extractSpecifiers(_parseFile(filePath, source), source, filePath)) {
112
+ const resolved = this.resolveSpecifier(specifier, filePath);
113
+ if (resolved && !isInNodeModules(resolved))
114
+ configurationFiles.addImport(filePath, resolved);
115
+ }
116
+ }
117
+ catch { }
118
+ }
119
+ }
95
120
  init() {
96
121
  const scopedPaths = this.paths.size > 0 ? Array.from(this.paths, ([scope, paths]) => ({ scope, paths })) : undefined;
97
122
  const scopedRootDirs = this.rootDirs.size > 0 ? Array.from(this.rootDirs, ([scope, rootDirs]) => ({ scope, rootDirs })) : undefined;
@@ -225,7 +250,7 @@ export class ProjectPrincipal {
225
250
  getCachedFile(filePath) {
226
251
  const cachedFile = this.cache.getCachedFile(filePath);
227
252
  const skipExports = this.skipExportsAnalysis.has(filePath) || !this.isReportExports;
228
- return cachedFile?.skipExports === skipExports ? cachedFile : undefined;
253
+ return cachedFile?.skipExports === skipExports ? copyFileNode(cachedFile) : undefined;
229
254
  }
230
255
  analyzeSourceFile(filePath, sourceText, options, ignoreExportsUsedInFile, parseResult, cachedFile) {
231
256
  if (cachedFile)
@@ -243,19 +268,16 @@ export class ProjectPrincipal {
243
268
  const visitor = ignoreExportsUsedInFile
244
269
  ? (this._localRefsVisitor ??= buildVisitor(this.pluginVisitorObjects, true))
245
270
  : (this._visitor ??= buildVisitor(this.pluginVisitorObjects, false));
246
- return _getImportsAndExports(filePath, sourceText, this.resolveModule, options, ignoreExportsUsedInFile, skipExports, visitor, this.pluginVisitorObjects.length > 0 ? this.pluginCtx : undefined, parseResult);
271
+ const file = _getImportsAndExports(filePath, sourceText, this.resolveModule, options, ignoreExportsUsedInFile, skipExports, visitor, this.pluginVisitorObjects.length > 0 ? this.pluginCtx : undefined, parseResult);
272
+ if (this.projectPaths.has(filePath))
273
+ this.cache.setFileData(filePath, copyFileNode(file));
274
+ return file;
247
275
  }
248
276
  invalidateFile(filePath) {
249
277
  this.fileManager.invalidate(filePath);
250
278
  this.cache.removeEntry(filePath);
251
279
  }
252
- reconcileCache(graph) {
253
- for (const [filePath, file] of graph) {
254
- const fd = this.cache.getFileDescriptor(filePath);
255
- if (!fd?.meta)
256
- continue;
257
- fd.meta.data = { ...file, internalImportCache: undefined, importedBy: undefined };
258
- }
280
+ reconcileCache() {
259
281
  this.cache.reconcile();
260
282
  }
261
283
  }
@@ -8,6 +8,7 @@ import type { DependencySet } from './types/workspace.ts';
8
8
  import { type Manifest } from './util/package-json.ts';
9
9
  import type { MainOptions } from './util/create-options.ts';
10
10
  import { type Input } from './util/input.ts';
11
+ import type { ConfigurationFiles } from './session/configuration.ts';
11
12
  type WorkspaceManagerOptions = {
12
13
  name: string;
13
14
  dir: string;
@@ -24,6 +25,7 @@ type WorkspaceManagerOptions = {
24
25
  ignoredWorkspacePatterns: string[];
25
26
  enabledPluginsInAncestors: string[];
26
27
  configFilesMap: Map<string, Map<PluginName, Set<string>>>;
28
+ configurationFiles?: ConfigurationFiles;
27
29
  options: MainOptions;
28
30
  };
29
31
  type CacheItem = {
@@ -51,7 +53,8 @@ export declare class WorkspaceWorker {
51
53
  enabledPluginsInAncestors: string[];
52
54
  cache: CacheConsultant<Partial<Record<PluginName, CacheItem>>>;
53
55
  configFilesMap: Map<string, Map<PluginName, Set<string>>>;
54
- constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, handleConfigLoadError, findWorkspaceByFilePath, getManifest, readRawFile, configFilesMap, options, }: WorkspaceManagerOptions);
56
+ configurationFiles: ConfigurationFiles | undefined;
57
+ constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, handleConfigLoadError, findWorkspaceByFilePath, getManifest, readRawFile, configFilesMap, configurationFiles, options, }: WorkspaceManagerOptions);
55
58
  init(): Promise<void>;
56
59
  private determineEnabledPlugins;
57
60
  private getConfigForPlugin;
@@ -60,7 +63,7 @@ export declare class WorkspaceWorker {
60
63
  getPluginProjectFilePatterns(patterns?: string[]): string[];
61
64
  private getPluginConfig;
62
65
  getPluginConfigPatterns(): string[];
63
- getPluginEntryFilePatterns(patterns: string[]): string[];
66
+ getPluginEntryFilePatterns(patterns: string[], base?: string): string[];
64
67
  getProductionEntryFilePatterns(): string[];
65
68
  getProductionProjectFilePatterns(): string[];
66
69
  private getConfigurationFilePatterns;
@@ -11,6 +11,7 @@ import { _parseFile } from './typescript/ast-nodes.js';
11
11
  import { compact } from './util/array.js';
12
12
  import { debugLog, debugLogArray, debugLogObject } from './util/debug.js';
13
13
  import { _glob, hasNoProductionSuffix, hasProductionSuffix, negate } from './util/glob.js';
14
+ import { expandIgnorePatterns } from './util/parse-and-convert-gitignores.js';
14
15
  import { isCatalog, isConfig, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
15
16
  import { filterTransitiveDependencies } from './util/filter-transitive-dependencies.js';
16
17
  import { timerify } from './util/Performance.js';
@@ -41,7 +42,8 @@ export class WorkspaceWorker {
41
42
  enabledPluginsInAncestors;
42
43
  cache;
43
44
  configFilesMap;
44
- constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, handleConfigLoadError, findWorkspaceByFilePath, getManifest, readRawFile, configFilesMap, options, }) {
45
+ configurationFiles;
46
+ constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, handleConfigLoadError, findWorkspaceByFilePath, getManifest, readRawFile, configFilesMap, configurationFiles, options, }) {
45
47
  this.name = name;
46
48
  this.dir = dir;
47
49
  this.config = config;
@@ -52,6 +54,7 @@ export class WorkspaceWorker {
52
54
  this.ignoredWorkspacePatterns = ignoredWorkspacePatterns;
53
55
  this.enabledPluginsInAncestors = enabledPluginsInAncestors;
54
56
  this.configFilesMap = configFilesMap;
57
+ this.configurationFiles = configurationFiles;
55
58
  this.handleInput = handleInput;
56
59
  this.handleConfigLoadError = handleConfigLoadError;
57
60
  this.findWorkspaceByFilePath = findWorkspaceByFilePath;
@@ -128,9 +131,14 @@ export class WorkspaceWorker {
128
131
  }
129
132
  return patterns;
130
133
  }
131
- getPluginEntryFilePatterns(patterns) {
134
+ getPluginEntryFilePatterns(patterns, base) {
132
135
  const negateWorkspaces = patterns.some(pattern => pattern.startsWith('**/')) ? this.negatedWorkspacePatterns : [];
133
- return [patterns, negateWorkspaces, this.ignoredWorkspacePatterns.map(negate)].flat();
136
+ const prefix = `${this.name}/`;
137
+ const toWorkspaceRelative = (name) => (name.startsWith(prefix) ? name.slice(prefix.length) : name);
138
+ const ignoredWorkspaces = base
139
+ ? expandIgnorePatterns(this.ignoredWorkspacePatterns.map(toWorkspaceRelative))
140
+ : this.ignoredWorkspacePatterns;
141
+ return [patterns, negateWorkspaces, ignoredWorkspaces.map(negate)].flat();
134
142
  }
135
143
  getProductionEntryFilePatterns() {
136
144
  const entry = this.config.entry.filter(hasProductionSuffix);
@@ -220,7 +228,8 @@ export class WorkspaceWorker {
220
228
  const [productionScripts, developmentScripts] = getFilteredScripts(manifest.scripts ?? {});
221
229
  const inputsFromManifest = _getInputsFromScripts(Object.values(developmentScripts), baseOptions);
222
230
  const productionInputsFromManifest = _getInputsFromScripts(Object.values(productionScripts), baseOptions);
223
- const hasProductionInput = (input) => productionInputsFromManifest.find(d => d.specifier === input.specifier && d.type === input.type);
231
+ for (const input of productionInputsFromManifest)
232
+ input.production = true;
224
233
  const createGetInputsFromScripts = (containingFilePath) => (scripts, options) => _getInputsFromScripts(scripts, { ...baseOptions, ...options, containingFilePath });
225
234
  const inputs = [];
226
235
  const configFilesMap = this.configFilesMap;
@@ -264,7 +273,7 @@ export class WorkspaceWorker {
264
273
  else if (isConfig(input)) {
265
274
  storeConfigFilePath(input.pluginName, { ...input, containingFilePath: inputContainingFilePath });
266
275
  }
267
- else if (!isProduction || (isProduction && (input.production || hasProductionInput(input)))) {
276
+ else if (!isProduction || input.production) {
268
277
  inputs.push({ ...input, containingFilePath: inputContainingFilePath });
269
278
  }
270
279
  }
@@ -324,6 +333,7 @@ export class WorkspaceWorker {
324
333
  if (seenConfigFiles.has(configFilePath))
325
334
  continue;
326
335
  seenConfigFiles.add(configFilePath);
336
+ this.configurationFiles?.paths.add(configFilePath);
327
337
  const isManifest = basename(configFilePath) === 'package.json';
328
338
  const fd = isManifest ? undefined : this.cache.getFileDescriptor(configFilePath);
329
339
  const data = fd?.changed ? undefined : fd?.meta?.data?.[pluginName];
@@ -419,9 +429,11 @@ export class WorkspaceWorker {
419
429
  for (const id of dependencies)
420
430
  addInput(id, id.containingFilePath ?? containingFilePath);
421
431
  }
422
- if (inputs.some(input => input.specifier.startsWith('!')))
432
+ if (inputs.some(input => input.specifier.startsWith('!'))) {
423
433
  for (const input of inputs)
424
- input.group = pluginName;
434
+ if (!seenConfigFiles.has(input.specifier))
435
+ input.group = pluginName;
436
+ }
425
437
  return inputs;
426
438
  };
427
439
  const enabledPluginTitles = this.enabledPlugins.map(name => Plugins[name].title);
@@ -429,6 +441,7 @@ export class WorkspaceWorker {
429
441
  for (const pluginName of this.enabledPlugins) {
430
442
  const configFiles = this.configFilesMap.get(wsName);
431
443
  const patterns = [...this.getConfigurationFilePatterns(pluginName), ...(configFiles?.get(pluginName) ?? [])];
444
+ this.configurationFiles?.addPatterns(this.dir, compact(patterns));
432
445
  configFiles?.delete(pluginName);
433
446
  for (const input of await runPlugin(pluginName, compact(patterns)))
434
447
  inputs.push(input);
@@ -56,7 +56,12 @@ const commands = new Set([
56
56
  ]);
57
57
  export const resolve = (_binary, words, options) => {
58
58
  const binary = toCommandBinary(_binary, options);
59
- const parsed = parseArgs(words, { string: ['cwd'] });
59
+ const parsed = parseArgs(words, {
60
+ string: ['cwd'],
61
+ boolean: ['bun', 'hot', 'if-present', 'silent', 'smol', 'watch'],
62
+ alias: { bun: 'b' },
63
+ isStorePositions: true,
64
+ });
60
65
  const [command, script] = parsed._;
61
66
  if (command === 'x') {
62
67
  const wordsForX = words.filter(word => word.value !== 'x');
@@ -81,7 +86,7 @@ export const resolve = (_binary, words, options) => {
81
86
  const dir = parsed.cwd ? join(cwd, parsed.cwd) : undefined;
82
87
  const opts = dir ? { cwd: dir } : {};
83
88
  if (command !== 'run')
84
- return [binary, ...fromArgs(words, opts)];
89
+ return [binary, ...fromArgs(dir ? words : words.slice(parsed.positionalIndices[0]), opts)];
85
90
  const input = toBinary(filePath, { optional: true });
86
91
  if (dir)
87
92
  input.dir = dir;
@@ -48,7 +48,8 @@ export const expandScript = (name, forwardedArgs, scripts, options, opts = {}) =
48
48
  if (expandedScripts.has(name))
49
49
  return;
50
50
  expandedScripts.add(name);
51
- return options.fromArgs([source, ...forwardedArgs], { ...opts, expandedScripts });
51
+ const cwd = options.manifestDir ?? options.cwd;
52
+ return options.fromArgs([source, ...forwardedArgs], { cwd, manifestDir: undefined, ...opts, expandedScripts });
52
53
  };
53
54
  export const parseNodeArgs = (args) => parseArgs(args, {
54
55
  string: ['r'],
package/dist/cli.js CHANGED
@@ -9,6 +9,7 @@ import { createPreprocessor, toReporterOptions } from './util/preprocessor.js';
9
9
  import { runReporters } from './util/reporter.js';
10
10
  import { prettyMilliseconds } from './util/string.js';
11
11
  import { version } from './version.js';
12
+ import { watchSession } from './session/watch.js';
12
13
  let args = {};
13
14
  try {
14
15
  args = parseArgs();
@@ -32,6 +33,10 @@ const main = async () => {
32
33
  process.exit(0);
33
34
  }
34
35
  const options = await createOptions({ args });
36
+ if (options.isWatch) {
37
+ await watchSession(options);
38
+ return;
39
+ }
35
40
  const { results } = await run(options);
36
41
  if (options.isWatch || options.isTrace)
37
42
  return;
@@ -39,7 +44,7 @@ const main = async () => {
39
44
  const finalData = await preprocess(toReporterOptions(options, results, args));
40
45
  if (options.isFix)
41
46
  await fix(finalData.issues, finalData.counters, options);
42
- await runReporters(args.reporter ?? ['symbols'], finalData);
47
+ await runReporters(args.reporter ?? ['symbols'], args['output-file'] ?? [], finalData);
43
48
  const totalErrorCount = Object.keys(finalData.report)
44
49
  .filter(reportGroup => finalData.report[reportGroup] && options.rules[reportGroup] === 'error')
45
50
  .reduce((errorCount, reportGroup) => errorCount + finalData.counters[reportGroup], 0);
@@ -3,4 +3,9 @@ import type { DependencySet } from '../types/workspace.ts';
3
3
  import type { Compilers, RawCompilers } from './types.ts';
4
4
  export declare const normalizeCompilerExtension: (ext: string) => string;
5
5
  export declare const normalizeCompilers: (rawLocalConfig: RawConfiguration) => RawCompilers;
6
+ export declare const builtInCompilers: {
7
+ dependencies: string[];
8
+ compiler: import("./types.ts").CompilerSync;
9
+ extensions: string[];
10
+ }[];
6
11
  export declare const getIncludedCompilers: (rawCompilers: RawCompilers, dependencies: DependencySet, onReferencedDependency?: (packageName: string) => void) => Compilers;
@@ -18,7 +18,7 @@ export const normalizeCompilers = (rawLocalConfig) => {
18
18
  }
19
19
  return compilers;
20
20
  };
21
- const builtInCompilers = [
21
+ export const builtInCompilers = [
22
22
  { extensions: ['.mdx'], ...MDX },
23
23
  { extensions: ['.sass', '.scss'], ...SCSS },
24
24
  { extensions: ['.less'], ...LESS },
@@ -11,6 +11,7 @@ export declare const BETA_TAG = "@beta";
11
11
  export declare const ALIAS_TAG = "@alias";
12
12
  export declare const DT_SCOPE = "@types";
13
13
  export declare const PROTOCOL_VIRTUAL = "virtual:";
14
+ export declare const PROTOCOL_CLOUDFLARE = "cloudflare:";
14
15
  export declare const IGNORED_GLOBAL_BINARIES: Set<string>;
15
16
  export declare const IGNORED_DEPENDENCIES: Set<string>;
16
17
  export declare const IGNORED_RUNTIME_DEPENDENCIES: Set<string>;
@@ -69,4 +70,5 @@ export declare const IMPORT_FLAGS: {
69
70
  readonly AUGMENT: number;
70
71
  readonly DYNAMIC: number;
71
72
  readonly LOADER: number;
73
+ readonly CAUGHT: number;
72
74
  };
package/dist/constants.js CHANGED
@@ -20,6 +20,7 @@ export const BETA_TAG = '@beta';
20
20
  export const ALIAS_TAG = '@alias';
21
21
  export const DT_SCOPE = '@types';
22
22
  export const PROTOCOL_VIRTUAL = 'virtual:';
23
+ export const PROTOCOL_CLOUDFLARE = 'cloudflare:';
23
24
  export const IGNORED_GLOBAL_BINARIES = new Set([
24
25
  'amplify',
25
26
  'aws',
@@ -278,4 +279,5 @@ export const IMPORT_FLAGS = {
278
279
  AUGMENT: 1 << 7,
279
280
  DYNAMIC: 1 << 8,
280
281
  LOADER: 1 << 9,
282
+ CAUGHT: 1 << 10,
281
283
  };