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

arc-resolver

Package Overview
Dependencies
Maintainers
2
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

arc-resolver - npm Package Compare versions

Comparing version 1.0.1 to 2.0.0-alpha.0

README.md

299

index.js

@@ -1,183 +0,180 @@

var fs = require('fs');
var path = require('path');
var resolve = require('resolve');
var directoryListings = {};
var fileMatches = {};
var configs = {};
let path = require('path');
let util = require('util');
let parseFlags = require('arc-flag-parser').parse;
let flaggedPathRegex = /\[(.*)\]/;
module.exports.adaptResource = adaptResource;
module.exports.joinFlags = joinFlags;
module.exports.loadArcConfig = loadArcConfig;
module.exports.resolveFrom = resolveFrom;
module.exports.getFileMatches = getFileMatches;
module.exports.getBestMatch = getBestMatch;
function getIndexedFlags(flags) {
if (!Array.isArray(flags)) return flags; //assume indexed flagset
if (flags.indexedFlags) return flags.indexedFlags;
var indexedFlags = {};
for (var i = 0; i < flags.length; i++) {
indexedFlags[flags[i]] = true;
class Resolver {
constructor(fs = require('fs')) {
validateFS(fs);
this.fs = fs;
this.fs.stat = util.promisify(this.fs.stat);
this.fs.readdir = util.promisify(this.fs.readdir);
this.dirCache = {};
this.matchCache = {};
}
clearCache() {
this.dirCache = {};
this.matchCache = {};
}
getMatchesSync(filepath, path) {
if (typeof filepath !== 'string') {
throw new TypeError('Filepath must be a string.');
}
Object.defineProperty(flags, 'indexedFlags', { value: indexedFlags });
return indexedFlags;
}
let matches = this.matchCache[filepath];
function getDirectoryListing(dirname) {
if (directoryListings[dirname]) {
return directoryListings[dirname];
}
if (!matches) {
path = path || getPathHelper(filepath);
let parsed = path.parse(filepath);
if (parsed.root === filepath || flaggedPathRegex.test(parsed.base)) {
matches = [{ flags: [], value: filepath }];
} else {
let parentMatches = this.getMatchesSync(parsed.dir, path).raw;
matches = parentMatches.reduce(
(matches, parent) => {
let childMatches = this.getDirMatchesSync(
parent.value,
parsed.base,
path
);
if (parent.flags.length) {
childMatches = childMatches.map(child => ({
flags: Array.from(new Set(parent.flags.concat(child.flags))),
value: child.value
}));
}
matches.push.apply(matches, childMatches);
return matches;
},
[]
);
}
return directoryListings[dirname] = fs.readdirSync(dirname);
}
function loadArcConfig(filepath) {
if (configs[filepath]) {
return configs[filepath];
matches = this.matchCache[filepath] = new MatchSet(matches);
}
var content = fs.readFileSync(filepath, 'utf8');
var config = configs[filepath] = JSON.parse(content);
return matches;
}
getDirMatchesSync(dir, request, path) {
let fs = this.fs;
let cache = this.dirCache[dir];
return config;
}
if (!cache) {
let entries = fs.readdirSync(dir);
function getFileMatches(filepath, extensions) {
if (fileMatches[filepath]) {
return fileMatches[filepath];
}
cache = {};
var dirname = path.dirname(filepath);
var filename = path.basename(filepath);
var extStart = filename.lastIndexOf('.');
var basename = filename.slice(0, extStart);
var extension = filename.slice(extStart + 1);
var files = getDirectoryListing(dirname);
var isIndexAdaptive = filename === 'index.arc';
var matches = [];
var hasDefault = false;
var defaultName;
var config;
var pattern;
if (isIndexAdaptive) {
pattern = /([\w\d-]+(?:\.[\w\d-]+)*)/;
config = loadArcConfig(filepath);
defaultName = config && config.default || 'default';
} else {
pattern = new RegExp('^' + basename + '((?:\\.[\\w\\d-]+)*)' + '\\.' + extension + '$');
}
files.forEach(file => {
var match = pattern.exec(file);
entries.forEach(entryName => {
let entryPath = path.join(dir, entryName);
let match = flaggedPathRegex.exec(entryName);
if (match) {
var fullpath = path.join(dirname, file);
var stat = fs.statSync(fullpath);
var flags = match[1].split('.');
if (isIndexAdaptive) {
if (!stat.isDirectory()) return;
} else {
if (!stat.isFile()) return;
flags = flags.slice(1);
}
let canonicalName = entryName.replace(match[0], '');
let entryCache = (cache[canonicalName] = cache[canonicalName] || []);
let flagsets = parseFlags(match[1]);
flagsets.forEach(flags =>
entryCache.push({ flags, value: entryPath })
);
} else {
let entryCache = (cache[entryName] = cache[entryName] || []);
entryCache.push({ flags: [], value: entryPath });
}
});
if (file === defaultName) {
flags = [];
}
Object.values(cache).forEach(entryCache => {
entryCache.sort((a, b) => b.flags.length - a.flags.length);
});
hasDefault = hasDefault || !flags.length;
this.dirCache[dir] = cache;
}
matches.push({ file: fullpath, flags });
}
});
let matches = cache[request];
if (!hasDefault) {
throw new Error('No default found for ' + filepath);
if (!matches) {
throw new Error(path.resolve(dir, request) + ' does not exist');
}
return fileMatches[filepath] = matches;
}
return matches;
}
resolveSync(filepath, flags) {
if (typeof filepath !== 'string') {
throw new TypeError('Filepath must be a string.');
}
// Utility function to get directory matches
function getDirMatches(filepath) {
if (fileMatches[filepath]) {
return fileMatches[filepath];
if (!flags || typeof flags !== 'object') {
throw new TypeError('Flags must be an object.');
}
var parentDir = path.dirname(filepath);
var basename = path.basename(filepath);
var contents = getDirectoryListing(parentDir);
var matches = [];
return this.getMatchesSync(filepath).match(flags);
}
isAdaptiveSync(filepath) {
if (typeof filepath !== 'string') {
throw new TypeError('Filepath must be a string.');
}
contents.forEach(dir => {
var fullpath = path.join(parentDir, dir);
// We only want to operate on the directories
var stat = fs.statSync(fullpath);
if (!stat.isDirectory()) return;
return this.getMatchesSync(filepath).count > 1;
}
};
var flags = dir.split('.');
if (dir === basename) {
flags = [];
}
matches.push({ file: fullpath, flags });
});
return fileMatches[filepath] = matches;
function getPathHelper(filepath) {
if (path.posix.isAbsolute(filepath)) {
return path.posix;
} else if (path.win32.isAbsolute(filepath)) {
return path.win32;
} else {
throw new Error(
'Filepath must be a fully resolved filepath. Got: ' + filepath
);
}
}
function adaptResource(filepath, flags) {
var stat = fs.statSync(filepath);
var matches = [];
function validateFS(fs) {
if (!fs) {
throw new Error(
'You must pass a filesystem to resolve, or undefined to use the node fs module'
);
}
if (stat.isFile()) {
matches = getFileMatches(filepath);
} else if (stat.isDirectory()) {
matches = getDirMatches(filepath);
}
let missing = ['stat', 'statSync', 'readdir', 'readdirSync'].filter(
method => !fs[method]
);
return getBestMatch(matches, flags).file;
if (missing.length) {
throw new Error(
'The passed filesystem is missing the following methods: ' +
missing.join(', ') +
'.'
);
}
}
class MatchSet {
constructor(matches) {
this.raw = matches;
}
get default() {
return this.raw[this.raw.length-1].value;
}
get count() {
return this.raw.length
}
map(fn) {
return new MatchSet(this.raw.map(({ flags, value }, index) => ({
flags: flags,
value: fn(value, flags, index)
})));
}
match(flags) {
let match = this.raw.find(match => match.flags.every(flag => flags[flag]));
function resolveFrom(requestingFile, targetFile, options) {
var flags = options.flags;
var extensions = (options.extensions || []).concat('.arc');
var resolvedFile = resolve.sync(targetFile, {
basedir: path.dirname(requestingFile),
extensions: extensions || ['.js']
});
if (getFileMatches(resolvedFile).some(match => match.file === requestingFile)) {
return resolvedFile;
if (!match) {
throw new Error('No match found');
}
return adaptResource(resolvedFile, flags);
return match.value;
}
[Symbol.iterator]() {
return this.raw[Symbol.iterator]();
}
}
// Alphabetize flags before joining them
function joinFlags(flags) {
flags.sort();
return flags.join('.');
}
// Return best matching filepath
function getBestMatch(matches, flags) {
var indexedFlags = getIndexedFlags(flags);
var bestMatchObj = {};
var bestMatchFile = '';
matches.sort((a, b) => (
b.flags.length - a.flags.length
));
bestMatchObj = matches.find(match => {
return match.flags.every(flag => indexedFlags[flag]);
});
return bestMatchObj;
}
module.exports = Resolver;
module.exports.MatchSet = MatchSet;
{
"name": "arc-resolver",
"version": "1.0.1",
"version": "2.0.0-alpha.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha"
"test": "nyc mocha test.js"
},
"author": "Michael Rawlings <ml.rawlings@gmail.com>",
"license": "ISC",
"license": "MIT",
"dependencies": {
"resolve": "^1.1.7"
"arc-flag-parser": "^2.0.0-alpha.0",
"cachedfs": "^0.3.3"
},
"devDependencies": {
"chai": "^3.5.0",
"lerna": "^2.0.0-rc.5",
"mocha": "^3.2.0"
}
"memory-fs": "^0.4.1",
"mocha": "^3.2.0",
"nyc": "^11.3.0"
},
"gitHead": "4772d05c45bc1bfbc988b7ac97a96295b452c650"
}
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