Socket
Socket
Sign inDemoInstall

@rollup/plugin-node-resolve

Package Overview
Dependencies
Maintainers
4
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rollup/plugin-node-resolve - npm Package Compare versions

Comparing version 11.0.1 to 11.1.0

8

CHANGELOG.md
# @rollup/plugin-node-resolve ChangeLog
## v11.1.0
_2021-01-15_
### Features
- feat: support pkg imports and export array (#693)
## v11.0.1

@@ -4,0 +12,0 @@

467

dist/cjs/index.js

@@ -11,2 +11,3 @@ 'use strict';

var util = require('util');
var url = require('url');
var resolve = require('resolve');

@@ -233,164 +234,328 @@ var pluginutils = require('@rollup/pluginutils');

const resolveImportPath = util.promisify(resolve__default['default']);
const readFile$1 = util.promisify(fs__default['default'].readFile);
/* eslint-disable no-await-in-loop */
const pathNotFoundError = (importPath, importer, subPath, pkgPath) =>
new Error(
`Could not resolve import "${importPath}" in "${importer}".` +
` Package subpath "${subPath}" is not defined by "exports" in ${pkgPath}`
);
const fileExists = util.promisify(fs__default['default'].exists);
function findExportKeyMatch(exportMap, subPath) {
if (subPath in exportMap) {
return subPath;
function isModuleDir(current, moduleDirs) {
return moduleDirs.some((dir) => current.endsWith(dir));
}
async function findPackageJson(base, moduleDirs) {
const { root } = path__default['default'].parse(base);
let current = base;
while (current !== root && !isModuleDir(current, moduleDirs)) {
const pkgJsonPath = path__default['default'].join(current, 'package.json');
if (await fileExists(pkgJsonPath)) {
const pkgJsonString = fs__default['default'].readFileSync(pkgJsonPath, 'utf-8');
return { pkgJson: JSON.parse(pkgJsonString), pkgPath: current, pkgJsonPath };
}
current = path__default['default'].resolve(current, '..');
}
return null;
}
const matchKeys = Object.keys(exportMap)
.filter((key) => key.endsWith('/') || key.endsWith('*'))
.sort((a, b) => b.length - a.length);
function isUrl(str) {
try {
return !!new URL(str);
} catch (_) {
return false;
}
}
for (const key of matchKeys) {
if (key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
if (subPath.startsWith(keyWithoutStar)) {
return key;
function isConditions(exports) {
return typeof exports === 'object' && Object.keys(exports).every((k) => !k.startsWith('.'));
}
function isMappings(exports) {
return typeof exports === 'object' && !isConditions(exports);
}
function isMixedExports(exports) {
const keys = Object.keys(exports);
return keys.some((k) => k.startsWith('.')) && keys.some((k) => !k.startsWith('.'));
}
function createBaseErrorMsg(importSpecifier, importer) {
return `Could not resolve import "${importSpecifier}" in ${importer}`;
}
function createErrorMsg(context, reason, internal) {
const { importSpecifier, importer, pkgJsonPath } = context;
const base = createBaseErrorMsg(importSpecifier, importer);
const field = internal ? 'imports' : 'exports';
return `${base} using ${field} defined in ${pkgJsonPath}.${reason ? ` ${reason}` : ''}`;
}
class ResolveError extends Error {}
class InvalidConfigurationError extends ResolveError {
constructor(context, reason) {
super(createErrorMsg(context, `Invalid "exports" field. ${reason}`));
}
}
class InvalidModuleSpecifierError extends ResolveError {
constructor(context, internal) {
super(createErrorMsg(context, internal));
}
}
class InvalidPackageTargetError extends ResolveError {
constructor(context, reason) {
super(createErrorMsg(context, reason));
}
}
/* eslint-disable no-await-in-loop, no-undefined */
function includesInvalidSegments(pathSegments, moduleDirs) {
return pathSegments
.split('/')
.slice(1)
.some((t) => ['.', '..', ...moduleDirs].includes(t));
}
async function resolvePackageTarget(context, { target, subpath, pattern, internal }) {
if (typeof target === 'string') {
if (!pattern && subpath.length > 0 && !target.endsWith('/')) {
throw new InvalidModuleSpecifierError(context);
}
if (!target.startsWith('./')) {
if (internal && !['/', '../'].some((p) => target.startsWith(p)) && !isUrl(target)) {
// this is a bare package import, remap it and resolve it using regular node resolve
if (pattern) {
const result = await context.resolveId(
target.replace(/\*/g, subpath),
context.pkgURL.href
);
return result ? url.pathToFileURL(result.location) : null;
}
const result = await context.resolveId(`${target}${subpath}`, context.pkgURL.href);
return result ? url.pathToFileURL(result.location) : null;
}
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
}
if (key.endsWith('/') && subPath.startsWith(key)) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return key;
if (includesInvalidSegments(target, context.moduleDirs)) {
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
}
if (key === subPath) {
// literal match
return key;
const resolvedTarget = new URL(target, context.pkgURL);
if (!resolvedTarget.href.startsWith(context.pkgURL.href)) {
throw new InvalidPackageTargetError(
context,
`Resolved to ${resolvedTarget.href} which is outside package ${context.pkgURL.href}`
);
}
if (includesInvalidSegments(subpath, context.moduleDirs)) {
throw new InvalidModuleSpecifierError(context);
}
if (pattern) {
return resolvedTarget.href.replace(/\*/g, subpath);
}
return new URL(subpath, resolvedTarget).href;
}
return null;
}
function mapSubPath({ importPath, importer, pkgJsonPath, subPath, key, value }) {
if (typeof value === 'string') {
if (typeof key === 'string' && key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
const subPathAfterKey = subPath.substring(keyWithoutStar.length);
return value.replace(/\*/g, subPathAfterKey);
if (Array.isArray(target)) {
let lastError;
for (const item of target) {
try {
const resolved = await resolvePackageTarget(context, {
target: item,
subpath,
pattern,
internal
});
// return if defined or null, but not undefined
if (resolved !== undefined) {
return resolved;
}
} catch (error) {
if (!(error instanceof InvalidPackageTargetError)) {
throw error;
} else {
lastError = error;
}
}
}
if (value.endsWith('/')) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return `${value}${subPath.substring(key.length)}`;
if (lastError) {
throw lastError;
}
return null;
}
// mapping is a string, for example { "./foo": "./dist/foo.js" }
return value;
if (target && typeof target === 'object') {
for (const [key, value] of Object.entries(target)) {
if (key === 'default' || context.conditions.includes(key)) {
const resolved = await resolvePackageTarget(context, {
target: value,
subpath,
pattern,
internal
});
// return if defined or null, but not undefined
if (resolved !== undefined) {
return resolved;
}
}
}
return undefined;
}
if (Array.isArray(value)) {
// mapping is an array with fallbacks, for example { "./foo": ["foo:bar", "./dist/foo.js"] }
return value.find((v) => v.startsWith('./'));
if (target === null) {
return null;
}
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
throw new InvalidPackageTargetError(context, `Invalid exports field.`);
}
function findEntrypoint({
importPath,
importer,
pkgJsonPath,
subPath,
exportMap,
conditions,
key
}) {
if (typeof exportMap !== 'object') {
return mapSubPath({ importPath, importer, pkgJsonPath, subPath, key, value: exportMap });
/* eslint-disable no-await-in-loop */
async function resolvePackageImportsExports(context, { matchKey, matchObj, internal }) {
if (!matchKey.endsWith('*') && matchKey in matchObj) {
const target = matchObj[matchKey];
const resolved = await resolvePackageTarget(context, { target, subpath: '', internal });
return resolved;
}
// iterate conditions recursively, find the first that matches all conditions
for (const [condition, subExportMap] of Object.entries(exportMap)) {
if (conditions.includes(condition)) {
const mappedSubPath = findEntrypoint({
importPath,
importer,
pkgJsonPath,
subPath,
exportMap: subExportMap,
conditions,
key
const expansionKeys = Object.keys(matchObj)
.filter((k) => k.endsWith('/') || k.endsWith('*'))
.sort((a, b) => b.length - a.length);
for (const expansionKey of expansionKeys) {
const prefix = expansionKey.substring(0, expansionKey.length - 1);
if (expansionKey.endsWith('*') && matchKey.startsWith(prefix)) {
const target = matchObj[expansionKey];
const subpath = matchKey.substring(expansionKey.length - 1);
const resolved = await resolvePackageTarget(context, {
target,
subpath,
pattern: true,
internal
});
if (mappedSubPath) {
return mappedSubPath;
}
return resolved;
}
}
throw pathNotFoundError(importer, subPath, pkgJsonPath);
}
function findEntrypointTopLevel({
importPath,
importer,
pkgJsonPath,
subPath,
exportMap,
conditions
}) {
if (typeof exportMap !== 'object') {
// the export map shorthand, for example { exports: "./index.js" }
if (subPath !== '.') {
// shorthand only supports a main entrypoint
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
if (matchKey.startsWith(expansionKey)) {
const target = matchObj[expansionKey];
const subpath = matchKey.substring(expansionKey.length);
const resolved = await resolvePackageTarget(context, { target, subpath, internal });
return resolved;
}
return mapSubPath({ importPath, importer, pkgJsonPath, subPath, key: null, value: exportMap });
}
// export map is an object, the top level can be either conditions or sub path mappings
const keys = Object.keys(exportMap);
const isConditions = keys.every((k) => !k.startsWith('.'));
const isMappings = keys.every((k) => k.startsWith('.'));
throw new InvalidModuleSpecifierError(context, internal);
}
if (!isConditions && !isMappings) {
throw new Error(
`Invalid package config ${pkgJsonPath}, "exports" cannot contain some keys starting with '.'` +
' and some not. The exports object must either be an object of package subpath keys or an object of main entry' +
' condition name keys only.'
async function resolvePackageExports(context, subpath, exports) {
if (isMixedExports(exports)) {
throw new InvalidConfigurationError(
context,
'All keys must either start with ./, or without one.'
);
}
let key = null;
let exportMapForSubPath;
if (subpath === '.') {
let mainExport;
// If exports is a String or Array, or an Object containing no keys starting with ".", then
if (typeof exports === 'string' || Array.isArray(exports) || isConditions(exports)) {
mainExport = exports;
} else if (isMappings(exports)) {
mainExport = exports['.'];
}
if (isConditions) {
// top level is conditions, for example { "import": ..., "require": ..., "module": ... }
if (subPath !== '.') {
// package with top level conditions means it only supports a main entrypoint
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
if (mainExport) {
const resolved = await resolvePackageTarget(context, { target: mainExport, subpath: '' });
if (resolved) {
return resolved;
}
}
exportMapForSubPath = exportMap;
} else {
// top level is sub path mappings, for example { ".": ..., "./foo": ..., "./bar": ... }
key = findExportKeyMatch(exportMap, subPath);
if (!key) {
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
} else if (isMappings(exports)) {
const resolvedMatch = await resolvePackageImportsExports(context, {
matchKey: subpath,
matchObj: exports
});
if (resolvedMatch) {
return resolvedMatch;
}
exportMapForSubPath = exportMap[key];
}
return findEntrypoint({
importPath,
throw new InvalidModuleSpecifierError(context);
}
async function resolvePackageImports({
importSpecifier,
importer,
moduleDirs,
conditions,
resolveId
}) {
const result = await findPackageJson(importer, moduleDirs);
if (!result) {
throw new Error(createBaseErrorMsg('. Could not find a parent package.json.'));
}
const { pkgPath, pkgJsonPath, pkgJson } = result;
const pkgURL = url.pathToFileURL(`${pkgPath}/`);
const context = {
importer,
importSpecifier,
moduleDirs,
pkgURL,
pkgJsonPath,
subPath,
exportMap: exportMapForSubPath,
conditions,
key
resolveId
};
const { imports } = pkgJson;
if (!imports) {
throw new InvalidModuleSpecifierError(context, true);
}
if (importSpecifier === '#' || importSpecifier.startsWith('#/')) {
throw new InvalidModuleSpecifierError(context, 'Invalid import specifier.');
}
return resolvePackageImportsExports(context, {
matchKey: importSpecifier,
matchObj: imports,
internal: true
});
}
const resolveImportPath = util.promisify(resolve__default['default']);
const readFile$1 = util.promisify(fs__default['default'].readFile);
async function getPackageJson(importer, pkgName, resolveOptions, moduleDirectories) {
if (importer) {
const selfPackageJsonResult = await findPackageJson(importer, moduleDirectories);
if (selfPackageJsonResult && selfPackageJsonResult.pkgJson.name === pkgName) {
// the referenced package name is the current package
return selfPackageJsonResult;
}
}
try {
const pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
const pkgJson = JSON.parse(await readFile$1(pkgJsonPath, 'utf-8'));
return { pkgJsonPath, pkgJson };
} catch (_) {
return null;
}
}
async function resolveId({
importer,
importPath,
importSpecifier,
exportConditions,

@@ -441,28 +606,57 @@ warn,

const pkgName = getPackageName(importPath);
if (pkgName) {
let pkgJsonPath;
let pkgJson;
try {
pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
pkgJson = JSON.parse(await readFile$1(pkgJsonPath, 'utf-8'));
} catch (_) {
// if there is no package.json we defer to regular resolve behavior
}
const pkgName = getPackageName(importSpecifier);
if (importSpecifier.startsWith('#')) {
// this is a package internal import, resolve using package imports field
const resolveResult = await resolvePackageImports({
importSpecifier,
importer,
moduleDirs: moduleDirectories,
conditions: exportConditions,
resolveId(id, parent) {
return resolveId({
importSpecifier: id,
importer: parent,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
});
}
});
location = url.fileURLToPath(resolveResult);
} else if (pkgName) {
// it's a bare import, find the package.json and resolve using package exports if available
const result = await getPackageJson(importer, pkgName, resolveOptions, moduleDirectories);
if (pkgJsonPath && pkgJson && pkgJson.exports) {
if (result && result.pkgJson.exports) {
const { pkgJson, pkgJsonPath } = result;
try {
const packageSubPath =
pkgName === importPath ? '.' : `.${importPath.substring(pkgName.length)}`;
const mappedSubPath = findEntrypointTopLevel({
const subpath =
pkgName === importSpecifier ? '.' : `.${importSpecifier.substring(pkgName.length)}`;
const pkgDr = pkgJsonPath.replace('package.json', '');
const pkgURL = url.pathToFileURL(pkgDr);
const context = {
importer,
importPath,
importSpecifier,
moduleDirs: moduleDirectories,
pkgURL,
pkgJsonPath,
subPath: packageSubPath,
exportMap: pkgJson.exports,
conditions: exportConditions
});
const pkgDir = path__default['default'].dirname(pkgJsonPath);
location = path__default['default'].join(pkgDir, mappedSubPath);
};
const resolvedPackageExport = await resolvePackageExports(
context,
subpath,
pkgJson.exports
);
location = url.fileURLToPath(resolvedPackageExport);
} catch (error) {
if (!(error instanceof ResolveError)) {
throw error;
}
warn(error);

@@ -475,4 +669,5 @@ return null;

if (!location) {
// package has no imports or exports, use classic node resolve
try {
location = await resolveImportPath(importPath, resolveOptions);
location = await resolveImportPath(importSpecifier, resolveOptions);
} catch (error) {

@@ -520,3 +715,3 @@ if (error.code !== 'MODULE_NOT_FOUND') {

importer,
importPath: importSpecifierList[i],
importSpecifier: importSpecifierList[i],
exportConditions,

@@ -523,0 +718,0 @@ warn,

@@ -7,2 +7,3 @@ import path, { dirname, resolve, extname, normalize, sep } from 'path';

import { promisify } from 'util';
import { pathToFileURL, fileURLToPath } from 'url';
import resolve$1 from 'resolve';

@@ -220,164 +221,328 @@ import { createFilter } from '@rollup/pluginutils';

const resolveImportPath = promisify(resolve$1);
const readFile$1 = promisify(fs.readFile);
/* eslint-disable no-await-in-loop */
const pathNotFoundError = (importPath, importer, subPath, pkgPath) =>
new Error(
`Could not resolve import "${importPath}" in "${importer}".` +
` Package subpath "${subPath}" is not defined by "exports" in ${pkgPath}`
);
const fileExists = promisify(fs.exists);
function findExportKeyMatch(exportMap, subPath) {
if (subPath in exportMap) {
return subPath;
function isModuleDir(current, moduleDirs) {
return moduleDirs.some((dir) => current.endsWith(dir));
}
async function findPackageJson(base, moduleDirs) {
const { root } = path.parse(base);
let current = base;
while (current !== root && !isModuleDir(current, moduleDirs)) {
const pkgJsonPath = path.join(current, 'package.json');
if (await fileExists(pkgJsonPath)) {
const pkgJsonString = fs.readFileSync(pkgJsonPath, 'utf-8');
return { pkgJson: JSON.parse(pkgJsonString), pkgPath: current, pkgJsonPath };
}
current = path.resolve(current, '..');
}
return null;
}
const matchKeys = Object.keys(exportMap)
.filter((key) => key.endsWith('/') || key.endsWith('*'))
.sort((a, b) => b.length - a.length);
function isUrl(str) {
try {
return !!new URL(str);
} catch (_) {
return false;
}
}
for (const key of matchKeys) {
if (key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
if (subPath.startsWith(keyWithoutStar)) {
return key;
function isConditions(exports) {
return typeof exports === 'object' && Object.keys(exports).every((k) => !k.startsWith('.'));
}
function isMappings(exports) {
return typeof exports === 'object' && !isConditions(exports);
}
function isMixedExports(exports) {
const keys = Object.keys(exports);
return keys.some((k) => k.startsWith('.')) && keys.some((k) => !k.startsWith('.'));
}
function createBaseErrorMsg(importSpecifier, importer) {
return `Could not resolve import "${importSpecifier}" in ${importer}`;
}
function createErrorMsg(context, reason, internal) {
const { importSpecifier, importer, pkgJsonPath } = context;
const base = createBaseErrorMsg(importSpecifier, importer);
const field = internal ? 'imports' : 'exports';
return `${base} using ${field} defined in ${pkgJsonPath}.${reason ? ` ${reason}` : ''}`;
}
class ResolveError extends Error {}
class InvalidConfigurationError extends ResolveError {
constructor(context, reason) {
super(createErrorMsg(context, `Invalid "exports" field. ${reason}`));
}
}
class InvalidModuleSpecifierError extends ResolveError {
constructor(context, internal) {
super(createErrorMsg(context, internal));
}
}
class InvalidPackageTargetError extends ResolveError {
constructor(context, reason) {
super(createErrorMsg(context, reason));
}
}
/* eslint-disable no-await-in-loop, no-undefined */
function includesInvalidSegments(pathSegments, moduleDirs) {
return pathSegments
.split('/')
.slice(1)
.some((t) => ['.', '..', ...moduleDirs].includes(t));
}
async function resolvePackageTarget(context, { target, subpath, pattern, internal }) {
if (typeof target === 'string') {
if (!pattern && subpath.length > 0 && !target.endsWith('/')) {
throw new InvalidModuleSpecifierError(context);
}
if (!target.startsWith('./')) {
if (internal && !['/', '../'].some((p) => target.startsWith(p)) && !isUrl(target)) {
// this is a bare package import, remap it and resolve it using regular node resolve
if (pattern) {
const result = await context.resolveId(
target.replace(/\*/g, subpath),
context.pkgURL.href
);
return result ? pathToFileURL(result.location) : null;
}
const result = await context.resolveId(`${target}${subpath}`, context.pkgURL.href);
return result ? pathToFileURL(result.location) : null;
}
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
}
if (key.endsWith('/') && subPath.startsWith(key)) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return key;
if (includesInvalidSegments(target, context.moduleDirs)) {
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
}
if (key === subPath) {
// literal match
return key;
const resolvedTarget = new URL(target, context.pkgURL);
if (!resolvedTarget.href.startsWith(context.pkgURL.href)) {
throw new InvalidPackageTargetError(
context,
`Resolved to ${resolvedTarget.href} which is outside package ${context.pkgURL.href}`
);
}
if (includesInvalidSegments(subpath, context.moduleDirs)) {
throw new InvalidModuleSpecifierError(context);
}
if (pattern) {
return resolvedTarget.href.replace(/\*/g, subpath);
}
return new URL(subpath, resolvedTarget).href;
}
return null;
}
function mapSubPath({ importPath, importer, pkgJsonPath, subPath, key, value }) {
if (typeof value === 'string') {
if (typeof key === 'string' && key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
const subPathAfterKey = subPath.substring(keyWithoutStar.length);
return value.replace(/\*/g, subPathAfterKey);
if (Array.isArray(target)) {
let lastError;
for (const item of target) {
try {
const resolved = await resolvePackageTarget(context, {
target: item,
subpath,
pattern,
internal
});
// return if defined or null, but not undefined
if (resolved !== undefined) {
return resolved;
}
} catch (error) {
if (!(error instanceof InvalidPackageTargetError)) {
throw error;
} else {
lastError = error;
}
}
}
if (value.endsWith('/')) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return `${value}${subPath.substring(key.length)}`;
if (lastError) {
throw lastError;
}
return null;
}
// mapping is a string, for example { "./foo": "./dist/foo.js" }
return value;
if (target && typeof target === 'object') {
for (const [key, value] of Object.entries(target)) {
if (key === 'default' || context.conditions.includes(key)) {
const resolved = await resolvePackageTarget(context, {
target: value,
subpath,
pattern,
internal
});
// return if defined or null, but not undefined
if (resolved !== undefined) {
return resolved;
}
}
}
return undefined;
}
if (Array.isArray(value)) {
// mapping is an array with fallbacks, for example { "./foo": ["foo:bar", "./dist/foo.js"] }
return value.find((v) => v.startsWith('./'));
if (target === null) {
return null;
}
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
throw new InvalidPackageTargetError(context, `Invalid exports field.`);
}
function findEntrypoint({
importPath,
importer,
pkgJsonPath,
subPath,
exportMap,
conditions,
key
}) {
if (typeof exportMap !== 'object') {
return mapSubPath({ importPath, importer, pkgJsonPath, subPath, key, value: exportMap });
/* eslint-disable no-await-in-loop */
async function resolvePackageImportsExports(context, { matchKey, matchObj, internal }) {
if (!matchKey.endsWith('*') && matchKey in matchObj) {
const target = matchObj[matchKey];
const resolved = await resolvePackageTarget(context, { target, subpath: '', internal });
return resolved;
}
// iterate conditions recursively, find the first that matches all conditions
for (const [condition, subExportMap] of Object.entries(exportMap)) {
if (conditions.includes(condition)) {
const mappedSubPath = findEntrypoint({
importPath,
importer,
pkgJsonPath,
subPath,
exportMap: subExportMap,
conditions,
key
const expansionKeys = Object.keys(matchObj)
.filter((k) => k.endsWith('/') || k.endsWith('*'))
.sort((a, b) => b.length - a.length);
for (const expansionKey of expansionKeys) {
const prefix = expansionKey.substring(0, expansionKey.length - 1);
if (expansionKey.endsWith('*') && matchKey.startsWith(prefix)) {
const target = matchObj[expansionKey];
const subpath = matchKey.substring(expansionKey.length - 1);
const resolved = await resolvePackageTarget(context, {
target,
subpath,
pattern: true,
internal
});
if (mappedSubPath) {
return mappedSubPath;
}
return resolved;
}
}
throw pathNotFoundError(importer, subPath, pkgJsonPath);
}
function findEntrypointTopLevel({
importPath,
importer,
pkgJsonPath,
subPath,
exportMap,
conditions
}) {
if (typeof exportMap !== 'object') {
// the export map shorthand, for example { exports: "./index.js" }
if (subPath !== '.') {
// shorthand only supports a main entrypoint
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
if (matchKey.startsWith(expansionKey)) {
const target = matchObj[expansionKey];
const subpath = matchKey.substring(expansionKey.length);
const resolved = await resolvePackageTarget(context, { target, subpath, internal });
return resolved;
}
return mapSubPath({ importPath, importer, pkgJsonPath, subPath, key: null, value: exportMap });
}
// export map is an object, the top level can be either conditions or sub path mappings
const keys = Object.keys(exportMap);
const isConditions = keys.every((k) => !k.startsWith('.'));
const isMappings = keys.every((k) => k.startsWith('.'));
throw new InvalidModuleSpecifierError(context, internal);
}
if (!isConditions && !isMappings) {
throw new Error(
`Invalid package config ${pkgJsonPath}, "exports" cannot contain some keys starting with '.'` +
' and some not. The exports object must either be an object of package subpath keys or an object of main entry' +
' condition name keys only.'
async function resolvePackageExports(context, subpath, exports) {
if (isMixedExports(exports)) {
throw new InvalidConfigurationError(
context,
'All keys must either start with ./, or without one.'
);
}
let key = null;
let exportMapForSubPath;
if (subpath === '.') {
let mainExport;
// If exports is a String or Array, or an Object containing no keys starting with ".", then
if (typeof exports === 'string' || Array.isArray(exports) || isConditions(exports)) {
mainExport = exports;
} else if (isMappings(exports)) {
mainExport = exports['.'];
}
if (isConditions) {
// top level is conditions, for example { "import": ..., "require": ..., "module": ... }
if (subPath !== '.') {
// package with top level conditions means it only supports a main entrypoint
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
if (mainExport) {
const resolved = await resolvePackageTarget(context, { target: mainExport, subpath: '' });
if (resolved) {
return resolved;
}
}
exportMapForSubPath = exportMap;
} else {
// top level is sub path mappings, for example { ".": ..., "./foo": ..., "./bar": ... }
key = findExportKeyMatch(exportMap, subPath);
if (!key) {
throw pathNotFoundError(importPath, importer, subPath, pkgJsonPath);
} else if (isMappings(exports)) {
const resolvedMatch = await resolvePackageImportsExports(context, {
matchKey: subpath,
matchObj: exports
});
if (resolvedMatch) {
return resolvedMatch;
}
exportMapForSubPath = exportMap[key];
}
return findEntrypoint({
importPath,
throw new InvalidModuleSpecifierError(context);
}
async function resolvePackageImports({
importSpecifier,
importer,
moduleDirs,
conditions,
resolveId
}) {
const result = await findPackageJson(importer, moduleDirs);
if (!result) {
throw new Error(createBaseErrorMsg('. Could not find a parent package.json.'));
}
const { pkgPath, pkgJsonPath, pkgJson } = result;
const pkgURL = pathToFileURL(`${pkgPath}/`);
const context = {
importer,
importSpecifier,
moduleDirs,
pkgURL,
pkgJsonPath,
subPath,
exportMap: exportMapForSubPath,
conditions,
key
resolveId
};
const { imports } = pkgJson;
if (!imports) {
throw new InvalidModuleSpecifierError(context, true);
}
if (importSpecifier === '#' || importSpecifier.startsWith('#/')) {
throw new InvalidModuleSpecifierError(context, 'Invalid import specifier.');
}
return resolvePackageImportsExports(context, {
matchKey: importSpecifier,
matchObj: imports,
internal: true
});
}
const resolveImportPath = promisify(resolve$1);
const readFile$1 = promisify(fs.readFile);
async function getPackageJson(importer, pkgName, resolveOptions, moduleDirectories) {
if (importer) {
const selfPackageJsonResult = await findPackageJson(importer, moduleDirectories);
if (selfPackageJsonResult && selfPackageJsonResult.pkgJson.name === pkgName) {
// the referenced package name is the current package
return selfPackageJsonResult;
}
}
try {
const pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
const pkgJson = JSON.parse(await readFile$1(pkgJsonPath, 'utf-8'));
return { pkgJsonPath, pkgJson };
} catch (_) {
return null;
}
}
async function resolveId({
importer,
importPath,
importSpecifier,
exportConditions,

@@ -428,28 +593,57 @@ warn,

const pkgName = getPackageName(importPath);
if (pkgName) {
let pkgJsonPath;
let pkgJson;
try {
pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
pkgJson = JSON.parse(await readFile$1(pkgJsonPath, 'utf-8'));
} catch (_) {
// if there is no package.json we defer to regular resolve behavior
}
const pkgName = getPackageName(importSpecifier);
if (importSpecifier.startsWith('#')) {
// this is a package internal import, resolve using package imports field
const resolveResult = await resolvePackageImports({
importSpecifier,
importer,
moduleDirs: moduleDirectories,
conditions: exportConditions,
resolveId(id, parent) {
return resolveId({
importSpecifier: id,
importer: parent,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
});
}
});
location = fileURLToPath(resolveResult);
} else if (pkgName) {
// it's a bare import, find the package.json and resolve using package exports if available
const result = await getPackageJson(importer, pkgName, resolveOptions, moduleDirectories);
if (pkgJsonPath && pkgJson && pkgJson.exports) {
if (result && result.pkgJson.exports) {
const { pkgJson, pkgJsonPath } = result;
try {
const packageSubPath =
pkgName === importPath ? '.' : `.${importPath.substring(pkgName.length)}`;
const mappedSubPath = findEntrypointTopLevel({
const subpath =
pkgName === importSpecifier ? '.' : `.${importSpecifier.substring(pkgName.length)}`;
const pkgDr = pkgJsonPath.replace('package.json', '');
const pkgURL = pathToFileURL(pkgDr);
const context = {
importer,
importPath,
importSpecifier,
moduleDirs: moduleDirectories,
pkgURL,
pkgJsonPath,
subPath: packageSubPath,
exportMap: pkgJson.exports,
conditions: exportConditions
});
const pkgDir = path.dirname(pkgJsonPath);
location = path.join(pkgDir, mappedSubPath);
};
const resolvedPackageExport = await resolvePackageExports(
context,
subpath,
pkgJson.exports
);
location = fileURLToPath(resolvedPackageExport);
} catch (error) {
if (!(error instanceof ResolveError)) {
throw error;
}
warn(error);

@@ -462,4 +656,5 @@ return null;

if (!location) {
// package has no imports or exports, use classic node resolve
try {
location = await resolveImportPath(importPath, resolveOptions);
location = await resolveImportPath(importSpecifier, resolveOptions);
} catch (error) {

@@ -507,3 +702,3 @@ if (error.code !== 'MODULE_NOT_FOUND') {

importer,
importPath: importSpecifierList[i],
importSpecifier: importSpecifierList[i],
exportConditions,

@@ -510,0 +705,0 @@ warn,

{
"name": "@rollup/plugin-node-resolve",
"version": "11.0.1",
"version": "11.1.0",
"publishConfig": {

@@ -5,0 +5,0 @@ "access": "public"

@@ -45,2 +45,6 @@ [npm]: https://img.shields.io/npm/v/@rollup/plugin-node-resolve

## Package entrypoints
This plugin supports the package entrypoints feature from node js, specified in the `exports` or `imports` field of a package. Check the [official documentation](https://nodejs.org/api/packages.html#packages_package_entry_points) for more information on how this works.
## Options

@@ -66,2 +70,4 @@

> This option does not work when a package is using [package entrypoints](https://nodejs.org/api/packages.html#packages_package_entry_points)
### `moduleDirectories`

@@ -68,0 +74,0 @@

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