Socket
Socket
Sign inDemoInstall

esm-resolve

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

esm-resolve - npm Package Compare versions

Comparing version 1.0.4 to 1.0.5

bundle.cjs

124

index.js

@@ -21,5 +21,5 @@ /*

import * as fs from 'fs';
import {statIsFile, statOrNull, isLocal, splitImport} from './lib/helper.js';
import {createRequire} from 'module';
import {matchModuleNode} from './lib/node.js';
import { statIsFile, statOrNull, isLocal } from './lib/helper.js';
import { createRequire } from 'module';
import { matchModuleNode } from './lib/node.js';

@@ -36,2 +36,3 @@

includeMainFallback: true,
checkNestedPackages: true,
};

@@ -91,3 +92,3 @@

/**
* @return {{resolved?: string, info?: types.InternalPackageJson}}
* @return {{resolved: string, info: types.InternalPackageJson} | undefined}
*/

@@ -97,3 +98,3 @@ loadSelfPackage() {

if (candidatePath === undefined) {
return {};
return;
}

@@ -106,5 +107,5 @@

} catch (e) {
return {};
return;
}
return {info, resolved: candidatePath};
return { info, resolved: candidatePath };
}

@@ -114,3 +115,3 @@

* @param {string} name
* @return {{resolved?: string, info?: types.InternalPackageJson}}
* @return {{resolved: string, info: types.InternalPackageJson} | undefined}
*/

