knip 1.1.0 → 1.3.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.
package/README.md CHANGED
@@ -87,7 +87,7 @@ Use `npm run knip` to analyze the project and output unused files, dependencies
87
87
  knip [options]
88
88
 
89
89
  Options:
90
- -c/--config [file] Configuration file path (default: knip.json, knip.jsonc or package.json#knip)
90
+ -c/--config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts or package.json#knip)
91
91
  -t/--tsConfig [file] TypeScript configuration path (default: tsconfig.json)
92
92
  --production Analyze only production source files (e.g. no tests, devDependencies, exported types)
93
93
  --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)
@@ -235,22 +235,24 @@ Knip contains a growing list of plugins:
235
235
  - [Gatsby][16]
236
236
  - [Jest][17]
237
237
  - [lint-staged][18]
238
- - [Mocha][19]
239
- - [Next.js][20]
240
- - [Nx][21]
241
- - [nyc][22]
242
- - [Playwright][23]
243
- - [PostCSS][24]
244
- - [Prettier][25]
245
- - [Release It][26]
246
- - [Remark][27]
247
- - [Remix][28]
248
- - [Rollup][29]
249
- - [Sentry][30]
250
- - [Storybook][31]
251
- - [Stryker][32]
252
- - [TypeScript][33]
253
- - [Webpack][34]
238
+ - [markdownlint][19]
239
+ - [Mocha][20]
240
+ - [Next.js][21]
241
+ - [npm-package-json-lint][22]
242
+ - [Nx][23]
243
+ - [nyc][24]
244
+ - [Playwright][25]
245
+ - [PostCSS][26]
246
+ - [Prettier][27]
247
+ - [Release It][28]
248
+ - [Remark][29]
249
+ - [Remix][30]
250
+ - [Rollup][31]
251
+ - [Sentry][32]
252
+ - [Storybook][33]
253
+ - [Stryker][34]
254
+ - [TypeScript][35]
255
+ - [Webpack][36]
254
256
 
255
257
  Plugins are automatically activated, no need to enable anything. Each plugin is automatically enabled based on simple
256
258
  heuristics. Most of them check whether one or one of a few (dev) dependencies are listed in `package.json`. Once
@@ -258,7 +260,7 @@ enabled, they add a set of configuration and/or entry files for Knip to analyze.
258
260
 
259
261
  Most plugins use one or both of the following file types:
260
262
 
261
- - `config` - custom dependency resolvers are applied to the [config files][35]
263
+ - `config` - custom dependency resolvers are applied to the [config files][37]
262
264
  - `entry` - files to include with the analysis of the rest of the source code
263
265
 
264
266
  See each plugin's documentation for its default values.
@@ -338,10 +340,10 @@ locations. The more plugins Knip will have, the more projects can be analyzed ou
338
340
 
339
341
  Knip provides the following built-in reporters:
340
342
 
341
- - [`codeowners`][36]
342
- - [`compact`][37]
343
- - [`json`][38]
344
- - [`symbol`][39] (default)
343
+ - [`codeowners`][38]
344
+ - [`compact`][39]
345
+ - [`json`][40]
346
+ - [`symbol`][41] (default)
345
347
 
346
348
  The `compact` reporter shows the sorted files first, and then a list of symbols:
347
349
 
