73 lines
2.0 KiB
JavaScript
73 lines
2.0 KiB
JavaScript
const {resolve: resolvePath} = require('path');
|
|
|
|
const D = require('./debug');
|
|
|
|
const debug = D('@flecks/core/build/resolve');
|
|
|
|
module.exports = function resolve({alias, fallback}, stubs) {
|
|
debug('installing resolution magic');
|
|
const {Module} = require('module');
|
|
// eslint-disable-next-line no-underscore-dangle
|
|
Module._initPaths();
|
|
const {require: Mr} = Module.prototype;
|
|
function preprocessMatchers(matchers) {
|
|
return Object.entries(matchers)
|
|
.map(([from, to]) => {
|
|
if (false === to) {
|
|
stubs.push(from);
|
|
return undefined;
|
|
}
|
|
if (from.endsWith('$')) {
|
|
return {
|
|
exact: true,
|
|
from: from.slice(0, -1),
|
|
to,
|
|
};
|
|
}
|
|
return {
|
|
exact: false,
|
|
from,
|
|
to,
|
|
};
|
|
})
|
|
.filter((entry) => entry);
|
|
}
|
|
function match(path, request, matchers) {
|
|
for (let i = 0; i < matchers.length; ++i) {
|
|
const {exact, from, to} = matchers[i];
|
|
const resolvedFrom = resolvePath(path, from);
|
|
const resolvedTo = resolvePath(path, to);
|
|
if (exact) {
|
|
if (resolvedFrom === request) {
|
|
return request.replace(resolvedFrom, resolvedTo);
|
|
}
|
|
}
|
|
else if (request.startsWith(resolvedFrom)) {
|
|
return request.replace(resolvedFrom, resolvedTo);
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
const aliases = preprocessMatchers(alias, stubs);
|
|
const fallbacks = preprocessMatchers(fallback, stubs);
|
|
Module.prototype.require = function flecksResolutionMagic(request, options) {
|
|
for (let i = 0; i < stubs.length; ++i) {
|
|
if (request.startsWith(stubs[i])) {
|
|
return undefined;
|
|
}
|
|
}
|
|
const qualified = resolvePath(this.path, request);
|
|
let resolved = match(this.path, qualified, aliases);
|
|
if (!resolved) {
|
|
resolved = match(this.path, qualified, fallbacks);
|
|
}
|
|
if (!resolved) {
|
|
resolved = request;
|
|
}
|
|
return Mr.call(this, resolved, options);
|
|
};
|
|
return () => {
|
|
Module.prototype.require = Mr;
|
|
};
|
|
};
|