Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@parcel/node-resolver-core

Package Overview
Dependencies
Maintainers
1
Versions
879
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@parcel/node-resolver-core - npm Package Compare versions

Comparing version 2.0.0-nightly.1787 to 2.0.0-nightly.1788

294

lib/NodeResolver.js

@@ -12,2 +12,4 @@ "use strict";

var _diagnostic = _interopRequireWildcard(require("@parcel/diagnostic"));
var _micromatch = _interopRequireDefault(require("micromatch"));

@@ -19,2 +21,6 @@

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -98,3 +104,3 @@

} else if (module.filePath) {
resolved = await this.loadRelative(module.filePath, extensions, env);
resolved = await this.loadRelative(module.filePath, extensions, env, parent ? _path.default.dirname(parent) : this.options.projectRoot);
}

@@ -112,2 +118,100 @@

async findAlternativeNodeModules(moduleName, dir) {
let potentialModules = [];
let root = _path.default.parse(dir).root;
let isOrganisationModule = moduleName.startsWith('@');
while (dir !== root) {
// Skip node_modules directories
if (_path.default.basename(dir) === 'node_modules') {
dir = _path.default.dirname(dir);
}
try {
let modulesDir = _path.default.join(dir, 'node_modules');
let stats = await this.options.inputFS.stat(modulesDir);
if (stats.isDirectory()) {
let dirContent = await this.options.inputFS.readdir(modulesDir); // Filter out the modules that interest us
let modules = dirContent.filter(i => isOrganisationModule ? i.startsWith('@') : !i.startsWith('@')); // If it's an organisation module, loop through all the modules of that organisation
if (isOrganisationModule) {
await Promise.all(modules.map(async item => {
let orgDirPath = _path.default.join(modulesDir, item);
let orgDirContent = await this.options.inputFS.readdir(orgDirPath); // Add all org packages
potentialModules.push(...orgDirContent.map(i => `${item}/${i}`));
}));
}
}
} catch (err) {} // ignore
// Move up a directory
dir = _path.default.dirname(dir);
}
return (0, _utils.fuzzySearch)(potentialModules, moduleName).slice(0, 2);
}
async findAllFilesUp({
dir,
root,
basedir,
maxlength,
collected
}) {
let dirContent = await this.options.inputFS.readdir(dir);
return Promise.all(dirContent.map(async item => {
let fullPath = _path.default.join(dir, item);
let relativePath = (0, _utils.relatifyPath)(basedir, fullPath);
if (relativePath.length < maxlength) {
let stats = await this.options.inputFS.stat(fullPath);
let isDir = stats.isDirectory();
if (isDir || stats.isFile()) {
collected.push(relativePath);
} // If it's a directory, run over each item within said directory...
if (isDir) {
return this.findAllFilesUp({
dir: fullPath,
root,
basedir,
maxlength,
collected
});
}
}
}));
}
async findAlternativeFiles(fileSpecifier, dir) {
let potentialFiles = []; // Find our root, we won't recommend files above the package root as that's bad practise
let pkg = await this.findPackage(dir);
if (!pkg) {
return potentialFiles;
}
let pkgRoot = pkg.pkgdir;
await this.findAllFilesUp({
dir: pkgRoot,
root: pkgRoot,
basedir: dir,
maxlength: fileSpecifier.length + 10,
collected: potentialFiles
});
return (0, _utils.fuzzySearch)(potentialFiles, fileSpecifier).slice(0, 2);
}
async resolveModule({

@@ -159,2 +263,14 @@ filename,

};
let alternativeModules = await this.findAlternativeNodeModules(resolved.moduleName, dir);
if (alternativeModules.length) {
throw new _diagnostic.default({
diagnostic: {
message: `Cannot find module ${resolved.moduleName}`,
hints: alternativeModules.map(r => {
return `Did you mean __${r}__?`;
})
}
});
}
}

@@ -233,7 +349,7 @@

