knip 2.0.0-alpha.1 → 2.0.0-alpha.3

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 (41) hide show
  1. package/README.md +46 -49
  2. package/dist/cli.js +2 -3
  3. package/dist/configuration-chief.js +7 -8
  4. package/dist/constants.js +5 -1
  5. package/dist/index.js +2 -2
  6. package/dist/issue-collector.js +2 -2
  7. package/dist/manifest/helpers.js +3 -3
  8. package/dist/plugins/eslint/helpers.js +2 -3
  9. package/dist/plugins/jest/index.d.ts +1 -1
  10. package/dist/plugins/jest/index.js +6 -7
  11. package/dist/plugins/mocha/index.d.ts +1 -1
  12. package/dist/plugins/mocha/index.js +1 -1
  13. package/dist/plugins/playwright/index.js +1 -1
  14. package/dist/plugins/storybook/index.js +2 -3
  15. package/dist/plugins/typedoc/index.js +1 -1
  16. package/dist/plugins/typedoc/types.d.ts +1 -1
  17. package/dist/plugins/vitest/index.d.ts +1 -1
  18. package/dist/plugins/vitest/index.js +1 -1
  19. package/dist/plugins/webpack/index.js +2 -3
  20. package/dist/principal-factory.js +3 -4
  21. package/dist/project-principal.js +4 -5
  22. package/dist/reporters/codeowners.js +4 -5
  23. package/dist/reporters/json.js +3 -4
  24. package/dist/reporters/symbols.js +2 -2
  25. package/dist/reporters/util.js +3 -3
  26. package/dist/typescript/SourceFileManager.js +3 -3
  27. package/dist/typescript/createHosts.js +2 -2
  28. package/dist/typescript/resolveModuleNames.js +2 -3
  29. package/dist/util/binaries/resolvers/node.js +2 -3
  30. package/dist/util/fs.js +4 -4
  31. package/dist/util/glob.js +4 -5
  32. package/dist/util/loader.js +2 -2
  33. package/dist/util/modules.js +2 -2
  34. package/dist/util/path.d.ts +7 -2
  35. package/dist/util/path.js +8 -4
  36. package/dist/util/require.d.ts +1 -1
  37. package/dist/util/require.js +4 -2
  38. package/dist/version.d.ts +1 -1
  39. package/dist/version.js +1 -1
  40. package/dist/workspace-worker.js +2 -2
  41. package/package.json +12 -11
package/README.md CHANGED
@@ -196,8 +196,8 @@ Use `--exclude` to ignore reports you're not interested in:
196
196
 
197
197
  Use `--dependencies` or `--exports` as shortcuts to combine groups of related types.
198
198
 
199
- Still not happy with the results? Getting too much output/false positives? The [FAQ][9] may be useful. Feel free to open
200
- an issue and I'm happy to look into it. Also see the next section on how to [ignore][11] certain false positives:
199
+ Still not happy with the results? Getting too much output/false positives? The [FAQ][10] may be useful. Feel free to
200
+ open an issue and I'm happy to look into it. Also see the next section on how to [ignore][11] certain false positives:
201
201
 
202
202
  ## Ignore
203
203
 
@@ -345,6 +345,14 @@ rest to find which of those dependencies are unused or missing.
345
345
  Other configuration files use `require` or `import` statements to use dependencies, so they can be analyzed like the
346
346
  rest of the source files. These configuration files are also considered `entry` files.
347
347
 
348
+ For plugins related to test files, it's good to know that the following glob patterns are always included by default:
349
+
350
+ - `**/*.{test,spec}.{js,jsx,ts,tsx,mjs,cjs}`
351
+ - `**/__tests__/**/*.{js,jsx,ts,tsx,mjs,cjs}`
352
+ - `**/test/**/*.{js,jsx,ts,tsx,mjs,cjs}`
353
+
354
+ Files matching these patterns are excluded in [production mode][45].
355
+
348
356
  ### Disable a plugin
349
357
 
350
358
  In case a plugin causes issues, it can be disabled by using `false` as its value (e.g. `"webpack": false`).
@@ -440,10 +448,10 @@ Each workspace can also have its own `paths` configured. Note that Knip `paths`
440
448
 
441
449
  Knip provides the following built-in reporters:
442
450
 
443
- - [`codeowners`][45]
444
- - [`compact`][46]
445
- - [`json`][47]
446
- - [`symbol`][48] (default)
451
+ - codeowners
452
+ - compact
453
+ - json
454
+ - symbol
447
455
 
448
456
  The `compact` reporter shows the sorted files first, and then a list of symbols:
449
457
 
@@ -470,13 +478,12 @@ type ReporterOptions = {
470
478
 
471
479
  The data can then be used to write issues to `stdout`, a JSON or CSV file, or sent to a service.
472
480
 
473
- Find more details and ideas in [custom reporters][49].
481
+ Find more details and ideas in [custom reporters][46].
474
482
 
475
- ## Libraries and "unused" exports
483
+ ## Public exports
476
484
 
477
- Libraries and applications are identical when it comes to files and dependencies: whatever is unused should be removed.
478
- Yet libraries usually have exports meant to be used by other libraries or applications. Such public variables and types
479
- in libraries can be marked with the JSDoc `@public` tag:
485
+ Sometimes a file that's not an entry file has one or more exports that are public, and should not be reported as unused.
486
+ Such variables and types can be marked with the JSDoc `@public` tag:
480
487
 
481
488
  ```js
482
489
  /**
@@ -528,7 +535,7 @@ When unused dependencies are related to dependencies having a Knip [plugin][1],
528
535
  for that dependency are at custom locations. The default values are at the plugin's documentation, and can be overridden
529
536
  to match the custom location(s).
530
537
 
531
- When the dependencies don't have a Knip plugin yet, please file an issue or [create a new plugin][50].
538
+ When the dependencies don't have a Knip plugin yet, please file an issue or [create a new plugin][47].
532
539
 
533
540
  #### Too many unused exports
534
541
 
@@ -536,7 +543,7 @@ When the project is a library and the exports are meant to be used by consumers
536
543
 
537
544
  1. By default, unused exports of `entry` files are not reported. You could re-export from an existing entry file, or
538
545
  add the containing file to the `entry` array in the configuration.
539
- 2. The exported values or types can be marked [using the JSDoc `@public` tag][51].
546
+ 2. The exported values or types can be marked [using the JSDoc `@public` tag][48]
540
547
 
541
548
  ### How to start using Knip in CI while having too many issues to sort out?
542
549
 
@@ -556,22 +563,23 @@ All of this is hiding problems, so please make sure to plan for fixing them and/
556
563
 
557
564
  This table is an ongoing comparison. Based on their docs (please report any mistakes):
558
565
 
559
- | Feature | **knip** | [depcheck][52] | [unimported][53] | [ts-unused-exports][54] | [ts-prune][55] |
560
- | :--------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
561
- | Unused files | ✅ | - | ✅ | - | - |
562
- | Unused dependencies | ✅ | ✅ | ✅ | - | - |
563
- | Unlisted dependencies | ✅ | ✅ | ✅ | - | - |
564
- | [Plugins][1] | ✅ | ✅ | ❌ | - | - |
565
- | Unused exports | ✅ | - | - | | |
566
- | Unused class members | ✅ | - | - | - | - |
567
- | Unused enum members | ✅ | - | - | - | - |
568
- | Duplicate exports | ✅ | - | - | | |
569
- | Search namespaces | ✅ | - | - | | ❌ |
570
- | Custom reporters | ✅ | - | - | - | - |
571
- | JavaScript support | ✅ | | | - | - |
572
- | Configure entry files | ✅ | | ✅ | | |
573
- | [Support workspaces/monorepos][52] | ✅ | ❌ | | - | - |
574
- | ESLint plugin available | - | - | - | | - |
566
+ | Feature | **knip** | [depcheck][49] | [unimported][50] | [ts-unused-exports][51] | [ts-prune][52] |
567
+ | :-------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
568
+ | Unused files | ✅ | - | ✅ | - | - |
569
+ | Unused dependencies | ✅ | ✅ | ✅ | - | - |
570
+ | Unlisted dependencies | ✅ | ✅ | ✅ | - | - |
571
+ | [Plugins][2] | ✅ | ✅ | ❌ | - | - |
572
+ | [Compilers][3] | ✅ | - | - | - | - |
573
+ | Unused exports | ✅ | - | - | | |
574
+ | Unused class members | ✅ | - | - | - | - |
575
+ | Unused enum members | ✅ | - | - | - | - |
576
+ | Duplicate exports | ✅ | - | - | | ❌ |
577
+ | Search namespaces | ✅ | - | - | | |
578
+ | Custom reporters | ✅ | - | - | - | - |
579
+ | JavaScript support | ✅ | | ✅ | - | - |
580
+ | Configure entry files | ✅ | ❌ | | | |
581
+ | [Support workspaces/monorepos][1] | | | | - | - |
582
+ | ESLint plugin available | - | - | - | ✅ | - |
575
583
 
576
584
  ✅ = Supported, ❌ = Not supported, - = Out of scope
577
585
 
@@ -591,7 +599,7 @@ The following commands are similar:
591
599
  unimported
592
600
  knip --production --dependencies --include files
593
601
 
594
- Also see [production mode][56].
602
+ Also see [production mode][45].
595
603
 
596
604
  ### ts-unused-exports
597
605
 
@@ -609,13 +617,6 @@ The following commands are similar:
609
617
  knip --include exports,types
610
618
  knip --exports # Adds unused exports/types in namespaces and unused enum/class members
611
619
 
612
- ## TypeScript language services
613
-
614
- TypeScript language services could play a major role in most of the "unused" areas, as they have an overview of the
615
- project as a whole. This powers things in VS Code like "Find references" or the "Module "./some" declares 'Thing'
616
- locally, but it is not exported" message. I think features like "duplicate exports" or "custom dependency resolvers" are
617
- userland territory, much like code linters.
618
-
619
620
  ## Knip?!
620
621
 
621
622
  Knip is Dutch for a "cut". A Dutch expression is "to be ge**knip**t for something", which means to be perfectly suited
@@ -665,15 +666,11 @@ for the job. I'm motivated to make knip perfectly suited for the job of cutting
665
666
  [42]: ./src/plugins/vitest
666
667
  [43]: ./src/plugins/webpack
667
668
  [44]: #config
668
- [45]: #code-owners
669
- [46]: #compact
670
- [47]: #json
671
- [48]: #symbol-default
672
- [49]: ./docs/custom-reporters.md
673
- [50]: #create-a-new-plugin
674
- [51]: #libraries-and-unused-exports
675
- [52]: https://github.com/depcheck/depcheck
676
- [53]: https://github.com/smeijer/unimported
677
- [54]: https://github.com/pzavolinsky/ts-unused-exports
678
- [55]: https://github.com/nadeesha/ts-prune
679
- [56]: #production-mode
669
+ [45]: #production-mode
670
+ [46]: ./docs/custom-reporters.md
671
+ [47]: #create-a-new-plugin
672
+ [48]: #public-exports
673
+ [49]: https://github.com/depcheck/depcheck
674
+ [50]: https://github.com/smeijer/unimported
675
+ [51]: https://github.com/pzavolinsky/ts-unused-exports
676
+ [52]: https://github.com/nadeesha/ts-prune
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import './util/register.js';
3
- import path from 'node:path';
4
3
  import prettyMilliseconds from 'pretty-ms';
5
4
  import reporters from './reporters/index.js';
6
5
  import parsedArgs, { helpText } from './util/cli-arguments.js';
7
6
  import { ConfigurationError } from './util/errors.js';
8
7
  import { _load } from './util/loader.js';
8
+ import { cwd, resolve } from './util/path.js';
9
9
  import { Performance } from './util/performance.js';
10
10
  import { version } from './version.js';
11
11
  import { main } from './index.js';
@@ -18,9 +18,8 @@ if (isVersion) {
18
18
  console.log(version);
19
19
  process.exit(0);
20
20
  }
21
- const cwd = process.cwd();
22
21
  const isShowProgress = !isDebug && isNoProgress === false && process.stdout.isTTY && typeof process.stdout.cursorTo === 'function';
23
- const printReport = reporter in reporters ? reporters[reporter] : await _load(path.join(cwd, reporter));
22
+ const printReport = reporter in reporters ? reporters[reporter] : await _load(resolve(reporter));
24
23
  const run = async () => {
25
24
  try {
26
25
  const perfObserver = new Performance(isObservePerf);
@@ -1,4 +1,3 @@
1
- import path from 'node:path';
2
1
  import mapWorkspaces from '@npmcli/map-workspaces';
3
2
  import micromatch from 'micromatch';
4
3
  import { ConfigurationValidator } from './configuration-validator.js';
@@ -11,16 +10,16 @@ import { ConfigurationError } from './util/errors.js';
11
10
  import { findFile, loadJSON } from './util/fs.js';
12
11
  import { _dirGlob } from './util/glob.js';
13
12
  import { _load } from './util/loader.js';
14
- import { relativePosix } from './util/path.js';
13
+ import { join, relative } from './util/path.js';
15
14
  import { toCamelCase } from './util/plugin.js';
16
15
  import { resolveIncludedIssueTypes } from './util/resolve-included-issue-types.js';
17
16
  import { byPathDepth } from './util/workspace.js';
18
17
  const { config: rawConfigArg, workspace: rawWorkspaceArg, include = [], exclude = [], dependencies = false, exports = false, } = parsedArgs.values;
19
18
  const getDefaultWorkspaceConfig = (extensions) => {
20
- const extsGlobStr = [...DEFAULT_EXTENSIONS, ...(extensions ?? [])].map(ext => ext.slice(1)).join(',');
19
+ const exts = [...DEFAULT_EXTENSIONS, ...(extensions ?? [])].map(ext => ext.slice(1)).join(',');
21
20
  return {
22
- entry: [`index.{${extsGlobStr}}!`, `src/index.{${extsGlobStr}}!`],
23
- project: [`**/*.{${extsGlobStr}}!`],
21
+ entry: [`index.{${exts}}!`, `src/index.{${exts}}!`],
22
+ project: [`**/*.{${exts}}!`],
24
23
  paths: {},
25
24
  ignore: [],
26
25
  ignoreBinaries: [],
@@ -155,7 +154,7 @@ export class ConfigurationChief {
155
154
  this.workspaceDirs = this.getWorkspaces()
156
155
  .sort(byPathDepth)
157
156
  .reverse()
158
- .map(dir => path.posix.join(this.cwd, dir));
157
+ .map(dir => join(this.cwd, dir));
159
158
  }
160
159
  async getManifestWorkspaces() {
161
160
  const workspaces = await mapWorkspaces({
@@ -165,7 +164,7 @@ export class ConfigurationChief {
165
164
  });
166
165
  const manifestWorkspaces = new Map();
167
166
  for (const [pkgName, dir] of workspaces.entries()) {
168
- manifestWorkspaces.set(relativePosix(this.cwd, dir), pkgName);
167
+ manifestWorkspaces.set(relative(this.cwd, dir), pkgName);
169
168
  }
170
169
  return manifestWorkspaces;
171
170
  }
@@ -195,7 +194,7 @@ export class ConfigurationChief {
195
194
  return workspaces.sort(byPathDepth).map(name => ({
196
195
  name,
197
196
  pkgName: this.manifestWorkspaces.get(name),
198
- dir: path.join(this.cwd, name),
197
+ dir: join(this.cwd, name),
199
198
  config: this.getConfigForWorkspace(name),
200
199
  ancestors: allWorkspaces.reduce(getAncestors(name), []),
201
200
  }));
package/dist/constants.js CHANGED
@@ -1,7 +1,11 @@
1
1
  export const ROOT_WORKSPACE_NAME = '.';
2
2
  export const KNIP_CONFIG_LOCATIONS = ['knip.json', 'knip.jsonc', '.knip.json', '.knip.jsonc', 'knip.ts', 'knip.js'];
3
3
  export const DEFAULT_EXTENSIONS = ['.js', '.mjs', '.cjs', '.jsx', '.ts', '.tsx'];
4
- export const TEST_FILE_PATTERNS = ['**/*.{test,spec}.{js,jsx,ts,tsx}', '**/__tests__/**/*.{js,jsx,ts,tsx}'];
4
+ export const TEST_FILE_PATTERNS = [
5
+ '**/*.{test,spec}.{js,jsx,ts,tsx,mjs,cjs}',
6
+ '**/__tests__/**/*.{js,jsx,ts,tsx,mjs,cjs}',
7
+ '**/test/**/*.{js,jsx,ts,tsx,mjs,cjs}',
8
+ ];
5
9
  export const IGNORED_GLOBAL_BINARIES = [
6
10
  'bun',
7
11
  'deno',
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import path from 'node:path';
2
1
  import { ConfigurationChief } from './configuration-chief.js';
3
2
  import { ROOT_WORKSPACE_NAME, DEFAULT_EXTENSIONS } from './constants.js';
4
3
  import { DependencyDeputy } from './dependency-deputy.js';
@@ -9,6 +8,7 @@ import { compact } from './util/array.js';
9
8
  import { debugLogObject, debugLogArray } from './util/debug.js';
10
9
  import { findFile, loadJSON, findFileWithExtensions } from './util/fs.js';
11
10
  import { _glob } from './util/glob.js';
11
+ import { join } from './util/path.js';
12
12
  import { loadTSConfig } from './util/tsconfig-loader.js';
13
13
  import { WorkspaceWorker } from './workspace-worker.js';
14
14
  export const main = async (unresolvedConfiguration) => {
@@ -38,7 +38,7 @@ export const main = async (unresolvedConfiguration) => {
38
38
  continue;
39
39
  const { ignoreDependencies } = chief.getConfigForWorkspace(name);
40
40
  deputy.addWorkspace({ name, dir, manifestPath, manifest, ignoreDependencies });
41
- const tsConfigFilePath = path.join(dir, tsConfigFile ?? 'tsconfig.json');
41
+ const tsConfigFilePath = join(dir, tsConfigFile ?? 'tsconfig.json');
42
42
  const tsConfig = await loadTSConfig(tsConfigFilePath);
43
43
  const principal = factory.getPrincipal({
44
44
  cwd: dir,
@@ -1,6 +1,6 @@
1
1
  import { initReport, initIssues, initCounters } from './issues/initializers.js';
2
2
  import { LineRewriter } from './util/log.js';
3
- import { relativePosix } from './util/path.js';
3
+ import { relative } from './util/path.js';
4
4
  export class IssueCollector {
5
5
  report;
6
6
  issues;
@@ -31,7 +31,7 @@ export class IssueCollector {
31
31
  });
32
32
  }
33
33
  addIssue(issue) {
34
- const key = relativePosix(this.cwd, issue.filePath);
34
+ const key = relative(this.cwd, issue.filePath);
35
35
  this.issues[issue.type][key] = this.issues[issue.type][key] ?? {};
36
36
  if (!this.issues[issue.type][key][issue.symbol]) {
37
37
  this.issues[issue.type][key][issue.symbol] = issue;
@@ -1,13 +1,13 @@
1
- import path from 'node:path';
1
+ import { join } from '../util/path.js';
2
2
  import { _require } from '../util/require.js';
3
3
  export const getPackageManifest = async (workingDir, packageName, isRoot, cwd) => {
4
4
  try {
5
- return _require(path.join(workingDir, 'node_modules', packageName, 'package.json'));
5
+ return _require(join(workingDir, 'node_modules', packageName, 'package.json'));
6
6
  }
7
7
  catch (error) {
8
8
  if (!isRoot) {
9
9
  try {
10
- return _require(path.join(cwd, 'node_modules', packageName, 'package.json'));
10
+ return _require(join(cwd, 'node_modules', packageName, 'package.json'));
11
11
  }
12
12
  catch (error) {
13
13
  }
@@ -1,8 +1,7 @@
1
- import path from 'node:path';
2
1
  import { compact } from '../../util/array.js';
3
2
  import { _load } from '../../util/loader.js';
4
3
  import { getPackageName } from '../../util/modules.js';
5
- import { isAbsolute, isInNodeModules } from '../../util/path.js';
4
+ import { isAbsolute, isInNodeModules, join, dirname } from '../../util/path.js';
6
5
  import { _resolve } from '../../util/require.js';
7
6
  import { fallback } from './fallback.js';
8
7
  const getDependencies = (config) => {
@@ -36,7 +35,7 @@ export const getDependenciesDeep = async (configFilePath, dependencies = new Set
36
35
  if (config.extends) {
37
36
  for (const extend of [config.extends].flat()) {
38
37
  if (extend.startsWith('.') || (isAbsolute(extend) && !isInNodeModules(extend))) {
39
- const filePath = isAbsolute(extend) ? extend : path.join(path.dirname(configFilePath), extend);
38
+ const filePath = isAbsolute(extend) ? extend : join(dirname(configFilePath), extend);
40
39
  const extendConfigFilePath = _resolve(filePath);
41
40
  addAll(await getDependenciesDeep(extendConfigFilePath, dependencies, options));
42
41
  }
@@ -3,5 +3,5 @@ export declare const NAME = "Jest";
3
3
  export declare const ENABLERS: string[];
4
4
  export declare const isEnabled: IsPluginEnabledCallback;
5
5
  export declare const CONFIG_FILE_PATTERNS: string[];
6
- export declare const ENTRY_FILE_PATTERNS: string[];
6
+ export declare const ENTRY_FILE_PATTERNS: never[];
7
7
  export declare const findDependencies: GenericPluginCallback;
@@ -1,7 +1,6 @@
1
- import path from 'node:path';
2
1
  import { _load } from '../../util/loader.js';
3
2
  import { getPackageName } from '../../util/modules.js';
4
- import { isAbsolute } from '../../util/path.js';
3
+ import { isAbsolute, join, dirname } from '../../util/path.js';
5
4
  import { timerify } from '../../util/performance.js';
6
5
  import { hasDependency } from '../../util/plugin.js';
7
6
  import { _resolve } from '../../util/require.js';
@@ -9,14 +8,14 @@ export const NAME = 'Jest';
9
8
  export const ENABLERS = ['jest'];
10
9
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
11
10
  export const CONFIG_FILE_PATTERNS = ['jest.config.{js,ts,mjs,cjs,json}'];
12
- export const ENTRY_FILE_PATTERNS = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'];
13
- const join = (base, id) => (isAbsolute(id) ? id : path.join(path.dirname(base), id));
11
+ export const ENTRY_FILE_PATTERNS = [];
12
+ const maybeJoin = (base, id) => (isAbsolute(id) ? id : join(dirname(base), id));
14
13
  const resolveExtensibleConfig = async (configFilePath) => {
15
14
  const config = await _load(configFilePath);
16
15
  if (config?.preset) {
17
16
  const { preset } = config;
18
17
  if (preset.startsWith('.') || isAbsolute(preset)) {
19
- const presetConfigPath = join(configFilePath, preset);
18
+ const presetConfigPath = maybeJoin(configFilePath, preset);
20
19
  const presetConfig = await resolveExtensibleConfig(presetConfigPath);
21
20
  delete config.preset;
22
21
  Object.assign(config, presetConfig);
@@ -31,9 +30,9 @@ const findJestDependencies = async (configFilePath, { cwd }) => {
31
30
  const dependencies = [];
32
31
  const entryFiles = [];
33
32
  const handleEntries = (name) => {
34
- name = name.includes('<rootDir>') ? path.join(cwd, name.replace(/^.*<rootDir>/, '')) : name;
33
+ name = name.includes('<rootDir>') ? join(cwd, name.replace(/^.*<rootDir>/, '')) : name;
35
34
  if (name.startsWith('.') || isAbsolute(name)) {
36
- entryFiles.push(_resolve(join(configFilePath, name)));
35
+ entryFiles.push(_resolve(maybeJoin(configFilePath, name)));
37
36
  }
38
37
  else {
39
38
  dependencies.push(name);
@@ -3,5 +3,5 @@ export declare const NAME = "Mocha";
3
3
  export declare const ENABLERS: string[];
4
4
  export declare const isEnabled: IsPluginEnabledCallback;
5
5
  export declare const CONFIG_FILE_PATTERNS: string[];
6
- export declare const ENTRY_FILE_PATTERNS: string[];
6
+ export declare const ENTRY_FILE_PATTERNS: never[];
7
7
  export declare const findDependencies: GenericPluginCallback;
@@ -6,7 +6,7 @@ export const NAME = 'Mocha';
6
6
  export const ENABLERS = ['mocha'];
7
7
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
8
8
  export const CONFIG_FILE_PATTERNS = ['.mocharc.{js,cjs,json,jsonc,yml,yaml}', 'package.json'];
9
- export const ENTRY_FILE_PATTERNS = ['test/**/*.{js,cjs,mjs}'];
9
+ export const ENTRY_FILE_PATTERNS = [];
10
10
  const findMochaDependencies = async (configFilePath, { manifest }) => {
11
11
  const config = configFilePath.endsWith('package.json') ? manifest.mocha : await _load(configFilePath);
12
12
  if (config) {
@@ -2,4 +2,4 @@ import { hasDependency } from '../../util/plugin.js';
2
2
  export const NAME = 'Playwright';
3
3
  export const ENABLERS = ['@playwright/test'];
4
4
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
5
- export const ENTRY_FILE_PATTERNS = ['playwright.config.{js,ts}', '.*{test,spec}.{js,ts,mjs}'];
5
+ export const ENTRY_FILE_PATTERNS = ['playwright.config.{js,ts}'];
@@ -1,7 +1,6 @@
1
- import path from 'node:path';
2
1
  import { _load } from '../../util/loader.js';
3
2
  import { getPackageName } from '../../util/modules.js';
4
- import { isAbsolute } from '../../util/path.js';
3
+ import { dirname, isAbsolute, join } from '../../util/path.js';
5
4
  import { timerify } from '../../util/performance.js';
6
5
  import { hasDependency } from '../../util/plugin.js';
7
6
  import { _resolve } from '../../util/require.js';
@@ -20,7 +19,7 @@ const findStorybookDependencies = async (configFilePath) => {
20
19
  config.addons?.forEach(addon => {
21
20
  const name = typeof addon === 'string' ? addon : addon.name;
22
21
  if (name.startsWith('.')) {
23
- entryFiles.push(_resolve(path.join(path.dirname(configFilePath), name)));
22
+ entryFiles.push(_resolve(join(dirname(configFilePath), name)));
24
23
  }
25
24
  else if (isAbsolute(name)) {
26
25
  entryFiles.push(configFilePath);
@@ -12,6 +12,6 @@ export const CONFIG_FILE_PATTERNS = [
12
12
  ];
13
13
  const findPluginDependencies = async (configFilePath) => {
14
14
  const config = await _load(configFilePath);
15
- return config?.plugins ?? [];
15
+ return config?.plugin ?? [];
16
16
  };
17
17
  export const findDependencies = timerify(findPluginDependencies);
@@ -1,3 +1,3 @@
1
1
  export type PluginConfig = {
2
- plugins?: string[];
2
+ plugin?: string[];
3
3
  };
@@ -3,5 +3,5 @@ export declare const NAME = "Vitest";
3
3
  export declare const ENABLERS: string[];
4
4
  export declare const isEnabled: IsPluginEnabledCallback;
5
5
  export declare const CONFIG_FILE_PATTERNS: string[];
6
- export declare const ENTRY_FILE_PATTERNS: string[];
6
+ export declare const ENTRY_FILE_PATTERNS: never[];
7
7
  export declare const findDependencies: GenericPluginCallback;
@@ -7,7 +7,7 @@ export const NAME = 'Vitest';
7
7
  export const ENABLERS = ['vitest'];
8
8
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
9
9
  export const CONFIG_FILE_PATTERNS = ['vitest.config.ts', 'vite.config.ts'];
10
- export const ENTRY_FILE_PATTERNS = ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'];
10
+ export const ENTRY_FILE_PATTERNS = [];
11
11
  const findVitestDependencies = async (configFilePath) => {
12
12
  const config = await _load(configFilePath);
13
13
  if (!config || !config.test)
@@ -1,8 +1,7 @@
1
- import path from 'node:path';
2
1
  import { compact } from '../../util/array.js';
3
2
  import { _load } from '../../util/loader.js';
4
3
  import { getPackageName } from '../../util/modules.js';
5
- import { isAbsolute } from '../../util/path.js';
4
+ import { isAbsolute, join } from '../../util/path.js';
6
5
  import { timerify } from '../../util/performance.js';
7
6
  import { hasDependency } from '../../util/plugin.js';
8
7
  import { getDependenciesFromConfig } from '../babel/index.js';
@@ -62,7 +61,7 @@ const findWebpackDependencies = async (configFilePath, { cwd, manifest, isProduc
62
61
  ? cfg.entry
63
62
  : Object.values(cfg.entry).map(entry => (typeof entry === 'string' ? entry : entry.filename));
64
63
  entries.forEach(entry => {
65
- entryFiles.add(isAbsolute(entry) ? entry : path.join(cwd, entry));
64
+ entryFiles.add(isAbsolute(entry) ? entry : join(cwd, entry));
66
65
  });
67
66
  }
68
67
  return dependencies;
@@ -1,11 +1,10 @@
1
- import path from 'node:path';
2
1
  import { ProjectPrincipal } from './project-principal.js';
3
- import { isAbsolute } from './util/path.js';
2
+ import { join, isAbsolute } from './util/path.js';
4
3
  const mergePaths = (cwd, compilerOptions = {}, paths = {}) => {
5
4
  const mergedPaths = { ...compilerOptions.paths, ...paths };
6
5
  const baseUrl = compilerOptions.baseUrl ?? '.';
7
6
  compilerOptions.paths = Object.keys(mergedPaths).reduce((paths, key) => {
8
- paths[key] = mergedPaths[key].map(entry => (isAbsolute(entry) ? entry : path.join(cwd, baseUrl, entry)));
7
+ paths[key] = mergedPaths[key].map(entry => (isAbsolute(entry) ? entry : join(cwd, baseUrl, entry)));
9
8
  return paths;
10
9
  }, {});
11
10
  return compilerOptions;
@@ -40,7 +39,7 @@ export class PrincipalFactory {
40
39
  const principal = new ProjectPrincipal({ cwd, compilerOptions, report, compilers });
41
40
  const paths = new Set(Object.keys(compilerOptions?.paths ?? {}));
42
41
  const isDefaultBaseUrl = hasDefaultBaseUrl(compilerOptions);
43
- compilerOptions.baseUrl = path.join(cwd, compilerOptions.baseUrl ?? '.');
42
+ compilerOptions.baseUrl = join(cwd, compilerOptions.baseUrl ?? '.');
44
43
  this.principals.add({ principal, cwds: new Set([cwd]), paths, isDefaultBaseUrl });
45
44
  return principal;
46
45
  }
@@ -1,10 +1,9 @@
1
- import path from 'node:path';
2
1
  import ts from 'typescript';
3
2
  import { DEFAULT_EXTENSIONS } from './constants.js';
4
3
  import { IGNORED_FILE_EXTENSIONS } from './constants.js';
5
4
  import { getImportsAndExports } from './typescript/ast-walker.js';
6
5
  import { createHosts } from './typescript/createHosts.js';
7
- import { isInNodeModules } from './util/path.js';
6
+ import { extname, isInNodeModules } from './util/path.js';
8
7
  import { timerify } from './util/performance.js';
9
8
  const baseCompilerOptions = {
10
9
  allowJs: true,
@@ -64,7 +63,7 @@ export class ProjectPrincipal {
64
63
  typeChecker();
65
64
  }
66
65
  hasAcceptedExtension(filePath) {
67
- return this.extensions.has(path.extname(filePath));
66
+ return this.extensions.has(extname(filePath));
68
67
  }
69
68
  addEntryPath(filePath) {
70
69
  if (!isInNodeModules(filePath) && this.hasAcceptedExtension(filePath)) {
@@ -86,7 +85,7 @@ export class ProjectPrincipal {
86
85
  async runAsyncCompilers() {
87
86
  const add = timerify(this.backend.fileManager.compileAndAddSourceFile.bind(this.backend.fileManager));
88
87
  const extensions = Array.from(this.asyncCompilers.keys());
89
- const files = Array.from(this.projectPaths).filter(filePath => extensions.includes(path.extname(filePath)));
88
+ const files = Array.from(this.projectPaths).filter(filePath => extensions.includes(extname(filePath)));
90
89
  for (const filePath of files) {
91
90
  await add(filePath);
92
91
  }
@@ -129,7 +128,7 @@ export class ProjectPrincipal {
129
128
  externalImports.add(specifier);
130
129
  }
131
130
  else {
132
- const ext = path.extname(specifier);
131
+ const ext = extname(specifier);
133
132
  if (!ext || (ext !== '.json' && !IGNORED_FILE_EXTENSIONS.includes(ext))) {
134
133
  finalUnresolvedImports.add(specifier);
135
134
  }
@@ -1,12 +1,11 @@
1
- import path from 'node:path';
2
1
  import { OwnershipEngine } from '@snyk/github-codeowners/dist/lib/ownership/index.js';
3
2
  import chalk from 'chalk';
4
- import { isAbsolute, relativePosix } from '../util/path.js';
3
+ import { isAbsolute, relative, resolve } from '../util/path.js';
5
4
  import { getTitle, logTitle, logIssueLine } from './util.js';
6
5
  const logIssueSet = (issues) => {
7
6
  issues
8
7
  .sort((a, b) => (a.owner < b.owner ? -1 : 1))
9
- .forEach(issue => console.log(chalk.cyan(issue.owner), isAbsolute(issue.symbol) ? relativePosix(issue.symbol) : issue.symbol));
8
+ .forEach(issue => console.log(chalk.cyan(issue.owner), isAbsolute(issue.symbol) ? relative(issue.symbol) : issue.symbol));
10
9
  };
11
10
  const logIssueRecord = (issues) => {
12
11
  const sortedByFilePath = issues.sort((a, b) => (a.owner < b.owner ? -1 : 1));
@@ -20,13 +19,13 @@ export default ({ report, issues, options }) => {
20
19
  catch (error) {
21
20
  console.error(error);
22
21
  }
23
- const codeownersFilePath = path.resolve(opts.path ?? '.github/CODEOWNERS');
22
+ const codeownersFilePath = resolve(opts.path ?? '.github/CODEOWNERS');
24
23
  const codeownersEngine = OwnershipEngine.FromCodeownersFile(codeownersFilePath);
25
24
  const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
26
25
  const [dependenciesOwner = '[no-owner]'] = codeownersEngine.calcFileOwnership('package.json');
27
26
  const fallbackOwner = dependenciesOwner;
28
27
  let totalIssues = 0;
29
- const calcFileOwnership = (filePath) => codeownersEngine.calcFileOwnership(relativePosix(filePath))[0] ?? fallbackOwner;
28
+ const calcFileOwnership = (filePath) => codeownersEngine.calcFileOwnership(relative(filePath))[0] ?? fallbackOwner;
30
29
  const addOwner = (issue) => ({ ...issue, owner: calcFileOwnership(issue.filePath) });
31
30
  for (const [reportType, isReportType] of Object.entries(report)) {
32
31
  if (isReportType) {
@@ -1,7 +1,6 @@
1
- import path from 'node:path';
2
1
  import { OwnershipEngine } from '@snyk/github-codeowners/dist/lib/ownership/index.js';
3
2
  import { isFile } from '../util/fs.js';
4
- import { relativePosix } from '../util/path.js';
3
+ import { relative, resolve } from '../util/path.js';
5
4
  const mergeTypes = (type) => type === 'exports' || type === 'nsExports' ? 'exports' : type === 'types' || type === 'nsTypes' ? 'types' : type;
6
5
  export default async ({ report, issues, options }) => {
7
6
  let opts = {};
@@ -12,11 +11,11 @@ export default async ({ report, issues, options }) => {
12
11
  console.error(error);
13
12
  }
14
13
  const json = {};
15
- const codeownersFilePath = path.resolve(opts.codeowners ?? '.github/CODEOWNERS');
14
+ const codeownersFilePath = resolve(opts.codeowners ?? '.github/CODEOWNERS');
16
15
  const codeownersEngine = isFile(codeownersFilePath) && OwnershipEngine.FromCodeownersFile(codeownersFilePath);
17
16
  const flatten = (issues) => Object.values(issues).map(Object.values).flat();
18
17
  const initRow = (filePath) => {
19
- const file = relativePosix(filePath);
18
+ const file = relative(filePath);
20
19
  const row = {
21
20
  file,
22
21
  ...(codeownersEngine && { owners: codeownersEngine.calcFileOwnership(file) }),
@@ -1,5 +1,5 @@
1
1
  import EasyTable from 'easy-table';
2
- import { relativePosix } from '../util/path.js';
2
+ import { relative } from '../util/path.js';
3
3
  import { getTitle, logTitle, logIssueSet } from './util.js';
4
4
  const TRUNCATE_WIDTH = 40;
5
5
  const truncate = (text) => (text.length > TRUNCATE_WIDTH ? text.slice(0, TRUNCATE_WIDTH - 3) + '...' : text);
@@ -9,7 +9,7 @@ const logIssueRecord = (issues) => {
9
9
  table.cell('symbol', issue.symbols ? truncate(issue.symbols.join(', ')) : issue.symbol);
10
10
  issue.parentSymbol && table.cell('parentSymbol', issue.parentSymbol);
11
11
  issue.symbolType && table.cell('symbolType', issue.symbolType);
12
- table.cell('filePath', relativePosix(issue.filePath));
12
+ table.cell('filePath', relative(issue.filePath));
13
13
  table.newRow();
14
14
  });
15
15
  console.log(table.sort(['filePath', 'parentSymbol', 'symbol']).print().trim());
@@ -1,6 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import { ISSUE_TYPE_TITLE } from '../constants.js';
3
- import { isAbsolute, relativePosix } from '../util/path.js';
3
+ import { isAbsolute, relative } from '../util/path.js';
4
4
  export const getTitle = (reportType) => {
5
5
  return ISSUE_TYPE_TITLE[reportType];
6
6
  };
@@ -8,8 +8,8 @@ export const logTitle = (title, count) => console.log(`${chalk.bold.yellow.under
8
8
  export const logIssueLine = ({ owner, filePath, symbols, parentSymbol }) => {
9
9
  const symbol = symbols ? `: ${symbols.join(', ')}` : '';
10
10
  const parent = parentSymbol ? ` (${parentSymbol})` : '';
11
- console.log(`${owner ? `${chalk.cyan(owner)} ` : ''}${relativePosix(filePath)}${symbol}${parent}`);
11
+ console.log(`${owner ? `${chalk.cyan(owner)} ` : ''}${relative(filePath)}${symbol}${parent}`);
12
12
  };
13
13
  export const logIssueSet = (issues) => {
14
- issues.sort().forEach(value => console.log(isAbsolute(value) ? relativePosix(value) : value));
14
+ issues.sort().forEach(value => console.log(isAbsolute(value) ? relative(value) : value));
15
15
  };
@@ -1,6 +1,6 @@
1
- import path from 'node:path';
2
1
  import ts from 'typescript';
3
2
  import { debugLog } from '../util/debug.js';
3
+ import { extname } from '../util/path.js';
4
4
  export class SourceFileManager {
5
5
  sourceFileCache = new Map();
6
6
  snapshotCache = new Map();
@@ -21,7 +21,7 @@ export class SourceFileManager {
21
21
  const contents = ts.sys.readFile(filePath);
22
22
  if (typeof contents !== 'string')
23
23
  throw new Error(`Unable to read ${filePath}`);
24
- const ext = path.extname(filePath);
24
+ const ext = extname(filePath);
25
25
  const compiler = this.syncCompilers?.get(ext);
26
26
  const compiled = compiler ? compiler(contents) : contents;
27
27
  if (compiler)
@@ -42,7 +42,7 @@ export class SourceFileManager {
42
42
  const contents = ts.sys.readFile(filePath);
43
43
  if (typeof contents !== 'string')
44
44
  throw new Error(`Unable to read ${filePath}`);
45
- const ext = path.extname(filePath);
45
+ const ext = extname(filePath);
46
46
  const compiler = this.asyncCompilers?.get(ext);
47
47
  if (compiler) {
48
48
  const compiled = await compiler(contents);
@@ -1,12 +1,12 @@
1
1
  import { EOL } from 'node:os';
2
2
  import path from 'node:path';
3
3
  import ts from 'typescript';
4
- import { _resolve } from '../util/require.js';
4
+ import { _require } from '../util/require.js';
5
5
  import { createCustomModuleResolver } from './resolveModuleNames.js';
6
6
  import { SourceFileManager } from './SourceFileManager.js';
7
7
  import { createCustomSys } from './sys.js';
8
8
  const cwd = process.cwd();
9
- const libLocation = path.dirname(_resolve('typescript', { paths: [cwd] }));
9
+ const libLocation = path.dirname(_require.resolve('typescript', { paths: [cwd] }));
10
10
  const fileManager = new SourceFileManager();
11
11
  export const createHosts = ({ cwd, compilerOptions, entryPaths, compilers }) => {
12
12
  fileManager.installCompilers(compilers);
@@ -1,6 +1,5 @@
1
- import path from 'node:path';
2
1
  import ts from 'typescript';
3
- import { isAbsolute } from '../util/path.js';
2
+ import { isAbsolute, join } from '../util/path.js';
4
3
  import { ensureRealFilePath, isVirtualFilePath } from './utils.js';
5
4
  export function createCustomModuleResolver(customSys, compilerOptions, virtualFileExtensions) {
6
5
  function resolveModuleNames(moduleNames, containingFile) {
@@ -9,7 +8,7 @@ export function createCustomModuleResolver(customSys, compilerOptions, virtualFi
9
8
  function resolveModuleName(name, containingFile) {
10
9
  const tsResolvedModule = ts.resolveModuleName(name, containingFile, compilerOptions, ts.sys).resolvedModule;
11
10
  if (tsResolvedModule && !isAbsolute(tsResolvedModule?.resolvedFileName)) {
12
- tsResolvedModule.resolvedFileName = path.join(customSys.getCurrentDirectory(), tsResolvedModule.resolvedFileName);
11
+ tsResolvedModule.resolvedFileName = join(customSys.getCurrentDirectory(), tsResolvedModule.resolvedFileName);
13
12
  }
14
13
  if (virtualFileExtensions.length === 0)
15
14
  return tsResolvedModule;
@@ -1,10 +1,9 @@
1
- import path from 'node:path';
2
1
  import parseArgs from 'minimist';
3
- import { isInNodeModules } from '../../path.js';
2
+ import { isInNodeModules, join } from '../../path.js';
4
3
  import { tryResolve } from '../../require.js';
5
4
  const tryResolveFilePath = (cwd, specifier, fallback) => {
6
5
  if (specifier) {
7
- const filePath = path.join(cwd, specifier);
6
+ const filePath = join(cwd, specifier);
8
7
  if (!isInNodeModules(filePath)) {
9
8
  const resolvedFilePath = tryResolve(filePath);
10
9
  if (resolvedFilePath)
package/dist/util/fs.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import { statSync } from 'node:fs';
2
2
  import { readFile } from 'node:fs/promises';
3
- import path from 'node:path';
4
3
  import stripJsonComments from 'strip-json-comments';
5
4
  import { LoaderError } from './errors.js';
5
+ import { join } from './path.js';
6
6
  export const isFile = (filePath) => {
7
7
  const stat = statSync(filePath, { throwIfNoEntry: false });
8
8
  return stat !== undefined && stat.isFile();
9
9
  };
10
10
  export const findFile = (workingDir, fileName) => {
11
- const filePath = path.join(workingDir, fileName);
11
+ const filePath = join(workingDir, fileName);
12
12
  return isFile(filePath) ? filePath : undefined;
13
13
  };
14
14
  export const loadJSON = async (filePath) => {
@@ -21,11 +21,11 @@ export const loadJSON = async (filePath) => {
21
21
  }
22
22
  };
23
23
  export const findFileWithExtensions = (cwd, specifier, extensions) => {
24
- const filePath = path.join(cwd, specifier);
24
+ const filePath = join(cwd, specifier);
25
25
  if (isFile(filePath))
26
26
  return filePath;
27
27
  for (const ext of extensions) {
28
- const filePath = path.join(cwd, specifier + ext);
28
+ const filePath = join(cwd, specifier + ext);
29
29
  if (isFile(filePath))
30
30
  return filePath;
31
31
  }
package/dist/util/glob.js CHANGED
@@ -1,16 +1,15 @@
1
- import path from 'node:path';
2
1
  import fg from 'fast-glob';
3
2
  import { globby } from 'globby';
4
3
  import memoize from 'nano-memoize';
5
4
  import { ROOT_WORKSPACE_NAME } from '../constants.js';
6
5
  import { compact } from './array.js';
7
6
  import { debugLogObject } from './debug.js';
8
- import { relativePosix } from './path.js';
7
+ import { join, relative } from './path.js';
9
8
  import { timerify } from './performance.js';
10
9
  export const prependDirToPattern = (workingDir, pattern) => {
11
10
  if (pattern.startsWith('!'))
12
- return '!' + path.posix.join(workingDir, pattern.slice(1));
13
- return path.posix.join(workingDir, pattern);
11
+ return '!' + join(workingDir, pattern.slice(1));
12
+ return join(workingDir, pattern);
14
13
  };
15
14
  export const negate = (pattern) => pattern.replace(/^!?/, '!');
16
15
  export const hasProductionSuffix = (pattern) => pattern.endsWith('!');
@@ -18,7 +17,7 @@ export const hasNoProductionSuffix = (pattern) => !pattern.endsWith('!');
18
17
  const removeProductionSuffix = (pattern) => pattern.replace(/!$/, '');
19
18
  const negatedLast = (pattern) => (pattern.startsWith('!') ? 1 : -1);
20
19
  const glob = async ({ cwd, workingDir = cwd, patterns, ignore = [], gitignore = true }) => {
21
- const relativePath = relativePosix(cwd, workingDir);
20
+ const relativePath = relative(cwd, workingDir);
22
21
  const prepend = (pattern) => prependDirToPattern(relativePath, pattern);
23
22
  const globPatterns = compact([patterns].flat().map(prepend).map(removeProductionSuffix)).sort(negatedLast);
24
23
  const ignorePatterns = compact([...ignore, '**/node_modules/**']);
@@ -1,14 +1,14 @@
1
1
  import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
2
  import { pathToFileURL } from 'node:url';
4
3
  import yaml from 'js-yaml';
5
4
  import { LoaderError } from './errors.js';
6
5
  import { loadJSON } from './fs.js';
6
+ import { extname } from './path.js';
7
7
  import { timerify } from './performance.js';
8
8
  import { jiti } from './register.js';
9
9
  const load = async (filePath) => {
10
10
  try {
11
- const ext = path.extname(filePath);
11
+ const ext = extname(filePath);
12
12
  if (ext === '.json' || ext === '.jsonc' || /rc$/.test(filePath)) {
13
13
  return loadJSON(filePath);
14
14
  }
@@ -1,10 +1,10 @@
1
- import { isAbsolute, toPosixPath } from './path.js';
1
+ import { isAbsolute, toPosix } from './path.js';
2
2
  export const getPackageNameFromModuleSpecifier = (moduleSpecifier) => {
3
3
  const parts = moduleSpecifier.split('/').slice(0, 2);
4
4
  return moduleSpecifier.startsWith('@') ? parts.join('/') : parts[0];
5
5
  };
6
6
  export const getPackageName = (value) => {
7
- const match = toPosixPath(value).match(/(?<=node_modules\/)(@[^/]+\/[^/]+|[^/]+)/g);
7
+ const match = toPosix(value).match(/(?<=node_modules\/)(@[^/]+\/[^/]+|[^/]+)/g);
8
8
  if (match)
9
9
  return match[match.length - 1];
10
10
  if (value.startsWith('@')) {
@@ -1,4 +1,9 @@
1
- export declare const toPosixPath: (value: string) => string;
2
- export declare const relativePosix: (from: string, to?: string) => string;
1
+ export declare const toPosix: (value: string) => string;
2
+ export declare const cwd: string;
3
+ export declare const resolve: (...paths: string[]) => string;
4
+ export declare const relative: (from: string, to?: string) => string;
3
5
  export declare const isAbsolute: (value: string) => boolean;
4
6
  export declare const isInNodeModules: (filePath: string) => boolean;
7
+ export declare const join: (...paths: string[]) => string;
8
+ export declare const extname: (path: string) => string;
9
+ export declare const dirname: (path: string) => string;
package/dist/util/path.js CHANGED
@@ -1,6 +1,10 @@
1
1
  import path from 'node:path';
2
- const cwd = process.cwd();
3
- export const toPosixPath = (value) => value.split(path.sep).join(path.posix.sep);
4
- export const relativePosix = (from, to) => toPosixPath(path.relative(to ? from : cwd, to ?? from));
5
- export const isAbsolute = (value) => /^(\/|[A-Z]:)/.test(value);
2
+ export const toPosix = (value) => value.split(path.sep).join(path.posix.sep);
3
+ export const cwd = toPosix(process.cwd());
4
+ export const resolve = (...paths) => paths.length === 1 ? path.posix.join(cwd, paths[0]) : path.posix.resolve(...paths);
5
+ export const relative = (from, to) => path.posix.relative(to ? toPosix(from) : cwd, toPosix(to ?? from));
6
+ export const isAbsolute = (value) => value.startsWith('/') || /^[A-Z]:(\/|\\)/.test(value);
6
7
  export const isInNodeModules = (filePath) => filePath.includes('node_modules');
8
+ export const join = path.posix.join;
9
+ export const extname = path.posix.extname;
10
+ export const dirname = path.posix.dirname;
@@ -1,4 +1,4 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  export declare const tryResolve: (specifier: string) => string | undefined;
3
3
  export declare const _require: NodeRequire;
4
- export declare const _resolve: NodeJS.RequireResolve;
4
+ export declare const _resolve: (specifier: string) => string;
@@ -1,12 +1,14 @@
1
1
  import { createRequire } from 'node:module';
2
+ import { toPosix } from './path.js';
2
3
  import { timerify } from './performance.js';
3
4
  const require = createRequire(process.cwd());
5
+ const resolve = (specifier) => toPosix(require.resolve(specifier));
4
6
  export const tryResolve = (specifier) => {
5
7
  try {
6
- return require.resolve(specifier);
8
+ return resolve(specifier);
7
9
  }
8
10
  catch (error) {
9
11
  }
10
12
  };
11
13
  export const _require = timerify(require);
12
- export const _resolve = timerify(require.resolve);
14
+ export const _resolve = timerify(resolve);
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.0.0-alpha.1";
1
+ export declare const version = "2.0.0-alpha.3";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.0.0-alpha.1';
1
+ export const version = '2.0.0-alpha.3';
@@ -1,9 +1,9 @@
1
- import path from 'node:path';
2
1
  import { ROOT_WORKSPACE_NAME, TEST_FILE_PATTERNS } from './constants.js';
3
2
  import * as npm from './manifest/index.js';
4
3
  import * as plugins from './plugins/index.js';
5
4
  import { debugLogArray, debugLogObject } from './util/debug.js';
6
5
  import { _pureGlob, negate, hasProductionSuffix, hasNoProductionSuffix, prependDirToPattern } from './util/glob.js';
6
+ import { join } from './util/path.js';
7
7
  const negatedTestFilePatterns = TEST_FILE_PATTERNS.map(negate);
8
8
  export class WorkspaceWorker {
9
9
  name;
@@ -61,7 +61,7 @@ export class WorkspaceWorker {
61
61
  dir: this.dir,
62
62
  cwd: this.rootWorkspaceDir,
63
63
  });
64
- const filePath = path.join(this.dir, 'package.json');
64
+ const filePath = join(this.dir, 'package.json');
65
65
  dependencies.forEach(dependency => this.referencedDependencies.add([filePath, dependency]));
66
66
  entryFiles.forEach(entryFile => this.entryFiles.add(entryFile));
67
67
  this.peerDependencies = peerDependencies;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.0.0-alpha.1",
3
+ "version": "2.0.0-alpha.3",
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",
@@ -19,17 +19,18 @@
19
19
  "scripts": {
20
20
  "knip": "node ./dist/cli.js",
21
21
  "knip:production": "node ./dist/cli.js --production --strict",
22
- "lint": "eslint src",
23
- "lint:fix": "eslint src --fix",
24
- "format": "prettier scripts src test --with-node-modules --write --config .prettierrc",
25
- "test": "globstar -- node --loader tsx --test \"test/**/*.test.ts\"",
22
+ "lint": "eslint src tests --ignore",
23
+ "lint:fix": "eslint src tests --fix",
24
+ "format": "prettier scripts src tests --with-node-modules --write --config .prettierrc",
25
+ "test": "globstar -- node --loader tsx --test \"tests/**/*.test.ts\"",
26
26
  "watch": "tsc --watch",
27
- "prebuild": "rm -rf dist",
27
+ "_prebuild": "rm -rf dist",
28
28
  "build": "tsc",
29
29
  "docs": "npm run docs:cli && npm run docs:plugins && npm run docs:format",
30
30
  "docs:cli": "tsx ./scripts/update-cli-usage-in-readme.ts",
31
31
  "docs:plugins": "tsx ./scripts/generate-plugin-docs.ts",
32
32
  "docs:format": "remark README.md docs/*.md src/plugins/*/README.md -o",
33
+ "qa": "npm run lint && npm run build && npm run knip && npm run knip:production && npm test",
33
34
  "release": "release-it",
34
35
  "create-plugin": "tsx ./scripts/create-new-plugin.ts"
35
36
  },
@@ -57,24 +58,24 @@
57
58
  "zod": "^3.20.6"
58
59
  },
59
60
  "devDependencies": {
60
- "@jest/types": "29.4.3",
61
+ "@jest/types": "29.5.0",
61
62
  "@npmcli/package-json": "3.0.0",
62
63
  "@release-it/bumper": "4.0.2",
63
64
  "@types/eslint": "8.21.1",
64
65
  "@types/js-yaml": "4.0.5",
65
66
  "@types/micromatch": "4.0.2",
66
67
  "@types/minimist": "1.2.2",
67
- "@types/node": "18.14.2",
68
+ "@types/node": "18.14.6",
68
69
  "@types/npmcli__map-workspaces": "3.0.0",
69
70
  "@types/webpack": "5.28.0",
70
- "@typescript-eslint/eslint-plugin": "5.54.0",
71
- "@typescript-eslint/parser": "5.54.0",
71
+ "@typescript-eslint/eslint-plugin": "5.54.1",
72
+ "@typescript-eslint/parser": "5.54.1",
72
73
  "eslint": "8.35.0",
73
74
  "eslint-import-resolver-typescript": "3.5.3",
74
75
  "eslint-plugin-import": "2.27.5",
75
76
  "globstar": "1.0.0",
76
77
  "prettier": "2.8.4",
77
- "release-it": "^15.6.1",
78
+ "release-it": "^15.7.0",
78
79
  "remark-cli": "11.0.0",
79
80
  "remark-preset-webpro": "0.0.1",
80
81
  "tsx": "3.12.3",