Skip to content

Commit

Permalink
fixup: throw on relative statLocation with remediation instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
JakobJingleheimer committed Oct 6, 2024
1 parent da29815 commit d76e8be
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 3 deletions.
29 changes: 26 additions & 3 deletions lib/internal/modules/package_json_reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@

const {
ArrayIsArray,
ArrayPrototypeJoin,
JSONParse,
ObjectDefineProperty,
StringPrototypeEndsWith,
} = primordials;
const {
codes: {
ERR_INVALID_ARG_VALUE,
},
} = require('internal/errors');
const modulesBinding = internalBinding('modules');
const { resolve } = require('path');
const path = require('path');
const { kEmptyObject } = require('internal/util');
const { fileURLToPath, URL } = require('internal/url');
const {
Expand Down Expand Up @@ -111,7 +118,7 @@ function read(jsonPath, { base, specifier, isESM } = kEmptyObject) {
*/
function readPackage(requestPath) {
// TODO(@anonrig): Remove this function.
return read(resolve(requestPath, 'package.json'));
return read(path.resolve(requestPath, 'package.json'));
}

/**
Expand All @@ -122,10 +129,26 @@ function readPackage(requestPath) {
* @returns {undefined | DeserializedPackageConfig<everything>}
*/
function getNearestParentPackageJSON(startLocation, everything = false) {
const startPath = URL.canParse(startLocation) ? fileURLToPath(startLocation) : startLocation;
let startPath = URL.canParse(startLocation) ? fileURLToPath(startLocation) : startLocation;

validateString(startPath, 'startPath');
validateBoolean(everything, 'everything');

if (!path.isAbsolute(startPath)) {
throw new ERR_INVALID_ARG_VALUE(
'startLocation',
startLocation,
ArrayPrototypeJoin([
'must be a fully resolved location. To use a relative location, first wrap with',
'`import.meta.resolve(startLocation)` in ESM',
'or',
'`path.resolve(__dirname, startLocation) in CJS',
], ' '),
);
}

if (!StringPrototypeEndsWith(startPath, path.sep)) startPath += path.sep;

Check failure on line 150 in lib/internal/modules/package_json_reader.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Expected { after 'if' condition

if (everything) {
const result = modulesBinding.getNearestRawParentPackageJSON(startPath);

Expand Down
1 change: 1 addition & 0 deletions test/fixtures/packages/nested/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "package-with-sub-package"}
4 changes: 4 additions & 0 deletions test/fixtures/packages/nested/sub-pkg-cjs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const { getPackageJSON } = require('node:module');
const { resolve } = require('node:path');

module.exports = getPackageJSON(resolve(__dirname, '..'));
1 change: 1 addition & 0 deletions test/fixtures/packages/nested/sub-pkg-cjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "sub-package", "type": "commonjs"}
3 changes: 3 additions & 0 deletions test/fixtures/packages/nested/sub-pkg-mjs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { getPackageJSON } from 'node:module';

export default getPackageJSON(import.meta.resolve('..'));
1 change: 1 addition & 0 deletions test/fixtures/packages/nested/sub-pkg-mjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "sub-package", "type": "module"}
33 changes: 33 additions & 0 deletions test/parallel/test-get-package-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,36 @@ const pkgType = 'module'; // a non-default value
},
});
}

{ // Throws on unresolved location
let err;
try {
getPackageJSON('..')

Check failure on line 111 in test/parallel/test-get-package-json.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Missing semicolon
} catch (e) {
err = e;
}

assert.strictEqual(err.code, 'ERR_INVALID_ARG_VALUE');
assert.match(err.message, /fully resolved/);
assert.match(err.message, /relative/);
assert.match(err.message, /import\.meta\.resolve/);
assert.match(err.message, /path\.resolve\(__dirname/);
}

{ // Can crawl up (CJS)
const pathToMod = fixtures.path('packages/nested/sub-pkg-cjs/index.js');
const parentPkg = require(pathToMod);

assert.strictEqual(parentPkg.data.name, 'package-with-sub-package');
const pathToParent = fixtures.path('packages/nested/package.json');
assert.strictEqual(parentPkg.path, pathToParent);
}

{ // Can crawl up (ESM)
const pathToMod = fixtures.path('packages/nested/sub-pkg-mjs/index.js');
const parentPkg = require(pathToMod).default;

assert.strictEqual(parentPkg.data.name, 'package-with-sub-package');
const pathToParent = fixtures.path('packages/nested/package.json');
assert.strictEqual(parentPkg.path, pathToParent);
}

0 comments on commit d76e8be

Please sign in to comment.