fix: npx usage #613 (#4630)
* fix(resolve-extends): add npx cache detection for package resolution
When running commitlint via npx or npm exec, packages are downloaded
to a temporary npx cache directory (e.g., ~/.npm/_npx) instead of
traditional global node_modules. This commit adds detection and
resolution from the npx cache directory to support running
commitlint via npx.
This helps with issue #613 - enabling usage like:
npx @commitlint/cli --extends @commitlint/config-conventional
Part of fixing #613
* fix(load): add npx cache and search paths support for plugin resolution
- Add npx cache detection to load-plugin.ts (similar to resolve-extends)
- Add LoadPluginOptions interface with searchPaths support
- This enables plugins to be resolved from npx cache when running
via npx/npm exec, and from extended config paths when provided
This helps with issue #613 - enabling plugin resolution when using:
npx @commitlint/cli --extends @commitlint/config-conventional
Part of fixing #613
* fix: address PR feedback for npx cache resolution
- Extract resolveFromNpxCache utility in resolve-extends (Issue #3)
- Use require.resolve with paths option for proper module resolution (Issue #1)
- Iterate ALL npx cache dirs instead of most recent by mtime (Issue #2)
- Add debug logging in catch blocks in load-plugin (Issue #4)
- Tighten control flow for plugin assignment (Issue #5)
- Change string | void to string | undefined return types (Issue #7)
- Add tests for npx cache resolution in load-plugin (Issue #6)
* fix(load): address review feedback from PR #4630
- Add type safety check when assigning plugin to PluginRecords
- Preserve original error when resolution succeeds but import fails
- Only show resolvedPath in debug output when it's defined
- Add mock for resolveFromNpxCache in tests
* fix(load): use resolvedPath for version lookup in debug mode
Previously the version was resolved using the package name which could
incorrectly resolve from commitlint's own node_modules instead of the
actual plugin location (npx cache or searchPath).
This ensures the package.json is loaded from the same path where the
plugin was actually loaded from.
* fix(resolve-extends): add debug logging to silent catch blocks
Add debug logging when errors occur during npx cache reading and
module resolution. This improves diagnosability when DEBUG=true
by providing information about what failed instead of silently
ignoring the errors.
* fix(load): sanitize error messages to avoid exposing internal paths
Add sanitizeErrorMessage function to remove node_modules paths from
error messages. This prevents exposing internal filesystem paths
like /home/user/.npm/_npx/abc123/node_modules in error output.
* fix(load): validate searchPaths to ensure they are safe absolute paths
Add validation to ensure searchPaths are:
1. Strings
2. Absolute paths
3. Existing directories
This prevents potential security issues when untrusted configuration
is used to provide search paths.
* fix(load): maintain backward compatibility for loadPlugin signature
Accept both boolean and options object as third parameter to maintain
backward compatibility with existing callers that pass a boolean
(e.g., loadPlugin(plugins, name, true)).
* fix(load): walk up directory tree to find package.json
The debug version lookup now uses findPackageJson() which walks up
the directory tree from resolvedPath to find the package root,
instead of assuming package.json is adjacent to the resolved file.
This fixes 'version unknown' when resolvedPath points to a nested
file like dist/index.js.
* fix(load): validate searchPaths is a directory
Add check that searchPaths are directories, not just existing paths.
A file path would previously pass validation but cause confusing
behavior when used in require.resolve({ paths: [...] }).
* test(load): add tests for npx cache resolution and searchPaths validation
- Add tests for loading plugins from npx cache
- Add tests for searchPaths validation (non-string, relative, nonexistent, file)
- Add test for backward compatibility with boolean parameter
* test(resolve-extends): add test for resolveFromNpxCache behavior
Add test to verify resolveFromNpxCache returns undefined when
package cannot be resolved from npx cache.
* fix: remove duplicate test names causing lint errors
* test(resolve-extends): remove ineffective test
The test 'resolveFromNpxCache returns undefined when npx cache
does not exist' was not actually testing what it claimed - the
vi.spyOn(require, 'resolve') doesn't affect the internal require
inside resolveFromNpxCache(). Removed to avoid false sense of coverage. E
escapedcat committed
1644f1e8f74a844547e44e3e7a76fabbb96775f8
Parent: b2d06ae
Committed by GitHub <noreply@github.com>
on 3/2/2026, 11:42:46 AM