Permalink
Cannot retrieve contributors at this time
234 lines (193 sloc)
6.71 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/eslint-module-utils/resolve.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
exports.__esModule = true; | |
const fs = require('fs'); | |
const Module = require('module'); | |
const path = require('path'); | |
const hashObject = require('./hash').hashObject; | |
const ModuleCache = require('./ModuleCache').default; | |
const pkgDir = require('./pkgDir').default; | |
const CASE_SENSITIVE_FS = !fs.existsSync(path.join(__dirname.toUpperCase(), 'reSOLVE.js')); | |
exports.CASE_SENSITIVE_FS = CASE_SENSITIVE_FS; | |
const ERROR_NAME = 'EslintPluginImportResolveError'; | |
const fileExistsCache = new ModuleCache(); | |
// Polyfill Node's `Module.createRequireFromPath` if not present (added in Node v10.12.0) | |
// Use `Module.createRequire` if available (added in Node v12.2.0) | |
const createRequire = Module.createRequire || Module.createRequireFromPath || function (filename) { | |
const mod = new Module(filename, null); | |
mod.filename = filename; | |
mod.paths = Module._nodeModulePaths(path.dirname(filename)); | |
mod._compile(`module.exports = require;`, filename); | |
return mod.exports; | |
}; | |
function tryRequire(target, sourceFile) { | |
let resolved; | |
try { | |
// Check if the target exists | |
if (sourceFile != null) { | |
try { | |
resolved = createRequire(path.resolve(sourceFile)).resolve(target); | |
} catch (e) { | |
resolved = require.resolve(target); | |
} | |
} else { | |
resolved = require.resolve(target); | |
} | |
} catch (e) { | |
// If the target does not exist then just return undefined | |
return undefined; | |
} | |
// If the target exists then return the loaded module | |
return require(resolved); | |
} | |
// https://stackoverflow.com/a/27382838 | |
exports.fileExistsWithCaseSync = function fileExistsWithCaseSync(filepath, cacheSettings, strict) { | |
// don't care if the FS is case-sensitive | |
if (CASE_SENSITIVE_FS) { return true; } | |
// null means it resolved to a builtin | |
if (filepath === null) { return true; } | |
if (filepath.toLowerCase() === process.cwd().toLowerCase() && !strict) { return true; } | |
const parsedPath = path.parse(filepath); | |
const dir = parsedPath.dir; | |
let result = fileExistsCache.get(filepath, cacheSettings); | |
if (result != null) { return result; } | |
// base case | |
if (dir === '' || parsedPath.root === filepath) { | |
result = true; | |
} else { | |
const filenames = fs.readdirSync(dir); | |
if (filenames.indexOf(parsedPath.base) === -1) { | |
result = false; | |
} else { | |
result = fileExistsWithCaseSync(dir, cacheSettings, strict); | |
} | |
} | |
fileExistsCache.set(filepath, result); | |
return result; | |
}; | |
function relative(modulePath, sourceFile, settings) { | |
return fullResolve(modulePath, sourceFile, settings).path; | |
} | |
let prevSettings = null; | |
let memoizedHash = ''; | |
function fullResolve(modulePath, sourceFile, settings) { | |
// check if this is a bonus core module | |
const coreSet = new Set(settings['import/core-modules']); | |
if (coreSet.has(modulePath)) { return { found: true, path: null }; } | |
const sourceDir = path.dirname(sourceFile); | |
if (prevSettings !== settings) { | |
memoizedHash = hashObject(settings).digest('hex'); | |
prevSettings = settings; | |
} | |
const cacheKey = sourceDir + memoizedHash + modulePath; | |
const cacheSettings = ModuleCache.getSettings(settings); | |
const cachedPath = fileExistsCache.get(cacheKey, cacheSettings); | |
if (cachedPath !== undefined) { return { found: true, path: cachedPath }; } | |
function cache(resolvedPath) { | |
fileExistsCache.set(cacheKey, resolvedPath); | |
} | |
function withResolver(resolver, config) { | |
if (resolver.interfaceVersion === 2) { | |
return resolver.resolve(modulePath, sourceFile, config); | |
} | |
try { | |
const resolved = resolver.resolveImport(modulePath, sourceFile, config); | |
if (resolved === undefined) { return { found: false }; } | |
return { found: true, path: resolved }; | |
} catch (err) { | |
return { found: false }; | |
} | |
} | |
const configResolvers = settings['import/resolver'] | |
|| { node: settings['import/resolve'] }; // backward compatibility | |
const resolvers = resolverReducer(configResolvers, new Map()); | |
for (const pair of resolvers) { | |
const name = pair[0]; | |
const config = pair[1]; | |
const resolver = requireResolver(name, sourceFile); | |
const resolved = withResolver(resolver, config); | |
if (!resolved.found) { continue; } | |
// else, counts | |
cache(resolved.path); | |
return resolved; | |
} | |
// failed | |
// cache(undefined) | |
return { found: false }; | |
} | |
exports.relative = relative; | |
function resolverReducer(resolvers, map) { | |
if (Array.isArray(resolvers)) { | |
resolvers.forEach((r) => resolverReducer(r, map)); | |
return map; | |
} | |
if (typeof resolvers === 'string') { | |
map.set(resolvers, null); | |
return map; | |
} | |
if (typeof resolvers === 'object') { | |
for (const key in resolvers) { | |
map.set(key, resolvers[key]); | |
} | |
return map; | |
} | |
const err = new Error('invalid resolver config'); | |
err.name = ERROR_NAME; | |
throw err; | |
} | |
function getBaseDir(sourceFile) { | |
return pkgDir(sourceFile) || process.cwd(); | |
} | |
function requireResolver(name, sourceFile) { | |
// Try to resolve package with conventional name | |
const resolver = tryRequire(`eslint-import-resolver-${name}`, sourceFile) | |
|| tryRequire(name, sourceFile) | |
|| tryRequire(path.resolve(getBaseDir(sourceFile), name)); | |
if (!resolver) { | |
const err = new Error(`unable to load resolver "${name}".`); | |
err.name = ERROR_NAME; | |
throw err; | |
} | |
if (!isResolverValid(resolver)) { | |
const err = new Error(`${name} with invalid interface loaded as resolver`); | |
err.name = ERROR_NAME; | |
throw err; | |
} | |
return resolver; | |
} | |
function isResolverValid(resolver) { | |
if (resolver.interfaceVersion === 2) { | |
return resolver.resolve && typeof resolver.resolve === 'function'; | |
} else { | |
return resolver.resolveImport && typeof resolver.resolveImport === 'function'; | |
} | |
} | |
const erroredContexts = new Set(); | |
/** | |
* Given | |
* @param {string} p - module path | |
* @param {object} context - ESLint context | |
* @return {string} - the full module filesystem path; | |
* null if package is core; | |
* undefined if not found | |
*/ | |
function resolve(p, context) { | |
try { | |
return relative(p, context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(), context.settings); | |
} catch (err) { | |
if (!erroredContexts.has(context)) { | |
// The `err.stack` string starts with `err.name` followed by colon and `err.message`. | |
// We're filtering out the default `err.name` because it adds little value to the message. | |
let errMessage = err.message; | |
if (err.name !== ERROR_NAME && err.stack) { | |
errMessage = err.stack.replace(/^Error: /, ''); | |
} | |
context.report({ | |
message: `Resolve error: ${errMessage}`, | |
loc: { line: 1, column: 0 }, | |
}); | |
erroredContexts.add(context); | |
} | |
} | |
} | |
resolve.relative = relative; | |
exports.default = resolve; |