knip 2.33.3 → 2.34.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 (97) hide show
  1. package/README.md +27 -7
  2. package/dist/ConfigurationChief.d.ts +1 -0
  3. package/dist/ConfigurationChief.js +13 -1
  4. package/dist/ConfigurationValidator.d.ts +56 -0
  5. package/dist/ConfigurationValidator.js +1 -0
  6. package/dist/WorkspaceWorker.d.ts +1 -1
  7. package/dist/WorkspaceWorker.js +12 -17
  8. package/dist/binaries/bash-parser.js +1 -1
  9. package/dist/cli.js +1 -1
  10. package/dist/index.js +17 -16
  11. package/dist/plugins/_template/index.js +14 -3
  12. package/dist/plugins/_template/types.d.ts +1 -0
  13. package/dist/plugins/angular/index.js +11 -11
  14. package/dist/plugins/astro/index.d.ts +7 -0
  15. package/dist/plugins/astro/index.js +10 -0
  16. package/dist/plugins/ava/index.js +13 -12
  17. package/dist/plugins/babel/index.js +8 -5
  18. package/dist/plugins/capacitor/index.js +4 -2
  19. package/dist/plugins/changesets/index.js +7 -5
  20. package/dist/plugins/commitizen/index.js +4 -3
  21. package/dist/plugins/commitizen/types.d.ts +1 -1
  22. package/dist/plugins/commitlint/index.js +4 -2
  23. package/dist/plugins/cspell/index.js +4 -2
  24. package/dist/plugins/cspell/types.d.ts +1 -1
  25. package/dist/plugins/cypress/index.js +7 -4
  26. package/dist/plugins/drizzle/index.js +4 -4
  27. package/dist/plugins/eslint/fallback.js +6 -1
  28. package/dist/plugins/eslint/helpers.d.ts +2 -2
  29. package/dist/plugins/eslint/helpers.js +7 -7
  30. package/dist/plugins/eslint/index.d.ts +0 -1
  31. package/dist/plugins/eslint/index.js +3 -4
  32. package/dist/plugins/gatsby/index.js +5 -8
  33. package/dist/plugins/github-actions/index.d.ts +1 -1
  34. package/dist/plugins/github-actions/index.js +5 -4
  35. package/dist/plugins/husky/index.js +4 -2
  36. package/dist/plugins/index.d.ts +1 -0
  37. package/dist/plugins/index.js +1 -0
  38. package/dist/plugins/jest/index.js +8 -8
  39. package/dist/plugins/jest/types.d.ts +3 -0
  40. package/dist/plugins/jest/types.js +1 -0
  41. package/dist/plugins/lefthook/index.js +5 -4
  42. package/dist/plugins/lint-staged/index.js +7 -7
  43. package/dist/plugins/markdownlint/index.js +5 -4
  44. package/dist/plugins/mocha/index.js +8 -7
  45. package/dist/plugins/mocha/types.d.ts +4 -0
  46. package/dist/plugins/mocha/types.js +1 -0
  47. package/dist/plugins/npm-package-json-lint/index.js +4 -3
  48. package/dist/plugins/nx/index.js +6 -5
  49. package/dist/plugins/nyc/index.js +4 -3
  50. package/dist/plugins/nyc/types.d.ts +3 -0
  51. package/dist/plugins/nyc/types.js +1 -0
  52. package/dist/plugins/playwright/index.d.ts +1 -1
  53. package/dist/plugins/playwright/index.js +7 -6
  54. package/dist/plugins/playwright-ct/index.js +11 -6
  55. package/dist/plugins/postcss/index.js +6 -5
  56. package/dist/plugins/prettier/index.js +3 -3
  57. package/dist/plugins/prettier/types.d.ts +8 -0
  58. package/dist/plugins/prettier/types.js +1 -0
  59. package/dist/plugins/release-it/index.js +10 -9
  60. package/dist/plugins/remark/index.js +6 -5
  61. package/dist/plugins/remix/index.js +1 -5
  62. package/dist/plugins/rollup/index.js +1 -1
  63. package/dist/plugins/semantic-release/index.js +5 -4
  64. package/dist/plugins/semantic-release/types.d.ts +1 -1
  65. package/dist/plugins/storybook/index.js +13 -11
  66. package/dist/plugins/stryker/index.js +9 -6
  67. package/dist/plugins/stylelint/index.js +6 -5
  68. package/dist/plugins/typedoc/index.js +4 -3
  69. package/dist/plugins/typedoc/types.d.ts +1 -1
  70. package/dist/plugins/typescript/index.js +13 -10
  71. package/dist/plugins/vite/index.js +4 -2
  72. package/dist/plugins/vitest/index.d.ts +1 -1
  73. package/dist/plugins/vitest/index.js +8 -8
  74. package/dist/plugins/webpack/index.js +25 -15
  75. package/dist/plugins/webpack/types.d.ts +2 -1
  76. package/dist/types/config.d.ts +1 -1
  77. package/dist/types/plugins.d.ts +1 -1
  78. package/dist/typescript/SourceFileManager.js +3 -3
  79. package/dist/typescript/ast-helpers.d.ts +2 -1
  80. package/dist/typescript/ast-helpers.js +3 -0
  81. package/dist/typescript/visitors/exports/exportKeyword.js +5 -2
  82. package/dist/util/cli-arguments.d.ts +2 -1
  83. package/dist/util/cli-arguments.js +2 -0
  84. package/dist/util/compilers.d.ts +10 -0
  85. package/dist/util/debug.d.ts +3 -3
  86. package/dist/util/debug.js +10 -8
  87. package/dist/util/glob.js +1 -1
  88. package/dist/util/modules.js +1 -1
  89. package/dist/util/path.js +4 -2
  90. package/dist/util/plugin.js +7 -1
  91. package/dist/util/require.js +1 -1
  92. package/dist/util/unwrapFunction.d.ts +1 -0
  93. package/dist/util/unwrapFunction.js +13 -0
  94. package/dist/version.d.ts +1 -1
  95. package/dist/version.js +1 -1
  96. package/package.json +1 -1
  97. package/schema.json +4 -0
