Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: browserify/resolve
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.20.0
Choose a base ref
...
head repository: browserify/resolve
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.21.0
Choose a head ref

Commits on Mar 3, 2016

  1. [New] add simple CLI util (#94)

     - requires it is executed directly, not via `node`, and not required
     - supports `--preserve-symlinks`, only when node itself supports it
     - supports `--` to stop further argument parsing
     - errors if a specifier is omitted
    
    Co-authored-by: j- <j@skeoh.com>
    Co-authored-by: Jordan Harband <ljharb@gmail.com>
    j- and ljharb committed Mar 3, 2016

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    613efb2 View commit details

Commits on Mar 19, 2021

  1. [Tests] invalid_main fixture had an invalid "name" field

    This error might obscure the real problem with this fixture, so, fixing it
    ljharb committed Mar 19, 2021
    Copy the full SHA
    5fd6ef6 View commit details

Commits on Apr 7, 2021

  1. Copy the full SHA
    7f23b0c View commit details

Commits on May 9, 2021

  1. Copy the full SHA
    1c67407 View commit details
  2. Copy the full SHA
    af633dd View commit details
  3. Copy the full SHA
    6af77d4 View commit details
  4. [Deps] update is-core-module

    ljharb committed May 9, 2021
    Copy the full SHA
    700eb64 View commit details

Commits on May 26, 2021

  1. [Dev Deps] update eslint

    ljharb committed May 26, 2021
    Copy the full SHA
    1262e72 View commit details
  2. [Deps] update path-parse

    ljharb committed May 26, 2021
    2
    Copy the full SHA
    d7f5c3e View commit details

Commits on Nov 1, 2021

  1. [Refactor] sync: Do not throw on missing files in isFile/`isDirec…

    …tory` (#256)
    Mark Molinaro authored and ljharb committed Nov 1, 2021
    Copy the full SHA
    d688575 View commit details

Commits on Nov 2, 2021

  1. Copy the full SHA
    f669601 View commit details
  2. Copy the full SHA
    09fa26b View commit details
  3. Copy the full SHA
    3e18d90 View commit details
  4. [Deps] update is-core-module

    ljharb committed Nov 2, 2021
    Copy the full SHA
    18c5ad5 View commit details

Commits on Dec 29, 2021

  1. [Tests] add coverage for absolute paths

    Closes #261
    ljharb committed Dec 29, 2021
    Copy the full SHA
    931ad2b View commit details
  2. Copy the full SHA
    dfab53f View commit details
  3. Copy the full SHA
    ebbe162 View commit details
  4. [Dev Deps] update eslint, @ljharb/eslint-config, `array.prototype…

    ….map`, `safe-publish-latest`, `tape`
    ljharb committed Dec 29, 2021
    Copy the full SHA
    c2b7070 View commit details
  5. Copy the full SHA
    d6e0871 View commit details

Commits on Dec 30, 2021

  1. Copy the full SHA
    e538c8a View commit details
  2. Copy the full SHA
    2e23786 View commit details

Commits on Jan 3, 2022

  1. [Dev Deps] update eslint

    ljharb committed Jan 3, 2022
    Copy the full SHA
    6f8d3c4 View commit details
  2. [meta] backport FUNDING.yml

    ljharb committed Jan 3, 2022
    Copy the full SHA
    677ab33 View commit details
  3. [Tests] backport appveyor.yml

    ljharb committed Jan 3, 2022
    Copy the full SHA
    14d92b8 View commit details
  4. v1.21.0

     - [New] add top-level granular entry points
     - [New] add simple CLI util (#94)
     - [Refactor] `sync`: Do not throw on missing files in `isFile`/`isDirectory` (#256)
     - [Deps] update `is-core-module`, `path-parse`
     - [readme] pull in changes from default branch
     - [readme] remove defunct travis badge; update badges
     - [meta] backport FUNDING.yml
     - [meta] skip deleted files in `eclint` check
     - [meta] use `prepublishOnly`, for npm 7+
     - [actions] reuse common workflows
     - [actions] pull in workflows from default branch
     - [actions] use `node/install` instead of `node/run`; use `codecov` action
     - [Tests] backport appveyor.yml
     - [Tests] add coverage for a malformed package.json
     - [Tests] only run `eclint` on intended files
     - [Tests] add coverage for absolute paths
     - [Tests] `invalid_main` fixture had an invalid "name" field
     - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `array.prototype.map`, `safe-publish-latest`, `tape`
     - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape`
    ljharb committed Jan 3, 2022
    Copy the full SHA
    da9e8af View commit details
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

41 changes: 33 additions & 8 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"extends": "@ljharb",
"root": true,

"extends": "@ljharb",

"rules": {
"array-bracket-newline": 0,
"array-element-newline": 0,
"indent": [2, 4],
"strict": 0,
"complexity": 0,
@@ -12,28 +12,53 @@
"dot-notation": [2, { "allowKeywords": true }],
"func-name-matching": 0,
"func-style": 0,
"global-require": 0,
"global-require": 1,
"id-length": [2, { "min": 1, "max": 30 }],
"max-lines-per-function": 0,
"max-nested-callbacks": 0,
"max-params": 0,
"max-statements-per-line": [2, { "max": 2 }],
"max-statements": 0,
"no-magic-numbers": 0,
"no-console": 0,
"no-shadow": 0,
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
"no-use-before-define": 0,
"object-curly-newline": 0,
"operator-linebreak": [2, "before"],
"sort-keys": 0,
},
"overrides": [
{
"files": "bin/**",
"rules": {
"no-process-exit": "off",
},
},
{
"files": "example/**",
"rules": {
"no-console": 0,
},
},
{
"files": "test/resolver/nested_symlinks/mylib/*.js",
"rules": {
"no-throw-literal": 0,
},
},
{
"files": "test/**",
"parserOptions": {
"ecmaVersion": 5,
"allowReserved": false,
},
"rules": {
"dot-notation": [2, { "allowPattern": "throws" }],
"max-lines": 0,
"max-lines-per-function": 0,
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
},
},
],

"ignorePatterns": [
"./test/resolver/malformed_package_json/package.json",
],
}
12 changes: 12 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/resolve
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
54 changes: 0 additions & 54 deletions .github/workflows/node-4+.yml

This file was deleted.

18 changes: 18 additions & 0 deletions .github/workflows/node-aught.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: 'Tests: node.js < 10'

on: [pull_request, push]

jobs:
tests:
uses: ljharb/actions/.github/workflows/node.yml@main
with:
range: '< 10'
type: minors
command: npm run tests-only

node:
name: 'node < 10'
needs: [tests]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
57 changes: 0 additions & 57 deletions .github/workflows/node-iojs.yml

This file was deleted.

24 changes: 2 additions & 22 deletions .github/workflows/node-pretest.yml
Original file line number Diff line number Diff line change
@@ -3,25 +3,5 @@ name: 'Tests: pretest/posttest'
on: [pull_request, push]

jobs:
pretest:
runs-on: ubuntu-latest


steps:
- uses: actions/checkout@v2
- uses: ljharb/actions/node/run@main
name: 'npm install && npm run pretest'
with:
node-version: 'lts/*'
command: 'pretest'

posttest:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: ljharb/actions/node/run@main
name: 'npm install && npm run posttest'
with:
node-version: 'lts/*'
command: 'posttest'
tests:
uses: ljharb/actions/.github/workflows/pretest.yml@main
18 changes: 18 additions & 0 deletions .github/workflows/node-tens.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: 'Tests: node.js >= 10'

on: [pull_request, push]

jobs:
tests:
uses: ljharb/actions/.github/workflows/node.yml@main
with:
range: '>= 10'
type: minors
command: npm run tests-only

node:
name: 'node >= 10'
needs: [tests]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
57 changes: 0 additions & 57 deletions .github/workflows/node-zero.yml

This file was deleted.

8 changes: 4 additions & 4 deletions .github/workflows/rebase.yml
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: ljharb/rebase@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v2
- uses: ljharb/rebase@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4 changes: 1 addition & 3 deletions .github/workflows/require-allow-edits.yml
Original file line number Diff line number Diff line change
@@ -9,6 +9,4 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: ljharb/require-allow-edits@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: ljharb/require-allow-edits@main
6 changes: 4 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -4,7 +4,9 @@ build: off

environment:
matrix:
#- nodejs_version: "15"
#- nodejs_version: "17"
- nodejs_version: "16"
- nodejs_version: "15"
- nodejs_version: "14"
- nodejs_version: "13"
- nodejs_version: "12"
@@ -26,7 +28,6 @@ environment:
matrix:
# fast_finish: true
allow_failures:
- nodejs_version: "5" # due to windows npm bug, registry-side
- nodejs_version: "0.8"
# platform: x86 # x64 has started failing on the registry side, around early November 2020
- nodejs_version: "0.6"
@@ -60,6 +61,7 @@ install:
- IF %nodejs_version% EQU 13 npm -g install npm@7
- IF %nodejs_version% EQU 14 npm -g install npm@7
- IF %nodejs_version% EQU 15 npm -g install npm@7
- IF %nodejs_version% EQU 16 npm -g install npm@7
- set PATH=%APPDATA%\npm;%PATH%
#- IF %nodejs_version% NEQ 0.6 AND %nodejs_version% NEQ 0.8 npm -g install npm
# install modules
3 changes: 3 additions & 0 deletions async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = require('./lib/async');
47 changes: 47 additions & 0 deletions bin/resolve
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env node

'use strict';

var path = require('path');
var fs = require('fs');

if (
!process.argv
|| process.argv.length < 2
|| (process.argv[1] !== __filename && fs.statSync(process.argv[1]).ino !== fs.statSync(__filename).ino)
|| (process.env._ && path.resolve(process.env._) !== __filename)
) {
console.error('Error: `resolve` must be run directly as an executable');
process.exit(1);
}

var supportsPreserveSymlinkFlag = require('supports-preserve-symlinks-flag');

var preserveSymlinks = false;
for (var i = 2; i < process.argv.length; i += 1) {
if (process.argv[i].slice(0, 2) === '--') {
if (supportsPreserveSymlinkFlag && process.argv[i] === '--preserve-symlinks') {
preserveSymlinks = true;
} else if (process.argv[i].length > 2) {
console.error('Unknown argument ' + process.argv[i].replace(/[=].*$/, ''));
process.exit(2);
}
process.argv.splice(i, 1);
i -= 1;
if (process.argv[i] === '--') { break; } // eslint-disable-line no-restricted-syntax
}
}

if (process.argv.length < 3) {
console.error('Error: `resolve` expects a specifier');
process.exit(2);
}

var resolve = require('../');

var result = resolve.sync(process.argv[2], {
basedir: process.cwd(),
preserveSymlinks: preserveSymlinks
});

console.log(result);
3 changes: 1 addition & 2 deletions lib/core.js
Original file line number Diff line number Diff line change
@@ -15,9 +15,8 @@ function specifierIncluded(specifier) {
return cur < ver;
} else if (op === '>=') {
return cur >= ver;
} else {
return false;
}
return false;
}
return op === '>=';
}
93 changes: 81 additions & 12 deletions lib/core.json
Original file line number Diff line number Diff line change
@@ -1,83 +1,152 @@
{
"assert": true,
"node:assert": [">= 14.18 && < 15", ">= 16"],
"assert/strict": ">= 15",
"node:assert/strict": ">= 16",
"async_hooks": ">= 8",
"node:async_hooks": [">= 14.18 && < 15", ">= 16"],
"buffer_ieee754": "< 0.9.7",
"buffer": true,
"node:buffer": [">= 14.18 && < 15", ">= 16"],
"child_process": true,
"node:child_process": [">= 14.18 && < 15", ">= 16"],
"cluster": true,
"node:cluster": [">= 14.18 && < 15", ">= 16"],
"console": true,
"node:console": [">= 14.18 && < 15", ">= 16"],
"constants": true,
"node:constants": [">= 14.18 && < 15", ">= 16"],
"crypto": true,
"node:crypto": [">= 14.18 && < 15", ">= 16"],
"_debug_agent": ">= 1 && < 8",
"_debugger": "< 8",
"dgram": true,
"diagnostics_channel": ">= 15.1",
"node:dgram": [">= 14.18 && < 15", ">= 16"],
"diagnostics_channel": [">= 14.17 && < 15", ">= 15.1"],
"node:diagnostics_channel": [">= 14.18 && < 15", ">= 16"],
"dns": true,
"node:dns": [">= 14.18 && < 15", ">= 16"],
"dns/promises": ">= 15",
"node:dns/promises": ">= 16",
"domain": ">= 0.7.12",
"node:domain": [">= 14.18 && < 15", ">= 16"],
"events": true,
"node:events": [">= 14.18 && < 15", ">= 16"],
"freelist": "< 6",
"fs": true,
"node:fs": [">= 14.18 && < 15", ">= 16"],
"fs/promises": [">= 10 && < 10.1", ">= 14"],
"node:fs/promises": [">= 14.18 && < 15", ">= 16"],
"_http_agent": ">= 0.11.1",
"node:_http_agent": [">= 14.18 && < 15", ">= 16"],
"_http_client": ">= 0.11.1",
"node:_http_client": [">= 14.18 && < 15", ">= 16"],
"_http_common": ">= 0.11.1",
"node:_http_common": [">= 14.18 && < 15", ">= 16"],
"_http_incoming": ">= 0.11.1",
"node:_http_incoming": [">= 14.18 && < 15", ">= 16"],
"_http_outgoing": ">= 0.11.1",
"node:_http_outgoing": [">= 14.18 && < 15", ">= 16"],
"_http_server": ">= 0.11.1",
"node:_http_server": [">= 14.18 && < 15", ">= 16"],
"http": true,
"node:http": [">= 14.18 && < 15", ">= 16"],
"http2": ">= 8.8",
"node:http2": [">= 14.18 && < 15", ">= 16"],
"https": true,
"inspector": ">= 8.0.0",
"node:https": [">= 14.18 && < 15", ">= 16"],
"inspector": ">= 8",
"node:inspector": [">= 14.18 && < 15", ">= 16"],
"_linklist": "< 8",
"module": true,
"node:module": [">= 14.18 && < 15", ">= 16"],
"net": true,
"node-inspect/lib/_inspect": ">= 7.6.0 && < 12",
"node-inspect/lib/internal/inspect_client": ">= 7.6.0 && < 12",
"node-inspect/lib/internal/inspect_repl": ">= 7.6.0 && < 12",
"node:net": [">= 14.18 && < 15", ">= 16"],
"node-inspect/lib/_inspect": ">= 7.6 && < 12",
"node-inspect/lib/internal/inspect_client": ">= 7.6 && < 12",
"node-inspect/lib/internal/inspect_repl": ">= 7.6 && < 12",
"os": true,
"node:os": [">= 14.18 && < 15", ">= 16"],
"path": true,
"node:path": [">= 14.18 && < 15", ">= 16"],
"path/posix": ">= 15.3",
"node:path/posix": ">= 16",
"path/win32": ">= 15.3",
"node:path/win32": ">= 16",
"perf_hooks": ">= 8.5",
"node:perf_hooks": [">= 14.18 && < 15", ">= 16"],
"process": ">= 1",
"node:process": [">= 14.18 && < 15", ">= 16"],
"punycode": true,
"node:punycode": [">= 14.18 && < 15", ">= 16"],
"querystring": true,
"node:querystring": [">= 14.18 && < 15", ">= 16"],
"readline": true,
"node:readline": [">= 14.18 && < 15", ">= 16"],
"readline/promises": ">= 17",
"node:readline/promises": ">= 17",
"repl": true,
"node:repl": [">= 14.18 && < 15", ">= 16"],
"smalloc": ">= 0.11.5 && < 3",
"_stream_duplex": ">= 0.9.4",
"node:_stream_duplex": [">= 14.18 && < 15", ">= 16"],
"_stream_transform": ">= 0.9.4",
"node:_stream_transform": [">= 14.18 && < 15", ">= 16"],
"_stream_wrap": ">= 1.4.1",
"node:_stream_wrap": [">= 14.18 && < 15", ">= 16"],
"_stream_passthrough": ">= 0.9.4",
"node:_stream_passthrough": [">= 14.18 && < 15", ">= 16"],
"_stream_readable": ">= 0.9.4",
"node:_stream_readable": [">= 14.18 && < 15", ">= 16"],
"_stream_writable": ">= 0.9.4",
"node:_stream_writable": [">= 14.18 && < 15", ">= 16"],
"stream": true,
"node:stream": [">= 14.18 && < 15", ">= 16"],
"stream/consumers": ">= 16.7",
"node:stream/consumers": ">= 16.7",
"stream/promises": ">= 15",
"node:stream/promises": ">= 16",
"stream/web": ">= 16.5",
"node:stream/web": ">= 16.5",
"string_decoder": true,
"node:string_decoder": [">= 14.18 && < 15", ">= 16"],
"sys": [">= 0.6 && < 0.7", ">= 0.8"],
"node:sys": [">= 14.18 && < 15", ">= 16"],
"timers": true,
"node:timers": [">= 14.18 && < 15", ">= 16"],
"timers/promises": ">= 15",
"node:timers/promises": ">= 16",
"_tls_common": ">= 0.11.13",
"node:_tls_common": [">= 14.18 && < 15", ">= 16"],
"_tls_legacy": ">= 0.11.3 && < 10",
"_tls_wrap": ">= 0.11.3",
"node:_tls_wrap": [">= 14.18 && < 15", ">= 16"],
"tls": true,
"node:tls": [">= 14.18 && < 15", ">= 16"],
"trace_events": ">= 10",
"node:trace_events": [">= 14.18 && < 15", ">= 16"],
"tty": true,
"node:tty": [">= 14.18 && < 15", ">= 16"],
"url": true,
"node:url": [">= 14.18 && < 15", ">= 16"],
"util": true,
"node:util": [">= 14.18 && < 15", ">= 16"],
"util/types": ">= 15.3",
"node:util/types": ">= 16",
"v8/tools/arguments": ">= 10 && < 12",
"v8/tools/codemap": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/consarray": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/csvparser": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/logreader": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/profile_view": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/splaytree": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/codemap": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/consarray": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/csvparser": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/logreader": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/profile_view": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8/tools/splaytree": [">= 4.4 && < 5", ">= 5.2 && < 12"],
"v8": ">= 1",
"node:v8": [">= 14.18 && < 15", ">= 16"],
"vm": true,
"node:vm": [">= 14.18 && < 15", ">= 16"],
"wasi": ">= 13.4 && < 13.5",
"worker_threads": ">= 11.7",
"zlib": true
"node:worker_threads": [">= 14.18 && < 15", ">= 16"],
"zlib": true,
"node:zlib": [">= 14.18 && < 15", ">= 16"]
}
2 changes: 1 addition & 1 deletion lib/node-modules-paths.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var path = require('path');
var parse = path.parse || require('path-parse');
var parse = path.parse || require('path-parse'); // eslint-disable-line global-require

var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) {
var prefix = '/';
8 changes: 4 additions & 4 deletions lib/sync.js
Original file line number Diff line number Diff line change
@@ -9,22 +9,22 @@ var realpathFS = fs.realpathSync && typeof fs.realpathSync.native === 'function'

var defaultIsFile = function isFile(file) {
try {
var stat = fs.statSync(file);
var stat = fs.statSync(file, { throwIfNoEntry: false });
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
return stat.isFile() || stat.isFIFO();
return !!stat && (stat.isFile() || stat.isFIFO());
};

var defaultIsDir = function isDirectory(dir) {
try {
var stat = fs.statSync(dir);
var stat = fs.statSync(dir, { throwIfNoEntry: false });
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
return stat.isDirectory();
return !!stat && stat.isDirectory();
};

var defaultRealpathSync = function realpathSync(x) {
30 changes: 18 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{
"name": "resolve",
"description": "resolve like require.resolve() on behalf of files asynchronously and synchronously",
"version": "1.20.0",
"version": "1.21.0",
"repository": {
"type": "git",
"url": "git://github.com/browserify/resolve.git"
},
"bin": {
"resolve": "./bin/resolve"
},
"main": "index.js",
"keywords": [
"resolve",
@@ -14,9 +17,10 @@
"module"
],
"scripts": {
"prepublish": "safe-publish-latest && cp node_modules/is-core-module/core.json ./lib/ ||:",
"prelint": "eclint check '**/*'",
"lint": "eslint --ext=js,mjs .",
"prepublishOnly": "safe-publish-latest && cp node_modules/is-core-module/core.json ./lib/ ||:",
"prepublish": "not-in-publish || npm run prepublishOnly",
"prelint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')",
"lint": "eslint --ext=js,mjs --no-eslintrc -c .eslintrc . 'bin/**'",
"pretests-only": "cd ./test/resolver/nested_symlinks && node mylib/sync && node mylib/async",
"tests-only": "tape test/*.js",
"pretest": "npm run lint",
@@ -25,15 +29,16 @@
"test:multirepo": "cd ./test/resolver/multirepo && npm install && npm test"
},
"devDependencies": {
"@ljharb/eslint-config": "^17.5.1",
"array.prototype.map": "^1.0.3",
"aud": "^1.1.4",
"@ljharb/eslint-config": "^20.1.0",
"array.prototype.map": "^1.0.4",
"aud": "^1.1.5",
"eclint": "^2.8.1",
"eslint": "^7.19.0",
"eslint": "^8.6.0",
"in-publish": "^2.0.1",
"object-keys": "^1.1.1",
"safe-publish-latest": "^1.1.4",
"safe-publish-latest": "^2.0.0",
"tap": "0.4.13",
"tape": "^5.1.1"
"tape": "^5.4.0"
},
"license": "MIT",
"author": {
@@ -45,7 +50,8 @@
"url": "https://github.com/sponsors/ljharb"
},
"dependencies": {
"is-core-module": "^2.2.0",
"path-parse": "^1.0.6"
"is-core-module": "^2.8.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
}
48 changes: 35 additions & 13 deletions readme.markdown
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
# resolve
# resolve <sup>[![Version Badge][2]][1]</sup>

implements the [node `require.resolve()`
algorithm](https://nodejs.org/api/modules.html#modules_all_together)
such that you can `require.resolve()` on behalf of a file asynchronously and
synchronously
implements the [node `require.resolve()` algorithm](https://nodejs.org/api/modules.html#modules_all_together) such that you can `require.resolve()` on behalf of a file asynchronously and synchronously

[![build status](https://secure.travis-ci.org/browserify/resolve.png)](http://travis-ci.org/browserify/resolve)
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][5]][6]
[![dev dependency status][7]][8]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]

[![npm badge][11]][1]

# example

asynchronously resolve:

```js
var resolve = require('resolve');
var resolve = require('resolve/async'); // or, require('resolve')
resolve('tap', { basedir: __dirname }, function (err, res) {
if (err) console.error(err);
else console.log(res);
@@ -27,8 +31,8 @@ $ node example/async.js
synchronously resolve:

```js
var resolve = require('resolve');
var res = resolve.sync('tap', { basedir: __dirname });
var resolve = require('resolve/sync'); // or, `require('resolve').sync
var res = resolve('tap', { basedir: __dirname });
console.log(res);
```

@@ -41,6 +45,8 @@ $ node example/sync.js

```js
var resolve = require('resolve');
var async = require('resolve/async');
var sync = require('resolve/sync');
```

For both the synchronous and asynchronous methods, errors may have any of the following `err.code` values:
@@ -67,7 +73,7 @@ options are:

* opts.isFile - function to asynchronously test whether a file exists

* opts.isDirectory - function to asynchronously test whether a directory exists
* opts.isDirectory - function to asynchronously test whether a file exists and is a directory

* opts.realpath - function to asynchronously resolve a potential symlink to its real path

@@ -79,7 +85,7 @@ options are:
* `opts.packageFilter(pkg, pkgfile, dir)` - transform the parsed package.json contents before looking at the "main" field
* pkg - package data
* pkgfile - path to package.json
* dir - directory for package.json
* dir - directory that contains package.json

* `opts.pathFilter(pkg, path, relativePath)` - transform a path within a package
* pkg - package data
@@ -177,7 +183,7 @@ options are:

* opts.isFile - function to synchronously test whether a file exists

* opts.isDirectory - function to synchronously test whether a directory exists
* opts.isDirectory - function to synchronously test whether a file exists and is a directory

* opts.realpathSync - function to synchronously resolve a potential symlink to its real path

@@ -187,7 +193,7 @@ options are:

* `opts.packageFilter(pkg, dir)` - transform the parsed package.json contents before looking at the "main" field
* pkg - package data
* dir - directory for package.json (Note: the second argument will change to "pkgfile" in v2)
* dir - directory that contains package.json (Note: the second argument will change to "pkgfile" in v2)

* `opts.pathFilter(pkg, path, relativePath)` - transform a path within a package
* pkg - package data
@@ -277,3 +283,19 @@ npm install resolve
# license

MIT

[1]: https://npmjs.org/package/resolve
[2]: https://versionbadg.es/browserify/resolve.svg
[5]: https://david-dm.org/browserify/resolve.svg
[6]: https://david-dm.org/browserify/resolve
[7]: https://david-dm.org/browserify/resolve/dev-status.svg
[8]: https://david-dm.org/browserify/resolve#info=devDependencies
[11]: https://nodei.co/npm/resolve.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/resolve.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/resolve.svg
[downloads-url]: https://npm-stat.com/charts.html?package=resolve
[codecov-image]: https://codecov.io/gh/browserify/resolve/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/browserify/resolve/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/browserify/resolve
[actions-url]: https://github.com/browserify/resolve/actions
3 changes: 3 additions & 0 deletions sync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = require('./lib/sync');
5 changes: 0 additions & 5 deletions test/.eslintrc

This file was deleted.

6 changes: 2 additions & 4 deletions test/mock_sync.js
Original file line number Diff line number Diff line change
@@ -122,9 +122,8 @@ test('symlinked', function (t) {
var dir = path.dirname(resolved);
var base = path.basename(resolved);
return path.join(dir, 'symlinked', base);
} else {
return path.join(resolved, 'symlinked');
}
return path.join(resolved, 'symlinked');
}
};
}
@@ -183,9 +182,8 @@ test('readPackageSync', function (t) {
var readPackageSync = function (readFileSync, file) {
if (file.indexOf(path.join('bar', 'package.json')) >= 0) {
return { main: './something-else.js' };
} else {
return JSON.parse(files[path.resolve(file)]);
}
return JSON.parse(files[path.resolve(file)]);
};

t.test('with readPackage', function (st) {
2 changes: 1 addition & 1 deletion test/node_path.js
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ test('$NODE_PATH', function (t) {
basedir: path.join(__dirname, 'node_path/x'),
isDirectory: isDir
}, function (err, res) {
var root = require('tap/package.json').main;
var root = require('tap/package.json').main; // eslint-disable-line global-require
t.error(err);
t.equal(res, path.resolve(__dirname, '..', 'node_modules/tap', root), 'tap resolves');
});
102 changes: 99 additions & 3 deletions test/resolver.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
var path = require('path');
var test = require('tape');
var resolve = require('../');
var async = require('../async');

test('`./async` entry point', function (t) {
t.equal(resolve, async, '`./async` entry point is the same as `main`');
t.end();
});

test('async foo', function (t) {
t.plan(12);
@@ -288,7 +294,7 @@ test('without basedir', function (t) {
t.plan(1);

var dir = path.join(__dirname, 'resolver/without_basedir');
var tester = require(path.join(dir, 'main.js'));
var tester = require(path.join(dir, 'main.js')); // eslint-disable-line global-require

tester(t, function (err, res, pkg) {
if (err) {
@@ -404,7 +410,7 @@ test('non-string "main" field in package.json', function (t) {
var dir = path.join(__dirname, 'resolver');
resolve('./invalid_main', { basedir: dir }, function (err, res, pkg) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.message, 'package “invalid_main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
t.equal(res, undefined, 'res is undefined');
t.equal(pkg, undefined, 'pkg is undefined');
@@ -417,7 +423,7 @@ test('non-string "main" field in package.json', function (t) {
var dir = path.join(__dirname, 'resolver');
resolve('./invalid_main', { basedir: dir }, function (err, res, pkg) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.message, 'package “invalid_main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
t.equal(res, undefined, 'res is undefined');
t.equal(pkg, undefined, 'pkg is undefined');
@@ -448,3 +454,93 @@ test('browser field in package.json', function (t) {
}
);
});

test('absolute paths', function (t) {
t.plan(4);

var extensionless = __filename.slice(0, -path.extname(__filename).length);

resolve(__filename, function (err, res) {
t.equal(
res,
__filename,
'absolute path to this file resolves'
);
});
resolve(extensionless, function (err, res) {
t.equal(
res,
__filename,
'extensionless absolute path to this file resolves'
);
});
resolve(__filename, { basedir: process.cwd() }, function (err, res) {
t.equal(
res,
__filename,
'absolute path to this file with a basedir resolves'
);
});
resolve(extensionless, { basedir: process.cwd() }, function (err, res) {
t.equal(
res,
__filename,
'extensionless absolute path to this file with a basedir resolves'
);
});
});

test('malformed package.json', function (t) {
/* eslint operator-linebreak: ["error", "before"], function-paren-newline: "off" */
t.plan(
(3 * 3) // 3 sets of 3 assertions in the final callback
+ 2 // 1 readPackage call with malformed package.json
);

var basedir = path.join(__dirname, 'resolver/malformed_package_json');
var expected = path.join(basedir, 'index.js');

resolve('./index.js', { basedir: basedir }, function (err, res, pkg) {
t.error(err, 'no error');
t.equal(res, expected, 'malformed package.json is silently ignored');
t.equal(pkg, undefined, 'malformed package.json gives an undefined `pkg` argument');
});

resolve(
'./index.js',
{
basedir: basedir,
packageFilter: function (pkg, pkgfile, dir) {
t.fail('should not reach here');
}
},
function (err, res, pkg) {
t.error(err, 'with packageFilter: no error');
t.equal(res, expected, 'with packageFilter: malformed package.json is silently ignored');
t.equal(pkg, undefined, 'with packageFilter: malformed package.json gives an undefined `pkg` argument');
}
);

resolve(
'./index.js',
{
basedir: basedir,
readPackage: function (readFile, pkgfile, cb) {
t.equal(pkgfile, path.join(basedir, 'package.json'), 'readPackageSync: `pkgfile` is package.json path');
readFile(pkgfile, function (err, result) {
try {
cb(null, JSON.parse(result));
} catch (e) {
t.ok(e instanceof SyntaxError, 'readPackage: malformed package.json parses as a syntax error');
cb(null);
}
});
}
},
function (err, res, pkg) {
t.error(err, 'with readPackage: no error');
t.equal(res, expected, 'with readPackage: malformed package.json is silently ignored');
t.equal(pkg, undefined, 'with readPackage: malformed package.json gives an undefined `pkg` argument');
}
);
});
2 changes: 1 addition & 1 deletion test/resolver/invalid_main/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "invalid main",
"name": "invalid_main",
"main": [
"why is this a thing",
"srsly omg wtf"
Empty file.
1 change: 1 addition & 0 deletions test/resolver/malformed_package_json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{
91 changes: 88 additions & 3 deletions test/resolver_sync.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
var path = require('path');
var fs = require('fs');
var test = require('tape');

var resolve = require('../');
var sync = require('../sync');

test('`./sync` entry point', function (t) {
t.equal(resolve.sync, sync, '`./sync` entry point is the same as `.sync` on `main`');
t.end();
});

test('foo', function (t) {
var dir = path.join(__dirname, 'resolver');
@@ -200,7 +208,6 @@ test('incorrect main', function (t) {
});

var stubStatSync = function stubStatSync(fn) {
var fs = require('fs');
var statSync = fs.statSync;
try {
fs.statSync = function () {
@@ -321,7 +328,7 @@ test('non-string "main" field in package.json', function (t) {
t.fail('should not get here');
} catch (err) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.message, 'package “invalid_main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
}
t.end();
@@ -335,7 +342,7 @@ test('non-string "main" field in package.json', function (t) {
t.fail('should not get here');
} catch (err) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.message, 'package “invalid_main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
}
t.end();
@@ -356,3 +363,81 @@ test('browser field in package.json', function (t) {
t.equal(res, path.join(dir, 'browser_field', 'b.js'));
t.end();
});

test('absolute paths', function (t) {
var extensionless = __filename.slice(0, -path.extname(__filename).length);

t.equal(
resolve.sync(__filename),
__filename,
'absolute path to this file resolves'
);
t.equal(
resolve.sync(extensionless),
__filename,
'extensionless absolute path to this file resolves'
);
t.equal(
resolve.sync(__filename, { basedir: process.cwd() }),
__filename,
'absolute path to this file with a basedir resolves'
);
t.equal(
resolve.sync(extensionless, { basedir: process.cwd() }),
__filename,
'extensionless absolute path to this file with a basedir resolves'
);

t.end();
});

test('malformed package.json', function (t) {
t.plan(5);

var basedir = path.join(__dirname, 'resolver/malformed_package_json');
var expected = path.join(basedir, 'index.js');

t.equal(
resolve.sync('./index.js', { basedir: basedir }),
expected,
'malformed package.json is silently ignored'
);

var res1 = resolve.sync(
'./index.js',
{
basedir: basedir,
packageFilter: function (pkg, pkgfile, dir) {
t.fail('should not reach here');
}
}
);

t.equal(
res1,
expected,
'with packageFilter: malformed package.json is silently ignored'
);

var res2 = resolve.sync(
'./index.js',
{
basedir: basedir,
readPackageSync: function (readFileSync, pkgfile) {
t.equal(pkgfile, path.join(basedir, 'package.json'), 'readPackageSync: `pkgfile` is package.json path');
var result = String(readFileSync(pkgfile));
try {
return JSON.parse(result);
} catch (e) {
t.ok(e instanceof SyntaxError, 'readPackageSync: malformed package.json parses as a syntax error');
}
}
}
);

t.equal(
res2,
expected,
'with readPackageSync: malformed package.json is silently ignored'
);
});