@@ -368,7 +370,7 @@ type ReporterOptions = {
368
370
 
369
371
  The data can then be used to write issues to `stdout`, a JSON or CSV file, or sent to a service.
370
372
 
371
- Find more details and ideas in [custom reporters][40].
373
+ Find more details and ideas in [custom reporters][42].
372
374
 
373
375
  ## Libraries and "unused" exports
374
376
 
@@ -425,14 +427,14 @@ When unused dependencies are related to dependencies having a Knip [plugin][1],
425
427
  for that dependency are at custom locations. The default values are at the plugin's documentation, and can be overridden
426
428
  to match the custom location(s).
427
429
 
428
- When the dependencies don't have a Knip plugin yet, please file an issue or [create a new plugin][41].
430
+ When the dependencies don't have a Knip plugin yet, please file an issue or [create a new plugin][43].
429
431
 
430
432
  #### Too many unused exports
431
433
 
432
434
  When the project is a library and the exports are meant to be used by consumers of the library, there are two options:
433
435
 
434
436
  1. By default, unused exports of `entry` files are not reported, so you can add the containing file to it.
435
- 2. The exported values or types can be marked [using the JSDoc `@public` tag][42].
437
+ 2. The exported values or types can be marked [using the JSDoc `@public` tag][44].
436
438
 
437
439
  ### How to start using Knip in CI while having too many issues to sort out?
438
440
 
@@ -449,7 +451,7 @@ All of this is hiding problems, so please make sure to plan for fixing them and/
449
451
 
450
452
  This table is an ongoing comparison. Based on their docs (please report any mistakes):
451
453
 
452
- | Feature | **knip** | [depcheck][43] | [unimported][44] | [ts-unused-exports][45] | [ts-prune][46] |
454
+ | Feature | **knip** | [depcheck][45] | [unimported][46] | [ts-unused-exports][47] | [ts-prune][48] |
453
455
  | :--------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
454
456
  | Unused files | ✅ | - | ✅ | - | - |
455
457
  | Unused dependencies | ✅ | ✅ | ✅ | - | - |
@@ -463,7 +465,7 @@ This table is an ongoing comparison. Based on their docs (please report any mist
463
465
  | Custom reporters | ✅ | - | - | - | - |
464
466
  | JavaScript support | ✅ | ✅ | ✅ | - | - |
465
467
  | Configure entry files | ✅ | ❌ | ✅ | ❌ | ❌ |
466
- | [Support workspaces/monorepos][47] | ✅ | ❌ | ❌ | - | - |
468
+ | [Support workspaces/monorepos][49] | ✅ | ❌ | ❌ | - | - |
467
469
  | ESLint plugin available | - | - | - | ✅ | - |
468
470
 
469
471
  ✅ = Supported, ❌ = Not supported, - = Out of scope
@@ -484,7 +486,7 @@ The following commands are similar:
484
486
  unimported
485
487
  knip --production --dependencies --include files
486
488
 
487
- Also see [production mode][48].
489
+ Also see [production mode][50].
488
490
 
489
491
  ### ts-unused-exports
490
492
 
@@ -532,33 +534,35 @@ for the job. I'm motivated to make knip perfectly suited for the job of cutting
532
534
  [16]: ./src/plugins/gatsby
533
535
  [17]: ./src/plugins/jest
534
536
  [18]: ./src/plugins/lint-staged
535
- [19]: ./src/plugins/mocha
536
- [20]: ./src/plugins/next
537
- [21]: ./src/plugins/nx
538
- [22]: ./src/plugins/nyc
539
- [23]: ./src/plugins/playwright
540
- [24]: ./src/plugins/postcss
541
- [25]: ./src/plugins/prettier
542
- [26]: ./src/plugins/release-it
543
- [27]: ./src/plugins/remark
544
- [28]: ./src/plugins/remix
545
- [29]: ./src/plugins/rollup
546
- [30]: ./src/plugins/sentry
547
- [31]: ./src/plugins/storybook
548
- [32]: ./src/plugins/stryker
549
- [33]: ./src/plugins/typescript
550
- [34]: ./src/plugins/webpack
551
- [35]: #config
552
- [36]: #code-owners
553
- [37]: #compact
554
- [38]: #json
555
- [39]: #symbol-default
556
- [40]: ./docs/custom-reporters.md
557
- [41]: #create-a-new-plugin
558
- [42]: #libraries-and-unused-exports
559
- [43]: https://github.com/depcheck/depcheck
560
- [44]: https://github.com/smeijer/unimported
561
- [45]: https://github.com/pzavolinsky/ts-unused-exports
562
- [46]: https://github.com/nadeesha/ts-prune
563
- [47]: #workspaces--monorepos
564
- [48]: #production-mode
537
+ [19]: ./src/plugins/markdownlint
538
+ [20]: ./src/plugins/mocha
539
+ [21]: ./src/plugins/next
540
+ [22]: ./src/plugins/npm-package-json-lint
541
+ [23]: ./src/plugins/nx
542
+ [24]: ./src/plugins/nyc
543
+ [25]: ./src/plugins/playwright
544
+ [26]: ./src/plugins/postcss
545
+ [27]: ./src/plugins/prettier
546
+ [28]: ./src/plugins/release-it
547
+ [29]: ./src/plugins/remark
548
+ [30]: ./src/plugins/remix
549
+ [31]: ./src/plugins/rollup
550
+ [32]: ./src/plugins/sentry
551
+ [33]: ./src/plugins/storybook
552
+ [34]: ./src/plugins/stryker
553
+ [35]: ./src/plugins/typescript
554
+ [36]: ./src/plugins/webpack
555
+ [37]: #config
556
+ [38]: #code-owners
557
+ [39]: #compact
558
+ [40]: #json
559
+ [41]: #symbol-default
560
+ [42]: ./docs/custom-reporters.md
561
+ [43]: #create-a-new-plugin
562
+ [44]: #libraries-and-unused-exports
563
+ [45]: https://github.com/depcheck/depcheck
564
+ [46]: https://github.com/smeijer/unimported
565
+ [47]: https://github.com/pzavolinsky/ts-unused-exports
566
+ [48]: https://github.com/nadeesha/ts-prune
567
+ [49]: #workspaces--monorepos
568
+ [50]: #production-mode
@@ -2,21 +2,19 @@ import path from 'node:path';
2
2
  import mapWorkspaces from '@npmcli/map-workspaces';
3
3
  import micromatch from 'micromatch';
4
4
  import { ConfigurationValidator } from './configuration-validator.js';
5
- import { ROOT_WORKSPACE_NAME } from './constants.js';
5
+ import { ROOT_WORKSPACE_NAME, DEFAULT_WORKSPACE_CONFIG, KNIP_CONFIG_LOCATIONS } from './constants.js';
6
6
  import * as plugins from './plugins/index.js';
7
7
  import { arrayify } from './util/array.js';
8
8
  import parsedArgs from './util/cli-arguments.js';
9
9
  import { ConfigurationError } from './util/errors.js';
10
10
  import { findFile, loadJSON } from './util/fs.js';
11
11
  import { ensurePosixPath } from './util/glob.js';
12
+ import { _load } from './util/loader.js';
13
+ import { toCamelCase } from './util/plugin.js';
12
14
  import { resolveIncludedIssueTypes } from './util/resolve-included-issue-types.js';
13
15
  import { byPathDepth } from './util/workspace.js';
14
16
  const { values: { config: rawConfigArg, workspace: rawWorkspaceArg, include = [], exclude = [], dependencies = false, exports = false, }, } = parsedArgs;
15
- const defaultWorkspaceConfig = {
16
- entry: ['index.{js,ts,tsx}!', 'src/index.{js,ts,tsx}!'],
17
- project: ['**/*.{js,ts,tsx}!'],
18
- ignore: [],
19
- };
17
+ const defaultWorkspaceConfig = DEFAULT_WORKSPACE_CONFIG;
20
18
  const defaultConfig = {
21
19
  include: [],
22
20
  exclude: [],
@@ -49,12 +47,16 @@ export default class ConfigurationChief {
49
47
  }
50
48
  this.manifestPath = manifestPath;
51
49
  this.manifest = manifest;
52
- const configFilePath = rawConfigArg ?? 'knip.json';
53
- const resolvedConfigFilePath = (await findFile(this.cwd, configFilePath)) ?? (!rawConfigArg && (await findFile(this.cwd, configFilePath + 'c')));
50
+ let resolvedConfigFilePath;
51
+ for (const configPath of rawConfigArg ? [rawConfigArg] : KNIP_CONFIG_LOCATIONS) {
52
+ resolvedConfigFilePath = await findFile(this.cwd, configPath);
53
+ if (resolvedConfigFilePath)
54
+ break;
55
+ }
54
56
  if (rawConfigArg && !resolvedConfigFilePath && !manifest.knip) {
55
57
  throw new ConfigurationError(`Unable to find ${rawConfigArg} or package.json#knip`);
56
58
  }
57
- const rawLocalConfig = resolvedConfigFilePath ? await loadJSON(resolvedConfigFilePath) : manifest.knip;
59
+ const rawLocalConfig = resolvedConfigFilePath ? await _load(resolvedConfigFilePath) : manifest.knip;
58
60
  if (rawLocalConfig) {
59
61
  this.config = this.normalize(ConfigurationValidator.parse(rawLocalConfig));
60
62
  }
@@ -94,16 +96,17 @@ export default class ConfigurationChief {
94
96
  ignore: arrayify(workspaceConfig.ignore),
95
97
  };
96
98
  for (const [pluginName, pluginConfig] of Object.entries(workspaceConfig)) {
97
- if (PLUGIN_NAMES.includes(pluginName)) {
99
+ const name = toCamelCase(pluginName);
100
+ if (PLUGIN_NAMES.includes(name)) {
98
101
  if (pluginConfig === false) {
99
- workspaces[workspaceName][pluginName] = false;
102
+ workspaces[workspaceName][name] = false;
100
103
  }
101
104
  else {
102
105
  const isObject = typeof pluginConfig !== 'string' && !Array.isArray(pluginConfig);
103
106
  const config = isObject ? arrayify(pluginConfig.config) : pluginConfig ? arrayify(pluginConfig) : null;
104
107
  const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) : null;
105
108
  const project = isObject && 'project' in pluginConfig ? arrayify(pluginConfig.project) : entry;
106
- workspaces[workspaceName][pluginName] = {
109
+ workspaces[workspaceName][name] = {
107
110
  config,
108
111
  entry,
109
112
  project,
@@ -158,6 +158,19 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
158
158
  entry?: string | string[] | undefined;
159
159
  project?: string | string[] | undefined;
160
160
  }>]>>;
161
+ 'npm-package-json-lint': z.ZodOptional<z.ZodUnion<[z.ZodLiteral<false>, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
162
+ config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
163
+ entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
164
+ project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
165
+ }, "strip", z.ZodTypeAny, {
166
+ config?: string | string[] | undefined;
167
+ entry?: string | string[] | undefined;
168
+ project?: string | string[] | undefined;
169
+ }, {
170
+ config?: string | string[] | undefined;
171
+ entry?: string | string[] | undefined;
172
+ project?: string | string[] | undefined;
173
+ }>]>>;
161
174
  nx: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<false>, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
162
175
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
163
176
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -399,6 +412,11 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
399
412
  entry?: string | string[] | undefined;
400
413
  project?: string | string[] | undefined;
401
414
  } | undefined;
415
+ 'npm-package-json-lint'?: string | false | string[] | {
416
+ config?: string | string[] | undefined;
417
+ entry?: string | string[] | undefined;
418
+ project?: string | string[] | undefined;
419
+ } | undefined;
402
420
  nx?: string | false | string[] | {
403
421
  config?: string | string[] | undefined;
404
422
  entry?: string | string[] | undefined;
@@ -528,6 +546,11 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
528
546
  entry?: string | string[] | undefined;
529
547
  project?: string | string[] | undefined;
530
548
  } | undefined;
549
+ 'npm-package-json-lint'?: string | false | string[] | {
550
+ config?: string | string[] | undefined;
551
+ entry?: string | string[] | undefined;
552
+ project?: string | string[] | undefined;
553
+ } | undefined;
531
554
  nx?: string | false | string[] | {
532
555
  config?: string | string[] | undefined;
533
556
  entry?: string | string[] | undefined;
@@ -743,6 +766,19 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
743
766
  entry?: string | string[] | undefined;
744
767
  project?: string | string[] | undefined;
745
768
  }>]>>;
769
+ 'npm-package-json-lint': z.ZodOptional<z.ZodUnion<[z.ZodLiteral<false>, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
770
+ config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
771
+ entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
772
+ project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
773
+ }, "strip", z.ZodTypeAny, {
774
+ config?: string | string[] | undefined;
775
+ entry?: string | string[] | undefined;
776
+ project?: string | string[] | undefined;
777
+ }, {
778
+ config?: string | string[] | undefined;
779
+ entry?: string | string[] | undefined;
780
+ project?: string | string[] | undefined;
781
+ }>]>>;
746
782
  nx: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<false>, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
747
783
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
748
784
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -989,6 +1025,11 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
989
1025
  entry?: string | string[] | undefined;
990
1026
  project?: string | string[] | undefined;
991
1027
  } | undefined;
1028
+ 'npm-package-json-lint'?: string | false | string[] | {
1029
+ config?: string | string[] | undefined;
1030
+ entry?: string | string[] | undefined;
1031
+ project?: string | string[] | undefined;
1032
+ } | undefined;
992
1033
  nx?: string | false | string[] | {
993
1034
  config?: string | string[] | undefined;
994
1035
  entry?: string | string[] | undefined;
@@ -1118,6 +1159,11 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
1118
1159
  entry?: string | string[] | undefined;
1119
1160
  project?: string | string[] | undefined;
1120
1161
  } | undefined;
1162
+ 'npm-package-json-lint'?: string | false | string[] | {
1163
+ config?: string | string[] | undefined;
1164
+ entry?: string | string[] | undefined;
1165
+ project?: string | string[] | undefined;
1166
+ } | undefined;
1121
1167
  nx?: string | false | string[] | {
1122
1168
  config?: string | string[] | undefined;
1123
1169
  entry?: string | string[] | undefined;
@@ -1253,6 +1299,11 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
1253
1299
  entry?: string | string[] | undefined;
1254
1300
  project?: string | string[] | undefined;
1255
1301
  } | undefined;
1302
+ 'npm-package-json-lint'?: string | false | string[] | {
1303
+ config?: string | string[] | undefined;
1304
+ entry?: string | string[] | undefined;
1305
+ project?: string | string[] | undefined;
1306
+ } | undefined;
1256
1307
  nx?: string | false | string[] | {
1257
1308
  config?: string | string[] | undefined;
1258
1309
  entry?: string | string[] | undefined;
@@ -1382,6 +1433,11 @@ export declare const ConfigurationValidator: z.ZodObject<z.extendShape<z.extendS
1382
1433
  entry?: string | string[] | undefined;
1383
1434
  project?: string | string[] | undefined;
1384
1435
  } | undefined;
1436
+ 'npm-package-json-lint'?: string | false | string[] | {
1437
+ config?: string | string[] | undefined;
1438
+ entry?: string | string[] | undefined;
1439
+ project?: string | string[] | undefined;
1440
+ } | undefined;
1385
1441
  nx?: string | false | string[] | {
1386
1442
  config?: string | string[] | undefined;
1387
1443
  entry?: string | string[] | undefined;
@@ -33,6 +33,7 @@ const pluginsSchema = z.object({
33
33
  'lint-staged': pluginSchema,
34
34
  mocha: pluginSchema,
35
35
  next: pluginSchema,
36
+ 'npm-package-json-lint': pluginSchema,
36
37
  nx: pluginSchema,
37
38
  nyc: pluginSchema,
38
39
  playwright: pluginSchema,
@@ -1,5 +1,11 @@
1
1
  import type { IssueType } from './types/issues.js';
2
2
  export declare const ROOT_WORKSPACE_NAME = ".";
3
+ export declare const KNIP_CONFIG_LOCATIONS: string[];
4
+ export declare const DEFAULT_WORKSPACE_CONFIG: {
5
+ entry: string[];
6
+ project: string[];
7
+ ignore: never[];
8
+ };
3
9
  export declare const TEST_FILE_PATTERNS: string[];
4
10
  export declare const IGNORED_GLOBAL_BINARIES: string[];
5
11
  export declare const IGNORE_DEFINITELY_TYPED: string[];
package/dist/constants.js CHANGED
@@ -1,4 +1,10 @@
1
1
  export const ROOT_WORKSPACE_NAME = '.';
2
+ export const KNIP_CONFIG_LOCATIONS = ['knip.json', 'knip.jsonc', '.knip.json', '.knip.jsonc', 'knip.ts', 'knip.js'];
3
+ export const DEFAULT_WORKSPACE_CONFIG = {
4
+ entry: ['index.{js,ts,tsx}!', 'src/index.{js,ts,tsx}!'],
5
+ project: ['**/*.{js,ts,tsx}!'],
6
+ ignore: [],
7
+ };
2
8
  export const TEST_FILE_PATTERNS = ['**/*.{test,spec}.{js,jsx,ts,tsx}', '**/__tests__/**/*.{js,jsx,ts,tsx}'];
3
9
  export const IGNORED_GLOBAL_BINARIES = ['npm', 'npx', 'node', 'yarn', 'pnpm', 'deno', 'git'];
4
10
  export const IGNORE_DEFINITELY_TYPED = ['node'];
@@ -1,14 +1,10 @@
1
1
  import path from 'node:path';
2
2
  import { FIRST_ARGUMENT_AS_BINARY_EXCEPTIONS } from '../constants.js';
3
+ import { getArgumentValues } from '../util/plugin.js';
3
4
  import { require } from '../util/require.js';
4
5
  const normalizeBinaries = (command) => command.replace(/(\.\/)?node_modules\/\.bin\/(\w+)/, '$2').replace(/\$\(npm bin\)\/(\w+)/, '$1');
5
6
  const stripEnvironmentVariables = (value) => value.replace(/([A-Z][^ ]*)=([^ ])+ /g, '');
6
- const getLoaderArgumentValues = (value) => {
7
- const match = value.match(/ (--(experimental-)?loader|--require|-r)[ =]([^ ]+)/g);
8
- if (match)
9
- return match.map(value => value.trim().split(/[ =]/)[1].trim());
10
- return [];
11
- };
7
+ const getLoaderArgumentValues = (value) => getArgumentValues(value, / (--(experimental-)?loader|--require|-r)[ =]([^ ]+)/g);
12
8
  const getDependenciesFromLoaderArguments = (args) => getLoaderArgumentValues(' ' + args.join(' '))
13
9
  .filter(scripts => !scripts.startsWith('.'))
14
10
  .map(script => {
@@ -7,8 +7,10 @@ export * as eslint from './eslint/index.js';
7
7
  export * as gatsby from './gatsby/index.js';
8
8
  export * as jest from './jest/index.js';
9
9
  export * as lintStaged from './lint-staged/index.js';
10
+ export * as markdownlint from './markdownlint/index.js';
10
11
  export * as mocha from './mocha/index.js';
11
12
  export * as next from './next/index.js';
13
+ export * as npmPackageJsonLint from './npm-package-json-lint/index.js';
12
14
  export * as nx from './nx/index.js';
13
15
  export * as nyc from './nyc/index.js';
14
16
  export * as playwright from './playwright/index.js';
@@ -7,8 +7,10 @@ export * as eslint from './eslint/index.js';
7
7
  export * as gatsby from './gatsby/index.js';
8
8
  export * as jest from './jest/index.js';
9
9
  export * as lintStaged from './lint-staged/index.js';
10
+ export * as markdownlint from './markdownlint/index.js';
10
11
  export * as mocha from './mocha/index.js';
11
12
  export * as next from './next/index.js';
13
+ export * as npmPackageJsonLint from './npm-package-json-lint/index.js';
12
14
  export * as nx from './nx/index.js';
13
15
  export * as nyc from './nyc/index.js';
14
16
  export * as playwright from './playwright/index.js';
@@ -0,0 +1,6 @@
1
+ import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
2
+ export declare const NAME = "markdownlint";
3
+ export declare const ENABLERS: string[];
4
+ export declare const isEnabled: IsPluginEnabledCallback;
5
+ export declare const CONFIG_FILE_PATTERNS: string[];
6
+ export declare const findDependencies: GenericPluginCallback;
@@ -0,0 +1,20 @@
1
+ import { _load } from '../../util/loader.js';
2
+ import { getPackageName } from '../../util/modules.js';
3
+ import { timerify } from '../../util/performance.js';
4
+ import { hasDependency, getArgumentValues } from '../../util/plugin.js';
5
+ export const NAME = 'markdownlint';
6
+ export const ENABLERS = ['markdownlint-cli'];
7
+ export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
8
+ export const CONFIG_FILE_PATTERNS = ['.markdownlint.{json,jsonc}', '.markdownlint.{yml,yaml}'];
9
+ const findMarkdownlintConfigDependencies = async (configFilePath, { manifest }) => {
10
+ const config = await _load(configFilePath);
11
+ const extend = config?.extends ? [getPackageName(config.extends)] : [];
12
+ const scripts = manifest.scripts
13
+ ? Object.values(manifest.scripts).filter((script) => typeof script === 'string')
14
+ : [];
15
+ const uses = scripts
16
+ .filter(script => script.includes('markdownlint '))
17
+ .flatMap(script => getArgumentValues(script, / (--rules|-r)[ =]([^ ]+)/g));
18
+ return [...extend, ...uses];
19
+ };
20
+ export const findDependencies = timerify(findMarkdownlintConfigDependencies);
@@ -0,0 +1,3 @@
1
+ export type MarkdownlintConfig = {
2
+ extends?: string;
3
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
2
+ export declare const NAME = "npm-package-json-lint";
3
+ export declare const ENABLERS: string[];
4
+ export declare const isEnabled: IsPluginEnabledCallback;
5
+ export declare const CONFIG_FILE_PATTERNS: string[];
6
+ export declare const findDependencies: GenericPluginCallback;
@@ -0,0 +1,14 @@
1
+ import { _load } from '../../util/loader.js';
2
+ import { timerify } from '../../util/performance.js';
3
+ import { hasDependency } from '../../util/plugin.js';
4
+ export const NAME = 'npm-package-json-lint';
5
+ export const ENABLERS = ['npm-package-json-lint'];
6
+ export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
7
+ export const CONFIG_FILE_PATTERNS = ['.npmpackagejsonlintrc.json', 'npmpackagejsonlint.config.js', 'package.json'];
8
+ const findNpmPkgJsonLintConfigDependencies = async (configFilePath, { manifest }) => {
9
+ const config = configFilePath.endsWith('package.json')
10
+ ? manifest.npmpackagejsonlint
11
+ : await _load(configFilePath);
12
+ return config?.extends ? [config.extends] : [];
13
+ };
14
+ export const findDependencies = timerify(findNpmPkgJsonLintConfigDependencies);
@@ -0,0 +1,3 @@
1
+ export type NpmPkgJsonLintConfig = {
2
+ extends?: string;
3
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- export declare const helpText = "knip [options]\n\nOptions:\n -c/--config [file] Configuration file path (default: knip.json, knip.jsonc or package.json#knip)\n -t/--tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --workspace Analyze a single workspace (default: analyze all configured workspaces)\n --include-entry-exports Include unused exports in entry files (without `@public`)\n --ignore Ignore files matching this glob pattern, can be repeated\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --no-progress Don't show dynamic progress updates\n --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n --debug Show debug output\n --debug-file-filter Filter for files in debug output (regex as string)\n --performance Measure running time of expensive functions and display stats table\n\n(1) Issue types: files, dependencies, unlisted, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --debug --debug-file-filter '(specific|particular)-module'\n\nMore info: https://github.com/webpro/knip";
1
+ export declare const helpText = "knip [options]\n\nOptions:\n -c/--config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts or package.json#knip)\n -t/--tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --workspace Analyze a single workspace (default: analyze all configured workspaces)\n --include-entry-exports Include unused exports in entry files (without `@public`)\n --ignore Ignore files matching this glob pattern, can be repeated\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --no-progress Don't show dynamic progress updates\n --reporter Select reporter: symbols, compact, codeowners, json (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n --debug Show debug output\n --debug-file-filter Filter for files in debug output (regex as string)\n --performance Measure running time of expensive functions and display stats table\n\n(1) Issue types: files, dependencies, unlisted, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --debug --debug-file-filter '(specific|particular)-module'\n\nMore info: https://github.com/webpro/knip";
2
2
  declare const _default: {
3
3
  values: {
4
4
  config: string | undefined;
@@ -2,7 +2,7 @@ import { parseArgs } from 'node:util';
2
2
  export const helpText = `knip [options]
3
3
 
4
4
  Options:
5
- -c/--config [file] Configuration file path (default: knip.json, knip.jsonc or package.json#knip)
5
+ -c/--config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts or package.json#knip)
6
6
  -t/--tsConfig [file] TypeScript configuration path (default: tsconfig.json)
7
7
  --production Analyze only production source files (e.g. no tests, devDependencies, exported types)
8
8
  --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)
@@ -8,7 +8,7 @@ import { logIfDebug } from './log.js';
8
8
  import { timerify } from './performance.js';
9
9
  const load = async (filePath) => {
10
10
  try {
11
- if (path.extname(filePath) === '.json' || /rc$/.test(filePath)) {
11
+ if (/\.jsonc?$/.test(filePath) || /rc$/.test(filePath)) {
12
12
  return loadJSON(filePath);
13
13
  }
14
14
  if (path.extname(filePath) === '.yaml' || path.extname(filePath) === '.yml') {
@@ -1 +1,3 @@
1
+ export declare const toCamelCase: (name: string) => string;
2
+ export declare const getArgumentValues: (value: string, matcher: RegExp) => string[];
1
3
  export declare const hasDependency: (dependencies: Set<string>, values: (string | RegExp)[]) => boolean;
@@ -1,3 +1,10 @@
1
+ export const toCamelCase = (name) => name.toLowerCase().replace(/(-[a-z])/g, group => group.toUpperCase().replace('-', ''));
2
+ export const getArgumentValues = (value, matcher) => {
3
+ const match = value.match(matcher);
4
+ if (match)
5
+ return match.map(value => value.trim().split(/[ =]/)[1].trim());
6
+ return [];
7
+ };
1
8
  export const hasDependency = (dependencies, values) => values.some(value => {
2
9
  if (typeof value === 'string') {
3
10
  return dependencies.has(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",
@@ -42,7 +42,7 @@
42
42
  "@snyk/github-codeowners": "1.1.0",
43
43
  "chalk": "5.2.0",
44
44
  "easy-table": "1.2.0",
45
- "esbuild": "0.16.16",
45
+ "esbuild": "0.16.17",
46
46
  "esbuild-register": "3.4.2",
47
47
  "eslint": "8.31.0",
48
48
  "fast-glob": "3.2.12",
package/schema.json CHANGED
@@ -192,6 +192,10 @@
192
192
  "title": "lint-staged plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/lint-staged/README.md)",
193
193
  "$ref": "#/definitions/plugin"
194
194
  },
195
+ "markdownlint": {
196
+ "title": "markdownlint plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/markdownlint/README.md)",
197
+ "$ref": "#/definitions/plugin"
198
+ },
195
199
  "mocha": {
196
200
  "title": "Mocha plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/mocha/README.md)",
197
201
  "$ref": "#/definitions/plugin"
@@ -200,6 +204,10 @@
200
204
  "title": "Next.js plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/main/README.md)",
201
205
  "$ref": "#/definitions/plugin"
202
206
  },
207
+ "npm-package-json-lint": {
208
+ "title": "npm-package-json-lint plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/npm-package-json-lint/README.md)",
209
+ "$ref": "#/definitions/plugin"
210
+ },
203
211
  "nx": {
204
212
  "title": "Nx plugin configuration (https://github.com/webpro/knip/blob/main/src/plugins/nx/README.md)",
205
213
  "$ref": "#/definitions/plugin"