package/README.md CHANGED
@@ -87,6 +87,8 @@ npm install -D knip
87
87
 
88
88
  Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.6.
89
89
 
90
+ Since v2.33.0, the Bun runtime is also supported.
91
+
90
92
  ### Default Configuration
91
93
 
92
94
  Knip has good defaults and aims for no or little configuration. The (simplified) default config:
@@ -123,6 +125,19 @@ const config: KnipConfig = {
123
125
  export default config;
124
126
  ```
125
127
 
128
+ And if you need, you can also expose an (async) function if you need, like so:
129
+
130
+ ```ts
131
+ import type { KnipConfig } from 'knip';
132
+
133
+ const config = async (): Promise<KnipConfig> => ({
134
+ entry: ['src/index.ts'],
135
+ project: ['src/**/*.ts'],
136
+ });
137
+
138
+ export default config;
139
+ ```
140
+
126
141
  Use `--config path/to/knip.config.json` for a different path.
127
142
 
128
143
  ### Let's Go!
@@ -249,6 +264,7 @@ This is especially useful over time when such configuration files change (and th
249
264
  Knip contains a growing list of plugins:
250
265
 
251
266
  - [Angular][plugin-angular]
267
+ - [Astro][plugin-astro]
252
268
  - [Ava][plugin-ava]
253
269
  - [Babel][plugin-babel]
254
270
  - [Capacitor][plugin-capacitor]
@@ -302,6 +318,8 @@ themselves and/or `entry` files for Knip to analyze.
302
318
 
303
319
  See each plugin's documentation for its default values.
304
320
 
321
+ In an Astro, Svelte or Vue project? Make sure to see [compilers][46] and add some extra configuration.
322
+
305
323
  #### `config`
306
324
 
307
325
  Plugins usually include `config` files. They are handled by the plugin's custom dependency finder, which returns all
@@ -339,7 +357,7 @@ level by setting it to `false` there, and vice versa.
339
357
  #### Multi-project repositories
340
358
 
341
359
  Some repositories have a single `package.json`, but consist of multiple projects with configuration files across the
342
- repository (such as the [Nx "intregrated repo" style][46]). Let's assume some of these projects are apps and have their
360
+ repository (such as the [Nx "intregrated repo" style][47]). Let's assume some of these projects are apps and have their
343
361
  own Cypress configuration and test files. In that case, we could configure the Cypress plugin like this:
344
362
 
345
363
  ```json
@@ -352,7 +370,7 @@ own Cypress configuration and test files. In that case, we could configure the C
352
370
 
353
371
  #### Create a new plugin
354
372
 
355
- Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][47]. This
373
+ Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][48]. This
356
374
  guide also contains more details if you want to learn more about plugins and why they are useful.
357
375
 
358
376
  ### Compilers
@@ -375,7 +393,7 @@ export default {
375
393
  };
376
394
  ```
377
395
 
378
- Read [Compilers][48] for more details and examples.
396
+ Read [Compilers][46] for more details and examples.
379
397
 
380
398
  ### Ignore files, binaries, dependencies and workspaces
381
399
 
@@ -383,7 +401,7 @@ There are a few ways to tell Knip to ignore certain files, binaries, dependencie
383
401
 
384
402
  ```json
385
403
  {
386
- "ignore": ["**/*.d.ts", "**/fixtures"],
404
+ "ignore": ["**/fixtures"],
387
405
  "ignoreBinaries": ["zip", "docker-compose"],
388
406
  "ignoreDependencies": ["hidden-package"],
389
407
  "ignoreWorkspaces": ["packages/ignore", "packages/examples/**"]
@@ -676,6 +694,7 @@ $ npx knip --help
676
694
  --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)
677
695
  --ignore-internal Ignore exports with tag @internal (JSDoc/TSDoc)
678
696
  -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)
697
+ --directory [dir] Run process from a different directory (default: cwd)
679
698
  --no-gitignore Don't use .gitignore
680
699
  --include Report only provided issue type(s), can be comma-separated or repeated (1)
681
700
  --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)
@@ -867,9 +886,9 @@ Special thanks to the wonderful people who have contributed to this project:
867
886
  [43]: #why-knip
868
887
  [44]: #really-another-unused-filedependencyexport-finder
869
888
  [45]: #contributors
870
- [46]: https://nx.dev/concepts/integrated-vs-package-based
871
- [47]: ./docs/writing-a-plugin.md
872
- [48]: ./docs/compilers.md
889
+ [46]: ./docs/compilers.md
890
+ [47]: https://nx.dev/concepts/integrated-vs-package-based
891
+ [48]: ./docs/writing-a-plugin.md
873
892
  [49]: ./docs/handling-issues.md
874
893
  [50]: ./docs/reporters-and-preprocessors.md
875
894
  [51]: ./docs/perf-boost-with-no-gitignore.md
@@ -896,6 +915,7 @@ Special thanks to the wonderful people who have contributed to this project:
896
915
  [72]: https://github.com/webpro/knip/graphs/contributors