async loadRelative(filename, extensions, env) {
async loadRelative(filename, extensions, env, parentdir) {
// Find a package.json file in the current package.
let pkg = await this.findPackage(_path.default.dirname(filename)); // First try as a file, then as a directory.
return (await this.loadAsFile({
let resolvedFile = (await this.loadAsFile({
file: filename,

@@ -248,4 +364,19 @@ extensions,

pkg
})) // eslint-disable-line no-return-await
;
}));
if (!resolvedFile) {
// If we can't load the file do a fuzzySearch for potential hints
let relativeFileSpecifier = (0, _utils.relatifyPath)(parentdir, filename);
let potentialFiles = await this.findAlternativeFiles(relativeFileSpecifier, parentdir);
throw new _diagnostic.default({
diagnostic: {
message: `Cannot load file '${relativeFileSpecifier}' in '${(0, _utils.relatifyPath)(this.options.projectRoot, parentdir)}'.`,
hints: potentialFiles.map(r => {
return `Did you mean __${r}__?`;
})
}
});
}
return resolvedFile;
}

@@ -301,27 +432,24 @@

async loadNodeModules(module, extensions, env) {
try {
// If a module was specified as a module sub-path (e.g. some-module/some/path),
// it is likely a file. Try loading it as a file first.
if (module.subPath && module.moduleDir) {
let pkg = await this.readPackage(module.moduleDir);
let res = await this.loadAsFile({
file: (0, _nullthrows.default)(module.filePath),
extensions,
env,
pkg
});
// If a module was specified as a module sub-path (e.g. some-module/some/path),
// it is likely a file. Try loading it as a file first.
if (module.subPath && module.moduleDir) {
let pkg = await this.readPackage(module.moduleDir);
let res = await this.loadAsFile({
file: (0, _nullthrows.default)(module.filePath),
extensions,
env,
pkg
});
if (res) {
return res;
}
} // Otherwise, load as a directory.
if (res) {
return res;
}
} // Otherwise, load as a directory.
return await this.loadDirectory({
dir: (0, _nullthrows.default)(module.filePath),
extensions,
env
});
} catch (e) {// ignore
}
return this.loadDirectory({
dir: (0, _nullthrows.default)(module.filePath),
extensions,
env
});
}

@@ -344,27 +472,56 @@

}) {
let failedEntry;
try {
pkg = await this.readPackage(dir); // Get a list of possible package entry points.
pkg = await this.readPackage(dir);
let entries = this.getPackageEntries(pkg, env);
if (pkg) {
// Get a list of possible package entry points.
let entries = this.getPackageEntries(pkg, env);
for (let file of entries) {
// First try loading package.main as a file, then try as a directory.
const res = (await this.loadAsFile({
file,
extensions,
env,
pkg
})) || (await this.loadDirectory({
dir: file,
extensions,
env,
pkg
}));
for (let entry of entries) {
// First try loading package.main as a file, then try as a directory.
let res = (await this.loadAsFile({
file: entry.filename,
extensions,
env,
pkg
})) || (await this.loadDirectory({
dir: entry.filename,
extensions,
env,
pkg
}));
if (res) {
return res;
if (res) {
return res;
} else {
failedEntry = entry;
throw new Error('');
}
}
}
} catch (err) {} // ignore
// Fall back to an index file inside the directory.
} catch (e) {
if (failedEntry && pkg) {
let fileSpecifier = (0, _utils.relatifyPath)(dir, failedEntry.filename);
let alternatives = await this.findAlternativeFiles(fileSpecifier, pkg.pkgdir);
let alternative = alternatives[0];
let pkgContent = await this.options.inputFS.readFile(pkg.pkgfile, 'utf8');
throw new _diagnostic.default({
diagnostic: {
message: `Could not load '${fileSpecifier}' from module '${pkg.name}' found in package.json#${failedEntry.field}`,
language: 'json',
filePath: pkg.pkgfile,
codeFrame: {
code: pkgContent,
codeHighlights: (0, _diagnostic.generateJSONCodeHighlights)(pkgContent, [{
key: `/${failedEntry.field}`,
type: 'value',
message: `'${fileSpecifier}' does not exist${alternative && `, did you mean '${alternative}'?`}'`
}])
}
}
});
}
} // Fall back to an index file inside the directory.

@@ -413,20 +570,34 @@

} else if (typeof pkg.browser === 'string') {
return pkg.browser;
return {
field,
filename: pkg.browser
};
} else if (typeof pkg.browser === 'object' && pkg.browser[pkg.name]) {
return pkg.browser[pkg.name];
return {
field: `browser/${pkg.name}`,
filename: pkg.browser[pkg.name]
};
}
}
return pkg[field];
}).filter(entry => typeof entry === 'string').map(main => {
// Default to index file if no main field find
if (!main || main === '.' || main === './') {
main = 'index';
}
return {
field,
// $FlowFixMe
filename: pkg[field]
};
}).filter(entry => entry && entry.filename && typeof entry.filename === 'string').map(entry => {
// This will never happen, it's just to help out flow?
if (!entry || typeof entry.filename !== 'string') {
throw new Error('Invalid package.json entry.');
} // Current dir refers to an index file
if (typeof main !== 'string') {
throw new Error('invariant: expected string');
if (entry.filename === '.' || entry.filename === './') {
entry.filename = 'index';
}
return _path.default.resolve(pkg.pkgdir, main);
return {
field: entry.field,
filename: _path.default.resolve(pkg.pkgdir, entry.filename)
};
});

@@ -495,9 +666,4 @@ }

