
Security News
Anthropic Identifies Biased Reasoning and Recklessness as Drivers of Claude’s PyPI Attack
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.
bare-module-resolve
Advanced tools
Low-level module resolution algorithm for Bare. The algorithm is implemented as a generator function that yields either package manifests to be read or resolution candidates to be tested by the caller. As a convenience, the main export is a synchronous and asynchronous iterable that relies on package manifests being read by a callback. For asynchronous iteration, the callback may return promises which will be awaited before being passed to the generator.
npm i bare-module-resolve
For synchronous resolution:
const resolve = require('bare-module-resolve')
function readPackage(url) {
// Read and parse `url` if it exists, otherwise `null`
}
for (const resolution of resolve('./file.js', new URL('file:///directory/'), readPackage)) {
console.log(resolution)
}
For asynchronous resolution:
const resolve = require('bare-module-resolve')
async function readPackage(url) {
// Read and parse `url` if it exists, otherwise `null`
}
for await (const resolution of resolve('./file.js', new URL('file:///directory/'), readPackage)) {
console.log(resolution)
}
See the bare-module-resolve reference.
The following generator functions implement the resolution algorithm, which has been adapted from the Node.js resolution algorithms for CommonJS and ES modules. Unlike Node.js, Bare uses the same resolution algorithm for both module formats. The yielded values have the following shape:
Package manifest
next.value = {
package: URL
}
If the package manifest identified by next.value.package exists, generator.next() must be passed the parsed JSON value of the manifest. If it does not exist, pass null instead.
Resolution candidate
next.value = {
resolution: URL
}
If the module identified by next.value.resolution exists, generator.next() may be passed true to signal that the resolution for the current set of conditions has been identified. If it does not exist, pass false instead.
To drive the generator functions, a loop like the following can be used:
const generator = resolve.module(specifier, parentURL)
let next = generator.next()
while (next.done !== true) {
const value = next.value
if (value.package) {
// Read and parse `value.package` if it exists, otherwise `null`
let info
next = generator.next(info)
} else {
const resolution = value.resolution
// `true` if `resolution` was the correct candidate, otherwise `false`
let resolved
next = generator.next(resolved)
}
}
Options are the same as resolve() for all functions.
[!WARNING] These functions are currently subject to change between minor releases. If using them directly, make sure to specify a tilde range (
~1.2.3) when declaring the module dependency.
const generator = resolve.module(specifier, parentURL[, options])specifier starts with a Windows drive letter:
/ to specifier.options.resolutions is set:
preresolved(specifier, options.resolutions, parentURL, options) yields, return.url(specifier, parentURL, options) yields, return.packageImports(specifier, parentURL, options) yields, return.specifier equals . or .., or if specifier starts with /, \, ./, .\, ../, or ..\:
options.imports is set:
packageImportsExports(specifier, options.imports, parentURL, true, options) yields, return.deferred(specifier, options) yields, return.file(specifier, parentURL, false, options) resolves, return.directory(specifier, parentURL, options).package(specifier, parentURL, options).const generator = resolve.url(url, parentURL[, options])url is not a valid URL, return.options.imports is set:
packageImportsExports(url.href, options.imports, parentURL, true, options) yields, return.url.protocol equals options.deferredProtocol:
specifier be url.pathname.options.resolutions is set:
imports be options.resolutions[parentURL].imports is a non-null object:
imports[specifier] to null.module(specifier, parentURL, options).url.protocol equals node::
specifier be url.pathname.specifier equals . or .., or if specifier starts with /, \, ./, .\, ../, or ..\, throw.package(specifier, parentURL, options).url.const generator = resolve.preresolved(specifier, resolutions, parentURL[, options])imports be resolutions[parentURL].imports is a non-null object:
packageImportsExports(specifier, imports, parentURL, true, options).const generator = resolve.deferred(specifier[, options])options.defer includes specifier:
options.deferredProtocol concatenated with specifier and return.const generator = resolve.package(packageSpecifier, parentURL[, options])packageSpecifier is the empty string, throw.packageSpecifier does not start with @:
packageName to the substring of packageSpecifier until the first / or the end of the string.packageName be undefined.packageSpecifier does not include /, throw.packageName to the substring of packageSpecifier until the second / or the end of the string.packageName starts with . or includes \ or %, throw.builtinTarget(packageSpecifier, null, options.builtins, options) yields, return.deferred(packageSpecifier, options) yields, return.packageSubpath be . concatenated with the substring of packageSpecifier from the position at the length of packageName.packageSelf(packageName, packageSubpath, parentURL, options) yields, return.packageURL of lookupPackageRoot(packageName, parentURL, options):
info be the result of yielding packageURL.info is not null:
info.engines is set:
validateEngines(packageURL, info.engines, options).info.exports is set:
packageExports(packageURL, packageSubpath, info.exports, options).packageSubpath is .:
info.main is a non-empty string:
packageSubpath to info.main.file('index', packageURL, true, options).file(packageSubpath, packageURL, false, options) resolves, return.directory(packageSubpath, packageURL, options).const generator = resolve.packageSelf(packageName, packageSubpath, parentURL[, options])packageURL of lookupPackageScope(parentURL, options):
info be the result of yielding packageURL.info is not null:
info.name does not equal packageName, return.info.exports is set:
packageExports(packageURL, packageSubpath, info.exports, options).packageSubpath is .:
info.main is a non-empty string:
packageSubpath to info.main.file('index', packageURL, true, options).file(packageSubpath, packageURL, false, options) resolves, return.directory(packageSubpath, packageURL, options).const generator = resolve.packageExports(packageURL, subpath, exports[, options])exports is a non-null, non-array object whose keys are a mix of ones that start with . and ones that don't, throw.subpath is .:
mainExport be undefined.exports is a string or an array:
mainExport to exports.exports is a non-null object:
exports start with .:
. is a key of exports:
mainExport to exports['.'].mainExport to exports.mainExport is not undefined:
packageTarget(packageURL, mainExport, null, false, options) yields, return.exports is a non-null object:
exports starts with .:
packageImportsExports(subpath, exports, packageURL, false, options) yields, return.const generator = resolve.packageImports(specifier, parentURL[, options])specifier is # or starts with #/, throw.packageURL of lookupPackageScope(parentURL, options):
info be the result of yielding packageURL.info is not null:
info.imports is set:
packageImportsExports(specifier, info.imports, packageURL, true, options) yields, return.#, throw.options.imports is set:
packageImportsExports(url.href, options.imports, parentURL, true, options) yields, return.const generator = resolve.packageImportsExports(matchKey, matchObject, packageURL, isImports[, options])matchKey is a key of matchObject and matchKey does not include *:
target be matchObject[matchKey].packageTarget(packageURL, target, null, isImports, options).expansionKeys be the keys of matchObject that include * sorted by patternKeyCompare.expansionKey of expansionKeys:
patternBase be the substring of expansionKey until the first *.matchKey starts with but isn't equal to patternBase:
patternTrailer be the substring of expansionKey from the position at the index after the first *.patternTrailer is the empty string, or if matchKey ends with patternTrailer and the length of matchKey is greater than or equal to the length of expansionKey:
target be matchObject[expansionKey].patternMatch be the substring of matchKey from the position at the length of patternBase until the length of matchKey minus the length of patternTrailer.packageTarget(packageURL, target, patternMatch, isImports, options).const generator = resolve.packageTarget(packageURL, target, patternMatch, isImports[, options])target is a string:
target does not start with ./ and isImports is false, throw.patternMatch is not null:
* in target with patternMatch.options.matchedTargets includes target, return, having detected a resolution cycle.target to options.matchedTargets for the remainder of these steps, removing it again before returning.url(target, packageURL, options) yields, return.target equals . or .., or if target starts with /, ./, or ../:
packageURL has an opaque path, return.target relative to packageURL and return.package(target, packageURL, options).target is an array:
targetValue of target:
packageTarget(packageURL, targetValue, patternMatch, isImports, options) resolves, return.target is a non-null object:
condition of target:
condition equals default or if options.conditions includes condition:
targetValue be target[condition].condition to options.matchedConditions.status be the result of packageTarget(packageURL, targetValue, patternMatch, isImports, options).condition from options.matchedConditions.status.const generator = resolve.builtinTarget(packageSpecifier, packageVersion, target[, options])target is a string:
target does not start with @:
targetName be the substring of target until the first @ or the end of the string.targetVersion be the substring of target from the character following the first @ and to the end of string, or null if no such substring exists.targetName be the substring of target until the second @ or the end of the string.targetVersion be the substring of target from the character following the second @ and to the end of string, or null if no such substring exists.packageSpecifier equals targetName:
packageVersion is null and targetVersion is null:
options.builtinProtocol concatenated with packageSpecifier and return.version be null.packageVersion is null, let version be targetVersion.targetVersion is either null or equals packageVersion, let version be packageVersionversion is not null:
options.builtinProtocol concatenated with packageSpecifier, @, and version and return.target is an array:
targetValue of target:
builtinTarget(packageSpecifier, packageVersion, targetValue, options) resolves, return.target is a non-null object:
condition of target:
condition equals default or if options.conditions includes condition:
targetValue be target[condition].condition to options.matchedConditions.status be the result of builtinTarget(packageSpecifier, packageVersion, targetValue, options).condition from options.matchedConditions.status.const generator = resolve.file(filename, parentURL, isIndex[, options])filename equals . or .., or if filename ends with / or \, return.parentURL has an opaque path, return.parentURL is a file: URL and filename includes encoded / or \, throw.isIndex is false:
filename relative to parentURL.ext of options.extensions:
filename ends with ext, continue.filename concatenated with ext relative to parentURL.const generator = resolve.directory(dirname, parentURL[, options])parentURL has an opaque path, return.directoryURL be undefined.dirname ends with / or \:
directoryURL to the resolution of dirname relative to parentURL.directoryURL to the resolution of dirname concatenated with / relative to parentURL.options.directories is true:
directoryURL.info be the result of yielding the resolution of package.json relative to directoryURL.info is not null:
info.exports is set:
packageExports(directoryURL, '.', info.exports, options).info.main is a non-empty string:
file(info.main, directoryURL, false, options) resolves, return.directory(info.main, directoryURL, options).file('index', directoryURL, true, options).Apache-2.0
FAQs
Low-level module resolution algorithm for Bare
The npm package bare-module-resolve receives a total of 119,450 weekly downloads. As such, bare-module-resolve popularity was classified as popular.
We found that bare-module-resolve demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.

Research
/Security News
Malicious Chrome and Firefox extensions target Axiom Trade and Padre users, stealing session tokens and wallet data.

Security News
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.