897
916
  [73]: https://contrib.rocks/image?repo=webpro/knip
898
917
  [plugin-angular]: ./src/plugins/angular
918
+ [plugin-astro]: ./src/plugins/astro
899
919
  [plugin-ava]: ./src/plugins/ava
900
920
  [plugin-babel]: ./src/plugins/babel
901
921
  [plugin-capacitor]: ./src/plugins/capacitor
@@ -37,6 +37,7 @@ export declare class ConfigurationChief {
37
37
  rawConfig?: any;
38
38
  constructor({ cwd, isProduction }: ConfigurationManagerOptions);
39
39
  init(): Promise<void>;
40
+ private loadResolvedConfigurationFile;
40
41
  getCompilers(): [SyncCompilers, AsyncCompilers];
41
42
  getRules(): import("./types/issues.js").Rules;
42
43
  getFilters(): {
@@ -18,6 +18,7 @@ import { getKeysByValue } from './util/object.js';
18
18
  import { join, relative, toPosix } from './util/path.js';
19
19
  import { normalizePluginConfig, toCamelCase } from './util/plugin.js';
20
20
  import { _require } from './util/require.js';
21
+ import { unwrapFunction } from './util/unwrapFunction.js';
21
22
  import { byPathDepth } from './util/workspace.js';
22
23
  const { config: rawConfigArg, workspace: rawWorkspaceArg, include = [], exclude = [], dependencies = false, exports = false, } = parsedArgValues;
23
24
  const workspaceArg = rawWorkspaceArg ? toPosix(rawWorkspaceArg).replace(/^\.\//, '').replace(/\/$/, '') : undefined;
@@ -90,11 +91,22 @@ export class ConfigurationChief {
90
91
  if (rawConfigArg && !this.resolvedConfigFilePath && !manifest.knip) {
91
92
  throw new ConfigurationError(`Unable to find ${rawConfigArg} or package.json#knip`);
92
93
  }
93
- this.rawConfig = this.resolvedConfigFilePath ? await _load(this.resolvedConfigFilePath) : manifest.knip;
94
+ this.rawConfig = this.resolvedConfigFilePath
95
+ ? await this.loadResolvedConfigurationFile(this.resolvedConfigFilePath)
96
+ : manifest.knip;
94
97
  const parsedConfig = this.rawConfig ? ConfigurationValidator.parse(partitionCompilers(this.rawConfig)) : {};
95
98
  this.config = this.normalize(parsedConfig);
96
99
  await this.setWorkspaces();
97
100
  }
101
+ async loadResolvedConfigurationFile(configPath) {
102
+ const loadedValue = await _load(configPath);
103
+ try {
104
+ return await unwrapFunction(loadedValue);
105
+ }
106
+ catch (e) {
107
+ throw new ConfigurationError(`Error running the function from ${configPath}`);
108
+ }
109
+ }
98
110
  getCompilers() {
99
111
  return [this.config.syncCompilers, this.config.asyncCompilers];
100
112
  }
@@ -34,6 +34,19 @@ export declare const ConfigurationValidator: z.ZodObject<{
34
34
  ignore: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
35
35
  ignoreBinaries: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
36
36
  ignoreDependencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
37
+ astro: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
38
+ config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
39
+ entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
40
+ project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
41
+ }, "strip", z.ZodTypeAny, {
42
+ config?: string | string[] | undefined;
43
+ entry?: string | string[] | undefined;
44
+ project?: string | string[] | undefined;
45
+ }, {
46
+ config?: string | string[] | undefined;
47
+ entry?: string | string[] | undefined;
48
+ project?: string | string[] | undefined;
49
+ }>]>>;
37
50
  angular: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
38
51
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
39
52
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -574,6 +587,11 @@ export declare const ConfigurationValidator: z.ZodObject<{
574
587
  ignore?: string | string[] | undefined;
575
588
  ignoreBinaries?: string[] | undefined;
576
589
  ignoreDependencies?: string[] | undefined;
590
+ astro?: string | boolean | string[] | {
591
+ config?: string | string[] | undefined;
592
+ entry?: string | string[] | undefined;
593
+ project?: string | string[] | undefined;
594
+ } | undefined;
577
595
  angular?: string | boolean | string[] | {
578
596
  config?: string | string[] | undefined;
579
597
  entry?: string | string[] | undefined;
@@ -786,6 +804,11 @@ export declare const ConfigurationValidator: z.ZodObject<{
786
804
  ignore?: string | string[] | undefined;
787
805
  ignoreBinaries?: string[] | undefined;
788
806
  ignoreDependencies?: string[] | undefined;
807
+ astro?: string | boolean | string[] | {
808
+ config?: string | string[] | undefined;
809
+ entry?: string | string[] | undefined;
810
+ project?: string | string[] | undefined;
811
+ } | undefined;
789
812
  angular?: string | boolean | string[] | {
790
813
  config?: string | string[] | undefined;
791
814
  entry?: string | string[] | undefined;
@@ -992,6 +1015,19 @@ export declare const ConfigurationValidator: z.ZodObject<{
992
1015
  project?: string | string[] | undefined;
993
1016
  } | undefined;
994
1017
  }>>>;
1018
+ astro: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
1019
+ config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1020
+ entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1021
+ project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
1022
+ }, "strip", z.ZodTypeAny, {
1023
+ config?: string | string[] | undefined;
1024
+ entry?: string | string[] | undefined;
1025
+ project?: string | string[] | undefined;
1026
+ }, {
1027
+ config?: string | string[] | undefined;
1028
+ entry?: string | string[] | undefined;
1029
+ project?: string | string[] | undefined;
1030
+ }>]>>;
995
1031
  angular: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
996
1032
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
997
1033
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -1547,6 +1583,11 @@ export declare const ConfigurationValidator: z.ZodObject<{
1547
1583
  ignore?: string | string[] | undefined;
1548
1584
  ignoreBinaries?: string[] | undefined;
1549
1585
  ignoreDependencies?: string[] | undefined;
1586
+ astro?: string | boolean | string[] | {
1587
+ config?: string | string[] | undefined;
1588
+ entry?: string | string[] | undefined;
1589
+ project?: string | string[] | undefined;
1590
+ } | undefined;
1550
1591
  angular?: string | boolean | string[] | {
1551
1592
  config?: string | string[] | undefined;
1552
1593
  entry?: string | string[] | undefined;
@@ -1753,6 +1794,11 @@ export declare const ConfigurationValidator: z.ZodObject<{
1753
1794
  project?: string | string[] | undefined;
1754
1795
  } | undefined;
1755
1796
  }> | undefined;
1797
+ astro?: string | boolean | string[] | {
1798
+ config?: string | string[] | undefined;
1799
+ entry?: string | string[] | undefined;
1800
+ project?: string | string[] | undefined;
1801
+ } | undefined;
1756
1802
  angular?: string | boolean | string[] | {
1757
1803
  config?: string | string[] | undefined;
1758
1804
  entry?: string | string[] | undefined;
@@ -1980,6 +2026,11 @@ export declare const ConfigurationValidator: z.ZodObject<{
1980
2026
  ignore?: string | string[] | undefined;
1981
2027
  ignoreBinaries?: string[] | undefined;
1982
2028
  ignoreDependencies?: string[] | undefined;
2029
+ astro?: string | boolean | string[] | {
2030
+ config?: string | string[] | undefined;
2031
+ entry?: string | string[] | undefined;
2032
+ project?: string | string[] | undefined;
2033
+ } | undefined;
1983
2034
  angular?: string | boolean | string[] | {
1984
2035
  config?: string | string[] | undefined;
1985
2036
  entry?: string | string[] | undefined;
@@ -2186,6 +2237,11 @@ export declare const ConfigurationValidator: z.ZodObject<{
2186
2237
  project?: string | string[] | undefined;
2187
2238
  } | undefined;
2188
2239
  }> | undefined;
2240
+ astro?: string | boolean | string[] | {
2241
+ config?: string | string[] | undefined;
2242
+ entry?: string | string[] | undefined;
2243
+ project?: string | string[] | undefined;
2244
+ } | undefined;
2189
2245
  angular?: string | boolean | string[] | {
2190
2246
  config?: string | string[] | undefined;
2191
2247
  entry?: string | string[] | undefined;
@@ -60,6 +60,7 @@ export const pluginSchema = z.union([
60
60
  }),
61
61
  ]);
62
62
  const pluginsSchema = z.object({
63
+ astro: pluginSchema,
63
64
  angular: pluginSchema,
64
65
  ava: pluginSchema,
65
66
  babel: pluginSchema,
@@ -52,7 +52,7 @@ export declare class WorkspaceWorker {
52
52
  installedBinaries: InstalledBinaries;
53
53
  referencedDependencies: ReferencedDependencies;
54
54
  hasTypesIncluded: Set<string>;
55
- enabledPlugins: ("angular" | "ava" | "babel" | "capacitor" | "changesets" | "commitizen" | "commitlint" | "cspell" | "cypress" | "eslint" | "gatsby" | "husky" | "jest" | "lefthook" | "markdownlint" | "mocha" | "next" | "nx" | "nyc" | "playwright" | "postcss" | "prettier" | "remark" | "remix" | "rollup" | "sentry" | "storybook" | "stryker" | "stylelint" | "tailwind" | "typedoc" | "typescript" | "vite" | "vitest" | "webpack" | "drizzle" | "githubActions" | "lintStaged" | "nodeTestRunner" | "npmPackageJsonLint" | "playwrightCt" | "releaseIt" | "semanticRelease" | "svelte")[];
55
+ enabledPlugins: ("astro" | "angular" | "ava" | "babel" | "capacitor" | "changesets" | "commitizen" | "commitlint" | "cspell" | "cypress" | "eslint" | "gatsby" | "husky" | "jest" | "lefthook" | "markdownlint" | "mocha" | "next" | "nx" | "nyc" | "playwright" | "postcss" | "prettier" | "remark" | "remix" | "rollup" | "sentry" | "storybook" | "stryker" | "stylelint" | "tailwind" | "typedoc" | "typescript" | "vite" | "vitest" | "webpack" | "drizzle" | "githubActions" | "lintStaged" | "nodeTestRunner" | "npmPackageJsonLint" | "playwrightCt" | "releaseIt" | "semanticRelease" | "svelte")[];
56
56
  entryFilePatterns: string[];
57
57
  productionEntryFilePatterns: string[];
58
58
  }>;
@@ -64,7 +64,7 @@ export class WorkspaceWorker {
64
64
  }
65
65
  this.enabledPlugins = getKeysByValue(this.enabled, true);
66
66
  const enabledPluginNames = this.enabledPlugins.map(name => plugins[name].NAME);
67
- debugLogObject(`Enabled plugins (${this.name})`, enabledPluginNames);
67
+ debugLogObject(this.name, `Enabled plugins (${this.name})`, enabledPluginNames);
68
68
  }
69
69
  async initReferencedDependencies() {
70
70
  const { dependencies, hostDependencies, installedBinaries, hasTypesIncluded } = await npm.findDependencies({
@@ -82,7 +82,8 @@ export class WorkspaceWorker {
82
82
  this.hasTypesIncluded = hasTypesIncluded;
83
83
  }
84
84
  getConfigForPlugin(pluginName) {
85
- return this.config[pluginName] !== true ? this.config[pluginName] ?? nullConfig : nullConfig;
85
+ const config = this.config[pluginName];
86
+ return typeof config === 'undefined' || typeof config === 'boolean' ? nullConfig : config;
86
87
  }
87
88
  getEntryFilePatterns() {
88
89
  const { entry } = this.config;
@@ -108,8 +109,8 @@ export class WorkspaceWorker {
108
109
  const patterns = [];
109
110
  for (const [pluginName, plugin] of Object.entries(plugins)) {
110
111
  const pluginConfig = this.getConfigForPlugin(pluginName);
111
- if (this.enabled[pluginName] && pluginConfig) {
112
- const { entry, project } = pluginConfig === true ? nullConfig : pluginConfig;
112
+ if (this.enabled[pluginName]) {
113
+ const { entry, project } = pluginConfig;
113
114
  patterns.push(...(project ?? entry ?? ('PROJECT_FILE_PATTERNS' in plugin ? plugin.PROJECT_FILE_PATTERNS : [])));
114
115
  }
115
116
  }
@@ -120,7 +121,7 @@ export class WorkspaceWorker {
120
121
  for (const [pluginName, plugin] of Object.entries(plugins)) {
121
122
  const pluginConfig = this.getConfigForPlugin(pluginName);
122
123
  if (this.enabled[pluginName] && pluginConfig) {
123
- const { config } = pluginConfig === true ? nullConfig : pluginConfig;
124
+ const { config } = pluginConfig;
124
125
  const defaultConfigFiles = 'CONFIG_FILE_PATTERNS' in plugin ? plugin.CONFIG_FILE_PATTERNS : [];
125
126
  patterns.push(...(config ?? defaultConfigFiles));
126
127
  }
@@ -160,7 +161,7 @@ export class WorkspaceWorker {
160
161
  const pluginConfig = this.getConfigForPlugin(pluginName);
161
162
  if (pluginConfig) {
162
163
  const defaultConfig = 'CONFIG_FILE_PATTERNS' in plugin ? plugin.CONFIG_FILE_PATTERNS : [];
163
- return (pluginConfig === true ? null : pluginConfig.config) ?? defaultConfig;
164
+ return pluginConfig.config ?? defaultConfig;
164
165
  }
165
166
  return [];
166
167
  }
@@ -168,6 +169,7 @@ export class WorkspaceWorker {
168
169
  return [...this.rootIgnore, ...this.config.ignore.map(pattern => prependDirToPattern(this.name, pattern))];
169
170
  }
170
171
  async findDependenciesByPlugins() {
172
+ const name = this.name;
171
173
  const cwd = this.dir;
172
174
  const ignore = this.getIgnorePatterns();
173
175
  for (const [pluginName, plugin] of Object.entries(plugins)) {
@@ -181,22 +183,15 @@ export class WorkspaceWorker {
181
183
  const allConfigFilePaths = await _pureGlob({ patterns, cwd, ignore, gitignore: false });
182
184
  const configFilePaths = allConfigFilePaths.filter(filePath => !filePath.endsWith('package.json') ||
183
185
  get(this.manifest, 'PACKAGE_JSON_PATH' in plugin ? plugin.PACKAGE_JSON_PATH : pluginName));
184
- debugLogArray(`Found ${plugin.NAME} config file paths`, configFilePaths);
185
- if (patterns.length > 0 && configFilePaths.length === 0) {
186
- if (typeof pluginConfig !== 'boolean' && pluginConfig.entry !== null && pluginConfig.entry.length > 0) {
187
- }
188
- else {
189
- continue;
190
- }
191
- }
192
- if (patterns.length === 0)
186
+ debugLogArray([name, plugin.NAME], 'config file paths', configFilePaths);
187
+ if (configFilePaths.length === 0)
193
188
  configFilePaths.push(FAKE_PATH);
194
189
  const pluginDependencies = new Set();
195
190
  for (const configFilePath of configFilePaths) {
196
191
  const dependencies = await plugin.findDependencies(configFilePath, {
197
192
  cwd,
198
193
  manifest: this.manifest,
199
- config: pluginConfig === true ? nullConfig : pluginConfig,
194
+ config: pluginConfig,
200
195
  isProduction: this.isProduction,
201
196
  });
202
197
  dependencies.forEach(specifier => {
@@ -212,7 +207,7 @@ export class WorkspaceWorker {
212
207
  }
213
208
  });
214
209
  }
215
- debugLogArray(`Dependencies referenced in ${plugin.NAME}`, pluginDependencies);
210
+ debugLogArray([name, plugin.NAME], 'dependencies', pluginDependencies);
216
211
  }
217
212
  }
218
213
  }
@@ -52,7 +52,7 @@ export const getBinariesFromScript = (script, { cwd, manifest, knownGlobalsOnly
52
52
  return parsed?.commands ? getBinariesFromNodes(parsed.commands) : [];
53
53
  }
54
54
  catch (error) {
55
- debugLogObject('Bash parser error', error);
55
+ debugLogObject('*', 'Bash parser error', error);
56
56
  return [];
57
57
  }
58
58
  };
package/dist/cli.js CHANGED
@@ -44,7 +44,7 @@ const run = async () => {
44
44
  };
45
45
  const finalData = await runPreprocessors(initialData);
46
46
  await runReporters(finalData);
47
- const totalErrorCount = Object.keys(report)
47
+ const totalErrorCount = Object.keys(finalData.report)
48
48
  .filter(reportGroup => report[reportGroup] && rules[reportGroup] === 'error')
49
49
  .reduce((errorCount, reportGroup) => errorCount + counters[reportGroup], 0);
50
50
  if (isObservePerf) {
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import { loadTSConfig } from './util/tsconfig-loader.js';
17
17
  import { WorkspaceWorker } from './WorkspaceWorker.js';
18
18
  export const main = async (unresolvedConfiguration) => {
19
19
  const { cwd, tsConfigFile, gitignore, isStrict, isProduction, isIgnoreInternal, isShowProgress, isIncludeEntryExports, } = unresolvedConfiguration;
20
- debugLogObject('Unresolved configuration (from CLI arguments)', unresolvedConfiguration);
20
+ debugLogObject('*', 'Unresolved configuration (from CLI arguments)', unresolvedConfiguration);
21
21
  const chief = new ConfigurationChief({ cwd, isProduction });
22
22
  const deputy = new DependencyDeputy({ isStrict });
23
23
  const factory = new PrincipalFactory();
@@ -35,8 +35,9 @@ export const main = async (unresolvedConfiguration) => {
35
35
  const collector = new IssueCollector({ cwd, rules, filters });
36
36
  const enabledPluginsStore = new Map();
37
37
  deputy.addIgnored(chief.config.ignoreBinaries, chief.config.ignoreDependencies);
38
- debugLogObject('Included workspaces', workspaces.map(w => w.pkgName));
39
- debugLogObject('Included workspace configs', workspaces.map(w => ({ name: w.name, pkgName: w.pkgName, config: w.config, ancestors: w.ancestors })));
38
+ const o = () => workspaces.map(w => ({ pkgName: w.pkgName, name: w.name, config: w.config, ancestors: w.ancestors }));
39
+ debugLogObject('*', 'Included workspaces', () => workspaces.map(w => w.pkgName));
40
+ debugLogObject('*', 'Included workspace configs', o);
40
41
  const handleReferencedDependency = ({ specifier, containingFilePath, principal, workspace, }) => {
41
42
  if (isInternal(specifier)) {
42
43
  const filePath = principal.resolveModule(specifier, containingFilePath)?.resolvedFileName;
@@ -82,7 +83,7 @@ export const main = async (unresolvedConfiguration) => {
82
83
  for (const workspace of workspaces) {
83
84
  const { name, dir, config, ancestors, pkgName, manifestPath, manifest } = workspace;
84
85
  const { paths, ignoreDependencies, ignoreBinaries } = config;
85
- streamer.cast(`Analyzing workspace (${name})...`);
86
+ streamer.cast(`Analyzing workspace ${name}...`);
86
87
  deputy.addWorkspace({ name, dir, manifestPath, manifest, ignoreDependencies, ignoreBinaries });
87
88
  const { compilerOptions, definitionPaths } = await loadTSConfig(join(dir, tsConfigFile ?? 'tsconfig.json'));
88
89
  const principal = factory.getPrincipal({ cwd: dir, paths, compilerOptions, compilers, pkgName });
@@ -100,10 +101,10 @@ export const main = async (unresolvedConfiguration) => {
100
101
  });
101
102
  await worker.init();
102
103
  principal.addEntryPaths(definitionPaths);
103
- debugLogArray(`Found definition paths (${name})`, definitionPaths);
104
+ debugLogArray(name, `Definition paths`, definitionPaths);
104
105
  const sharedGlobOptions = { cwd, workingDir: dir, gitignore, ignore: worker.getIgnorePatterns() };
105
106
  const entryPathsFromManifest = await getEntryPathFromManifest(cwd, dir, manifest);
106
- debugLogArray(`Found entry paths in package.json (${name})`, entryPathsFromManifest);
107
+ debugLogArray(name, 'Entry paths in package.json', entryPathsFromManifest);
107
108
  principal.addEntryPaths(entryPathsFromManifest);
108
109
  const dependencies = await worker.findAllDependencies();
109
110
  const { referencedDependencies, hostDependencies, installedBinaries, hasTypesIncluded, enabledPlugins, entryFilePatterns, productionEntryFilePatterns, } = dependencies;
@@ -119,18 +120,18 @@ export const main = async (unresolvedConfiguration) => {
119
120
  {
120
121
  const patterns = worker.getProductionEntryFilePatterns(negatedEntryPatterns);
121
122
  const workspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns });
122
- debugLogArray(`Found entry paths (${name})`, workspaceEntryPaths);
123
+ debugLogArray(name, `Entry paths`, workspaceEntryPaths);
123
124
  principal.addEntryPaths(workspaceEntryPaths);
124
125
  }
125
126
  {
126
127
  const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns: productionEntryFilePatterns });
127
- debugLogArray(`Found production plugin entry paths (${name})`, pluginWorkspaceEntryPaths);
128
+ debugLogArray(name, `Production plugin entry paths`, pluginWorkspaceEntryPaths);
128
129
  principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
129
130
  }
130
131
  {
131
132
  const patterns = worker.getProductionProjectFilePatterns(negatedEntryPatterns);
132
133
  const workspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns });
133
- debugLogArray(`Found project paths (${name})`, workspaceProjectPaths);
134
+ debugLogArray(name, `Project paths`, workspaceProjectPaths);
134
135
  workspaceProjectPaths.forEach(projectPath => principal.addProjectPath(projectPath));
135
136
  }
136
137
  }
@@ -138,31 +139,31 @@ export const main = async (unresolvedConfiguration) => {
138
139
  {
139
140
  const patterns = worker.getEntryFilePatterns();
140
141
  const workspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns });
141
- debugLogArray(`Found entry paths (${name})`, workspaceEntryPaths);
142
+ debugLogArray(name, `Entry paths`, workspaceEntryPaths);
142
143
  principal.addEntryPaths(workspaceEntryPaths);
143
144
  }
144
145
  {
145
146
  const patterns = worker.getProjectFilePatterns([...productionEntryFilePatterns]);
146
147
  const workspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns });
147
- debugLogArray(`Found project paths (${name})`, workspaceProjectPaths);
148
+ debugLogArray(name, `Project paths`, workspaceProjectPaths);
148
149
  workspaceProjectPaths.forEach(projectPath => principal.addProjectPath(projectPath));
149
150
  }
150
151
  {
151
152
  const patterns = [...entryFilePatterns, ...productionEntryFilePatterns];
152
153
  const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns });
153
- debugLogArray(`Found plugin entry paths (${name})`, pluginWorkspaceEntryPaths);
154
+ debugLogArray(name, `Plugin entry paths`, pluginWorkspaceEntryPaths);
154
155
  principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
155
156
  }
156
157
  {
157
158
  const patterns = worker.getPluginProjectFilePatterns();
158
159
  const pluginWorkspaceProjectPaths = await _glob({ ...sharedGlobOptions, patterns });
159
- debugLogArray(`Found plugin project paths (${name})`, pluginWorkspaceProjectPaths);
160
+ debugLogArray(name, `Plugin project paths`, pluginWorkspaceProjectPaths);
160
161
  pluginWorkspaceProjectPaths.forEach(projectPath => principal.addProjectPath(projectPath));
161
162
  }
162
163
  {
163
164
  const patterns = compact(worker.getPluginConfigPatterns());
164
165
  const configurationEntryPaths = await _glob({ ...sharedGlobOptions, patterns });
165
- debugLogArray(`Found plugin configuration paths (${name})`, configurationEntryPaths);
166
+ debugLogArray(name, `Plugin configuration paths`, configurationEntryPaths);
166
167
  principal.addEntryPaths(configurationEntryPaths, { skipExportsAnalysis: true });
167
168
  }
168
169
  }
@@ -171,7 +172,7 @@ export const main = async (unresolvedConfiguration) => {
171
172
  }
172
173
  }
173
174
  const principals = factory.getPrincipals();
174
- debugLog(`Installed ${principals.length} principals for ${workspaces.length} workspaces`);
175
+ debugLog('*', `Installed ${principals.length} principals for ${workspaces.length} workspaces`);
175
176
  const analyzedFiles = new Set();
176
177
  const exportedSymbols = new Map();
177
178
  const importedSymbols = new Map();
@@ -244,7 +245,7 @@ export const main = async (unresolvedConfiguration) => {
244
245
  size = principal.entryPaths.size;
245
246
  const resolvedFiles = principal.getUsedResolvedFiles();
246
247
  const files = resolvedFiles.filter(filePath => !analyzedFiles.has(filePath));
247
- debugLogArray(`Analyzing used resolved files [P${principals.indexOf(principal) + 1}/${++round}]`, files);
248
+ debugLogArray('*', `Analyzing used resolved files [P${principals.indexOf(principal) + 1}/${++round}]`, files);
248
249
  files.forEach(filePath => {
249
250
  analyzeSourceFile(filePath);
250
251
  analyzedFiles.add(filePath);
@@ -1,5 +1,6 @@
1
1
  import { timerify } from '../../util/Performance.js';
2
2
  import { hasDependency, load } from '../../util/plugin.js';
3
+ import { toEntryPattern, toProductionEntryPattern } from '../../util/protocols.js';
3
4
  export const NAME = '';
4
5
  export const ENABLERS = [''];
5
6
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
@@ -7,8 +8,18 @@ export const CONFIG_FILE_PATTERNS = [];
7
8
  export const ENTRY_FILE_PATTERNS = [];
8
9
  export const PRODUCTION_ENTRY_FILE_PATTERNS = [];
9
10
  export const PROJECT_FILE_PATTERNS = [];
10
- const findPluginDependencies = async (configFilePath, { manifest }) => {
11
- const config = configFilePath.endsWith('package.json') ? manifest.plugin : await load(configFilePath);
12
- return config?.plugins ?? [];
11
+ const findPluginDependencies = async (configFilePath, options) => {
12
+ const { manifest, config, isProduction } = options;
13
+ const localConfig = configFilePath.endsWith('package.json')
14
+ ? manifest.plugin
15
+ : await load(configFilePath);
16
+ if (!localConfig)
17
+ return [];
18
+ const entryPatterns = (config?.entry ?? localConfig.entryPathsOrPatterns ?? ENTRY_FILE_PATTERNS).map(toEntryPattern);
19
+ const productionPatterns = config.entry ? [] : PRODUCTION_ENTRY_FILE_PATTERNS.map(toProductionEntryPattern);
20
+ if (isProduction)
21
+ return [...entryPatterns, ...productionPatterns];
22
+ const dependencies = localConfig?.plugins ?? [];
23
+ return [...dependencies, ...entryPatterns, ...productionPatterns];
13
24
  };
14
25
  export const findDependencies = timerify(findPluginDependencies);
@@ -1,3 +1,4 @@
1
1
  export type PluginConfig = {
2
2
  plugins?: string[];
3
+ entryPathsOrPatterns?: string[];
3
4
  };
@@ -6,26 +6,26 @@ export const NAME = 'Angular';
6
6
  export const ENABLERS = ['@angular/cli'];
7
7
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
8
8
  export const CONFIG_FILE_PATTERNS = ['angular.json'];
9
- const findPluginDependencies = async (configFilePath, opts) => {
10
- const { cwd } = opts;
11
- const config = await load(configFilePath);
12
- if (!config.projects)
9
+ const findPluginDependencies = async (configFilePath, options) => {
10
+ const { cwd } = options;
11
+ const localConfig = await load(configFilePath);
12
+ if (!localConfig?.projects)
13
13
  return [];
14
14
  const dependencies = new Set();
15
- for (const project of Object.values(config.projects)) {
15
+ for (const project of Object.values(localConfig.projects)) {
16
16
  if (!project.architect)
17
17
  return [];
18
18
  for (const target of Object.values(project.architect)) {
19
- const { options } = target;
19
+ const { options: opts } = target;
20
20
  const [packageName] = typeof target.builder === 'string' ? target.builder.split(':') : [];
21
21
  if (typeof packageName === 'string')
22
22
  dependencies.add(packageName);
23
- if (options) {
24
- if ('main' in options && typeof options?.main === 'string') {
25
- dependencies.add(join(cwd, options.main));
23
+ if (opts) {
24
+ if ('main' in opts && typeof opts.main === 'string') {
25
+ dependencies.add(join(cwd, opts.main));
26
26
  }
27
- if ('tsConfig' in options && typeof options.tsConfig === 'string') {
28
- const tsConfigDependencies = await findTypeScriptDependencies(join(cwd, options.tsConfig), opts);
27
+ if ('tsConfig' in opts && typeof opts.tsConfig === 'string') {
28
+ const tsConfigDependencies = await findTypeScriptDependencies(join(cwd, opts.tsConfig), options);
29
29
  tsConfigDependencies.forEach(dependency => dependencies.add(dependency));
30
30
  }
31
31
  }
@@ -0,0 +1,7 @@
1
+ import type { GenericPluginCallback, IsPluginEnabledCallback } from '../../types/plugins.js';
2
+ export declare const NAME = "Astro";
3
+ export declare const ENABLERS: string[];
4
+ export declare const isEnabled: IsPluginEnabledCallback;
5
+ export declare const ENTRY_FILE_PATTERNS: string[];
6
+ export declare const PRODUCTION_ENTRY_FILE_PATTERNS: string[];
7
+ export declare const findDependencies: GenericPluginCallback;
@@ -0,0 +1,10 @@
1
+ import { hasDependency } from '../../util/plugin.js';
2
+ import { toEntryPattern, toProductionEntryPattern } from '../../util/protocols.js';
3
+ export const NAME = 'Astro';
4
+ export const ENABLERS = ['astro'];
5
+ export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
6
+ export const ENTRY_FILE_PATTERNS = ['astro.config.{js,cjs,mjs,ts}', 'src/content/config.ts'];
7
+ export const PRODUCTION_ENTRY_FILE_PATTERNS = ['src/pages/**/*.{astro,mdx,js,ts}', 'src/content/**/*.mdx'];
8
+ export const findDependencies = async () => {
9
+ return [...ENTRY_FILE_PATTERNS.map(toEntryPattern), ...PRODUCTION_ENTRY_FILE_PATTERNS.map(toProductionEntryPattern)];
10
+ };
@@ -18,19 +18,20 @@ export const ENTRY_FILE_PATTERNS = [
18
18
  '!**/__tests__/**/__{helper,fixture}?(s)__/**/*',
19
19
  '!**/test?(s)/**/{helper,fixture}?(s)/**/*',
20
20
  ];
21
- const findAvaDependencies = async (configFilePath, { cwd, manifest, isProduction }) => {
22
- let config = configFilePath.endsWith('package.json') ? manifest.ava : await load(configFilePath);
23
- if (typeof config === 'function')
24
- config = config();
25
- const entryPatterns = (config?.files ?? ENTRY_FILE_PATTERNS).map(toEntryPattern);
26
- if (isProduction)
21
+ const findAvaDependencies = async (configFilePath, options) => {
22
+ const { cwd, manifest, isProduction, config } = options;
23
+ let localConfig = configFilePath.endsWith('package.json')
24
+ ? manifest.ava
25
+ : await load(configFilePath);
26
+ if (typeof localConfig === 'function')
27
+ localConfig = localConfig();
28
+ const entryPatterns = (config.entry ?? localConfig?.files ?? ENTRY_FILE_PATTERNS).map(toEntryPattern);
29
+ if (isProduction || !localConfig)
27
30
  return entryPatterns;
28
- if (!config)
29
- return [];
30
- const requireArgs = (config.require ?? []).map(require => `--require ${require}`);
31
- const otherArgs = config.nodeArguments ?? [];
32
- const cmd = `node ${otherArgs.join(' ')} ${requireArgs.join(' ')}`;
33
- const dependencies = _getDependenciesFromScripts([cmd], {
31
+ const nodeArgs = localConfig.nodeArguments ?? [];
32
+ const requireArgs = (localConfig.require ?? []).map(require => `--require ${require}`);
33
+ const fakeCommand = `node ${nodeArgs.join(' ')} ${requireArgs.join(' ')}`;
34
+ const dependencies = _getDependenciesFromScripts([fakeCommand], {
34
35
  cwd,
35
36
  manifest,
36
37
  knownGlobalsOnly: true,