if (_path.default.isAbsolute(filename)) {
filename = _path.default.relative(dir, filename);
if (filename[0] !== '.') {
filename = './' + filename;
}
alias = await this.lookupAlias(aliases, filename.replace(/\\/g, '/'), dir);
filename = (0, _utils.relatifyPath)(dir, filename);
alias = await this.lookupAlias(aliases, filename, dir);
} else {

@@ -504,0 +670,0 @@ // It is a node_module. First try the entire filename as a key.

{
"name": "@parcel/node-resolver-core",
"version": "2.0.0-nightly.1787+161837f7",
"version": "2.0.0-nightly.1788+76c5ac6c",
"license": "MIT",

@@ -18,8 +18,9 @@ "publishConfig": {

"dependencies": {
"@parcel/node-libs-browser": "2.0.0-nightly.1787+161837f7",
"@parcel/utils": "2.0.0-nightly.165+161837f7",
"@parcel/diagnostic": "2.0.0-nightly.166+76c5ac6c",
"@parcel/node-libs-browser": "2.0.0-nightly.1788+76c5ac6c",
"@parcel/utils": "2.0.0-nightly.166+76c5ac6c",
"micromatch": "^3.0.4",
"nullthrows": "^1.1.1"
},
"gitHead": "161837f71682f13d2b16e7396e82eb620fe06e4e"
"gitHead": "76c5ac6c8dad3158dd0bd6f2a7879a73a80b1979"
}

@@ -10,3 +10,6 @@ // @flow

import path from 'path';
import {isGlob} from '@parcel/utils';
import {isGlob, fuzzySearch, relatifyPath} from '@parcel/utils';
import ThrowableDiagnostic, {
generateJSONCodeHighlights,
} from '@parcel/diagnostic';
import micromatch from 'micromatch';

@@ -18,3 +21,3 @@ import builtins from './builtins';

type InternalPackageJSON = PackageJSON & {pkgdir: string, ...};
type InternalPackageJSON = PackageJSON & {pkgdir: string, pkgfile: string, ...};
type Options = {|

@@ -99,3 +102,8 @@ options: PluginOptions,

} else if (module.filePath) {
resolved = await this.loadRelative(module.filePath, extensions, env);
resolved = await this.loadRelative(
module.filePath,
extensions,
env,
parent ? path.dirname(parent) : this.options.projectRoot,
);
}

@@ -116,2 +124,118 @@

async findAlternativeNodeModules(
moduleName: string,
dir: string,
): Promise<Array<string>> {
let potentialModules: Array<string> = [];
let root = path.parse(dir).root;
let isOrganisationModule = moduleName.startsWith('@');
while (dir !== root) {
// Skip node_modules directories
if (path.basename(dir) === 'node_modules') {
dir = path.dirname(dir);
}
try {
let modulesDir = path.join(dir, 'node_modules');
let stats = await this.options.inputFS.stat(modulesDir);
if (stats.isDirectory()) {
let dirContent = await this.options.inputFS.readdir(modulesDir);
// Filter out the modules that interest us
let modules = dirContent.filter(i =>
isOrganisationModule ? i.startsWith('@') : !i.startsWith('@'),
);
// If it's an organisation module, loop through all the modules of that organisation
if (isOrganisationModule) {
await Promise.all(
modules.map(async item => {
let orgDirPath = path.join(modulesDir, item);
let orgDirContent = await this.options.inputFS.readdir(
orgDirPath,
);
// Add all org packages
potentialModules.push(
...orgDirContent.map(i => `${item}/${i}`),
);
}),
);
}
}
} catch (err) {
// ignore
}
// Move up a directory
dir = path.dirname(dir);
}
return fuzzySearch(potentialModules, moduleName).slice(0, 2);
}
async findAllFilesUp({
dir,
root,
basedir,
maxlength,
collected,
}: {|
dir: string,
root: string,
basedir: string,
maxlength: number,
collected: Array<string>,
|}) {
let dirContent = await this.options.inputFS.readdir(dir);
return Promise.all(
dirContent.map(async item => {
let fullPath = path.join(dir, item);
let relativePath = relatifyPath(basedir, fullPath);
if (relativePath.length < maxlength) {
let stats = await this.options.inputFS.stat(fullPath);
let isDir = stats.isDirectory();
if (isDir || stats.isFile()) {
collected.push(relativePath);
}
// If it's a directory, run over each item within said directory...
if (isDir) {
return this.findAllFilesUp({
dir: fullPath,
root,
basedir,
maxlength,
collected,
});
}
}
}),
);
}
async findAlternativeFiles(
fileSpecifier: string,
dir: string,
): Promise<Array<string>> {
let potentialFiles: Array<string> = [];
// Find our root, we won't recommend files above the package root as that's bad practise
let pkg = await this.findPackage(dir);
if (!pkg) {
return potentialFiles;
}
let pkgRoot = pkg.pkgdir;
await this.findAllFilesUp({
dir: pkgRoot,
root: pkgRoot,
basedir: dir,
maxlength: fileSpecifier.length + 10,
collected: potentialFiles,
});
return fuzzySearch(potentialFiles, fileSpecifier).slice(0, 2);
}
async resolveModule({

@@ -169,2 +293,18 @@ filename,

};
let alternativeModules = await this.findAlternativeNodeModules(
resolved.moduleName,
dir,
);
if (alternativeModules.length) {
throw new ThrowableDiagnostic({
diagnostic: {
message: `Cannot find module ${resolved.moduleName}`,
hints: alternativeModules.map(r => {
return `Did you mean __${r}__?`;
}),
},
});
}
}

@@ -247,2 +387,3 @@

env: Environment,
parentdir: string,
) {

@@ -253,7 +394,40 @@ // Find a package.json file in the current package.

// First try as a file, then as a directory.
return (
(await this.loadAsFile({file: filename, extensions, env, pkg})) ||
(await this.loadDirectory({dir: filename, extensions, env, pkg})) // eslint-disable-line no-return-await
);
let resolvedFile =
(await this.loadAsFile({
file: filename,
extensions,
env,
pkg,
})) ||
(await this.loadDirectory({
dir: filename,
extensions,
env,
pkg,
}));
if (!resolvedFile) {
// If we can't load the file do a fuzzySearch for potential hints
let relativeFileSpecifier = relatifyPath(parentdir, filename);
let potentialFiles = await this.findAlternativeFiles(
relativeFileSpecifier,
parentdir,
);
throw new ThrowableDiagnostic({
diagnostic: {
message: `Cannot load file '${relativeFileSpecifier}' in '${relatifyPath(
this.options.projectRoot,
parentdir,
)}'.`,
hints: potentialFiles.map(r => {
return `Did you mean __${r}__?`;
}),
},
});
}
return resolvedFile;
}
findBuiltin(filename: string, env: Environment) {

@@ -307,27 +481,23 @@ if (builtins[filename]) {

) {
try {
// If a module was specified as a module sub-path (e.g. some-module/some/path),
// it is likely a file. Try loading it as a file first.
if (module.subPath && module.moduleDir) {
let pkg = await this.readPackage(module.moduleDir);
let res = await this.loadAsFile({
file: nullthrows(module.filePath),
extensions,
env,
pkg,
});
if (res) {
return res;
}
}
// Otherwise, load as a directory.
return await this.loadDirectory({
dir: nullthrows(module.filePath),
// If a module was specified as a module sub-path (e.g. some-module/some/path),
// it is likely a file. Try loading it as a file first.
if (module.subPath && module.moduleDir) {
let pkg = await this.readPackage(module.moduleDir);
let res = await this.loadAsFile({
file: nullthrows(module.filePath),
extensions,
env,
pkg,
});
} catch (e) {
// ignore
if (res) {
return res;
}
}
// Otherwise, load as a directory.
return this.loadDirectory({
dir: nullthrows(module.filePath),
extensions,
env,
});
}

@@ -355,19 +525,66 @@

|}) {
let failedEntry;
try {
pkg = await this.readPackage(dir);
// Get a list of possible package entry points.
let entries = this.getPackageEntries(pkg, env);
if (pkg) {
// Get a list of possible package entry points.
let entries = this.getPackageEntries(pkg, env);
for (let file of entries) {
// First try loading package.main as a file, then try as a directory.
const res =
(await this.loadAsFile({file, extensions, env, pkg})) ||
(await this.loadDirectory({dir: file, extensions, env, pkg}));
if (res) {
return res;
for (let entry of entries) {
// First try loading package.main as a file, then try as a directory.
let res =
(await this.loadAsFile({
file: entry.filename,
extensions,
env,
pkg,
})) ||
(await this.loadDirectory({
dir: entry.filename,
extensions,
env,
pkg,
}));
if (res) {
return res;
} else {
failedEntry = entry;
throw new Error('');
}
}
}
} catch (err) {
// ignore
} catch (e) {
if (failedEntry && pkg) {
let fileSpecifier = relatifyPath(dir, failedEntry.filename);
let alternatives = await this.findAlternativeFiles(
fileSpecifier,
pkg.pkgdir,
);
let alternative = alternatives[0];
let pkgContent = await this.options.inputFS.readFile(
pkg.pkgfile,
'utf8',
);
throw new ThrowableDiagnostic({
diagnostic: {
message: `Could not load '${fileSpecifier}' from module '${pkg.name}' found in package.json#${failedEntry.field}`,
language: 'json',
filePath: pkg.pkgfile,
codeFrame: {
code: pkgContent,
codeHighlights: generateJSONCodeHighlights(pkgContent, [
{
key: `/${failedEntry.field}`,
type: 'value',
message: `'${fileSpecifier}' does not exist${alternative &&
`, did you mean '${alternative}'?`}'`,
},
]),
},
},
});
}
}

@@ -411,3 +628,9 @@

getPackageEntries(pkg: InternalPackageJSON, env: Environment): Array<string> {
getPackageEntries(
pkg: InternalPackageJSON,
env: Environment,
): Array<{|
filename: string,
field: string,
|}> {
return this.mainFields

@@ -419,22 +642,35 @@ .map(field => {

} else if (typeof pkg.browser === 'string') {
return pkg.browser;
return {field, filename: pkg.browser};
} else if (typeof pkg.browser === 'object' && pkg.browser[pkg.name]) {
return pkg.browser[pkg.name];
return {
field: `browser/${pkg.name}`,
filename: pkg.browser[pkg.name],
};
}
}
return pkg[field];
return {
field,
// $FlowFixMe
filename: pkg[field],
};
})
.filter(entry => typeof entry === 'string')
.map(main => {
// Default to index file if no main field find
if (!main || main === '.' || main === './') {
main = 'index';
.filter(
entry => entry && entry.filename && typeof entry.filename === 'string',
)
.map(entry => {
// This will never happen, it's just to help out flow?
if (!entry || typeof entry.filename !== 'string') {
throw new Error('Invalid package.json entry.');
}
if (typeof main !== 'string') {
throw new Error('invariant: expected string');
// Current dir refers to an index file
if (entry.filename === '.' || entry.filename === './') {
entry.filename = 'index';
}
return path.resolve(pkg.pkgdir, main);
return {
field: entry.field,
filename: path.resolve(pkg.pkgdir, entry.filename),
};
});

@@ -530,12 +766,4 @@ }

if (path.isAbsolute(filename)) {
filename = path.relative(dir, filename);
if (filename[0] !== '.') {
filename = './' + filename;
}
alias = await this.lookupAlias(
aliases,
filename.replace(/\\/g, '/'),
dir,
);
filename = relatifyPath(dir, filename);
alias = await this.lookupAlias(aliases, filename, dir);
} else {

@@ -542,0 +770,0 @@ // It is a node_module. First try the entire filename as a key.

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