@@ -120,3 +121,3 @@ loadPackage(name) {

if (!candidatePaths?.length) {
return {};
return;
}

@@ -126,4 +127,4 @@

const self = this.loadSelfPackage();
if (self.info?.['name'] === name) {
return {resolved: self.resolved, info: self.info};
if (self?.info['name'] === name) {
return { resolved: self.resolved, info: self.info };
}

@@ -140,7 +141,7 @@

if (!packagePath) {
return {};
return;
}
const info = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
return {resolved: path.dirname(packagePath), info};
return { resolved: path.dirname(packagePath), info };
}

@@ -209,3 +210,3 @@

const self = this.loadSelfPackage();
if (!self.info || !self.resolved) {
if (!self) {
return;

@@ -225,52 +226,63 @@ }

const {name, rest} = splitImport(importee);
if (!name) {
return;
}
const pathComponents = importee.split('/');
let index = (pathComponents[0].startsWith('@') ? 2 : 1);
const {resolved, info} = this.loadPackage(name);
if (!resolved || !info) {
return;
}
/** @type {string=} */
let fallbackBest = undefined;
// If we find exports, then use a modern resolution mechanism.
if (info.exports) {
const matched = matchModuleNode(info.exports, rest, this.#options.constraints);
if (matched) {
if (!isLocal(matched)) {
// This module is trying to export something that is not part of its own package.
// This isn't allowed although perhaps we should let it happen.
// This loop only exists to check "bad" nested paths.
do {
const name = pathComponents.slice(0, index).join('/');
const rest = ['.', ...pathComponents.slice(index)].join('/');
const pkg = this.loadPackage(name);
if (!pkg) {
continue;
}
// Match exports.
if (pkg.info.exports) {
const matched = matchModuleNode(pkg.info.exports, rest, this.#options.constraints);
if (matched && isLocal(matched)) {
return `file://${path.join(pkg.resolved, matched)}`;
}
// This module could be trying to export something that is not part of its own package.
// This isn't allowed although perhaps we should let it happen.
if (!this.#options.allowExportFallback) {
return;
}
return `file://${path.join(resolved, matched)}`;
}
if (!this.#options.allowExportFallback) {
return;
}
// If we couldn't find a node, then fallback to running the legacy resolution algorithm. This
// is agaist Node's rules: if an exports field is found, it's all that should be used.
}
// Check a few legacy options.
let simple = rest;
if (simple === '.') {
let found = false;
for (const key of modulePackageNames) {
if (typeof pkg.info[key] === 'string') {
simple = /** @type {string} */ (pkg.info[key]);
found = true;
break;
}
}
// Check a few legacy options and fall back to allowing any path within the package.
let simple = rest;
if (simple === '.') {
let found = false;
for (const key of modulePackageNames) {
if (typeof info[key] === 'string') {
simple = /** @type {string} */ (info[key]);
found = true;
break;
// If we can't find a name which implies a module import, optionally fall back to 'main' even
// if the type of the package isn't correct.
if (!found &&
(this.#options.includeMainFallback || pkg.info['type'] === 'module') &&
typeof pkg.info['main'] === 'string') {
simple = pkg.info['main'];
}
return `file://${path.join(pkg.resolved, simple)}`;
}
// If we can't find a name which implies a module import, optionally fall back to 'main' even
// if the type of the package isn't correct.
if (!found &&
(this.#options.includeMainFallback || info['type'] === 'module') &&
typeof info['main'] === 'string') {
simple = info['main'];
// Otherwise, choose the best (if we're the 1st pass) based on the guessed filename.
if (!fallbackBest) {
fallbackBest = `file://${path.join(pkg.resolved, rest)}`;
}
}
return `file://${path.join(resolved, simple)}`;
} while (this.#options.checkNestedPackages && ++index <= pathComponents.length);
return fallbackBest;
}

@@ -286,3 +298,3 @@

return; // ignore, is valid URL
} catch {}
} catch { }

@@ -302,3 +314,3 @@ /** @type {URL} */

let {pathname} = url;
let { pathname } = url;
const suffix = url.search + url.hash;

@@ -320,3 +332,3 @@

}
// Find the relative path from the request.

@@ -323,0 +335,0 @@ let out = path.relative(this.#importerDir.pathname, pathname);

@@ -23,2 +23,3 @@ /*

* @param {string} p
* @return {fs.Stats?}
*/

@@ -46,21 +47,1 @@ export const statOrNull = (p) => {

export const isLocal = (p) => p === '.' || p.startsWith('./');
/**
* @param {string} importee
* @return {{name?: string, rest: string}}
*/
export function splitImport(importee) {
const split = importee.split('/', 2);
let name = '';
if (!split[0].startsWith('@')) {
name = split[0];
} else if (split[0] && split[1]) {
name = split.join('/');
}
if (!name || name.startsWith('.')) {
return {rest: importee};
}
return {name, rest: '.' + importee.substr(name.length)};
}

@@ -20,3 +20,3 @@ /*

import * as path from 'path';
import {isLocal} from './helper.js';
import { isLocal } from './helper.js';

@@ -35,3 +35,3 @@

if (typeof exports !== 'object') {
return {node: exports};
return { node: exports };
}

@@ -46,3 +46,3 @@ let fallback;

if (key === rest) {
return {node: exports[key]};
return { node: exports[key] };
}

@@ -63,7 +63,7 @@

return {node: exports[key], subpath};
return { node: exports[key], subpath };
}
if (fallback) {
return {node: fallback};
return { node: fallback };
}

@@ -80,3 +80,3 @@ return {};

export function matchModuleNode(exports, rest, constraints) {
let {node, subpath} = matchModuleNodePath(exports, rest);
let { node, subpath } = matchModuleNodePath(exports, rest);

@@ -83,0 +83,0 @@ // Traverse looking for the best conditional. These can be nested.

{
"name": "esm-resolve",
"version": "1.0.4",
"version": "1.0.5",
"description": "Resolves ESM imports in JS",

@@ -8,3 +8,4 @@ "main": "index.js",

".": {
"import": "./index.js"
"import": "./index.js",
"require": "./bundle.cjs"
}

@@ -14,3 +15,4 @@ },

"scripts": {
"test": "ava"
"test": "ava",
"prepublishOnly": "rollup -o bundle.cjs -f cjs index.js --output.exports=named"
},

@@ -22,5 +24,6 @@ "author": "Sam Thorogood <sam.thorogood@gmail.com>",

"@types/node": "^14.14.25",
"ava": "^3.15.0"
"ava": "^3.15.0",
"rollup": "^2.60.2"
},
"types": "index.d.ts"
}

@@ -78,2 +78,11 @@ /*

/**
* If we can't find a match in "node_modules/package" (or under "node_modules/@user/package"),
* then see if there's a nested package. These aren't allowed by Node, but actually show up a
* bit in the wild.
*
* @default true
*/
checkNestedPackages: boolean,
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc