babel-plugin-local-scoped-modules
Version:
babel-plugin-local-scoped-modules ================ This plugin intends to avoid typing relative paths.Use relative paths like local modules instead.
145 lines (144 loc) • 4.17 kB
JavaScript
import { existsSync as x } from "fs";
import { normalize as m, dirname as y, basename as v, relative as P, sep as c, join as L } from "path";
class R {
constructor() {
this.cachedMethodNames = [], this.visitor = {};
}
addMethod(t, r) {
let i = t;
t in this.cachedMethodNames || (this.cachedMethodNames.push(t), this.visitor[t] = (n, l) => r(n, l, i));
}
getVisitor() {
return this.cachedMethodNames.length === 0 ? {} : this.visitor;
}
}
const B = {
rootPrefix: "~",
scopePrefix: "@",
scopes: [],
calleeNames: ["require"]
}, O = "." + c;
function S(e) {
return e = m(e), x(e + ".js") || x(e + ".json") || v(e).indexOf(".") > -1 ? "file" : "dir";
}
function $(e, t, r = {}) {
e = m(e), t = m(t);
let i, n, l, o, { isDir: f } = r;
const u = S(e), h = f == !0 ? "dir" : S(t);
return i = e, u === "file" && (i = y(e)), n = t, h === "file" && (n = y(t), l = v(t)), o = P(i, n), n.endsWith(c) && (o += c), l && (o = L(o, l)), n.indexOf(i) > -1 && (o = O + o), o.endsWith("..") && (o += c), o;
}
var q = /[|\\{}()[\]^$+*?.-]/g;
const C = (e) => {
if (typeof e != "string")
throw new TypeError("Expected a string");
return e.replace(q, "\\$&");
}, I = { resolve: {}, eject: {} }, V = "__THE_ITEM_WAS_EJECTED__", { resolve: ee, eject: g } = I, k = (e) => {
e in g || (g[e] = V);
};
function z(e) {
let t = [];
return e.forEach((r, i) => {
let { name: n, alias: l, dir: o } = r;
t.push({ name: n, dir: o }), l && (Array.isArray(l) ? l.forEach((f) => t.push({ name: f, dir: o })) : t.push({ name: l, dir: o }));
}), t;
}
function E(e, t, r) {
const { cwd: i, filename: n } = t, { rootPrefix: l, scopePrefix: o } = r, f = e;
if (f in g)
return;
let u = z(r.scopes);
const h = { name: l, dir: i };
u.unshift(h);
let p = W(e);
if (!p) {
k(f);
return;
}
let N = j(), T = A(), w = p === l ? "" : T[p].slice(l.length), D = e.slice(p.length);
return (N + m(w + D)).replace(c + c, c);
function j() {
return $(n, i);
}
function W(s) {
if (!_(s))
return;
let a;
return u.some((M) => {
let d = M.name;
return s === d || s.startsWith(`${d}/`) && s.split(d).length === 2 ? (a = d, !0) : !1;
}), a;
}
function _(s) {
let a = new RegExp(`^${C(o)}[-_0-9A-z/]+`);
return s = l || s.startsWith(`${l}/`) && s.split(l).length === 2 || a.test(s) && s.split(o).length === 2;
}
function A() {
return u.reduce((s, a) => (s[a.name] = a.dir, s), {});
}
}
const F = (e) => {
for (; e.type === "BinaryExpression"; ) {
let t = e.left;
if (t.type === "BinaryExpression") {
e = e.left;
continue;
}
if (t.type === "StringLiteral" && e.operator === "+")
return t;
if (t.type === "TemplateLiteral" && e.operator === "+")
return t;
break;
}
}, H = (e) => (t, r) => {
if (e.type === "BinaryExpression" && (e = F(e)), e.type === "CallExpression" && (e = e.callee.object), !!e) {
if (e.type === "StringLiteral")
return J(e, t, r);
if (e.type === "TemplateLiteral")
return G(e, t, r);
}
}, J = (e, t, r) => {
let i = e.value, n = E(i, t, r);
n && (e.value = n);
}, G = (e, t, r) => {
e = e.quasis[0];
const { raw: i, cooked: n } = e.value;
let o = E(i, t, r);
o && (e.value = { raw: o, cooked: o });
};
function K(e, t, r) {
let i;
if (t === "CallExpression") {
Array.isArray(r.calleeNames) || (r.calleeNames = []), r.calleeNames.includes("require") || r.calleeNames.push("require");
let n = e.node.callee.name;
const { calleeNames: l } = r;
if (!l.includes(n) || !e.node.arguments.length)
return;
i = e.node.arguments[0];
}
return e.node.source && (i = e.node.source), i;
}
const Q = [
"CallExpression",
"ImportDeclaration",
"ExportNamedDeclaration",
"ExportAllDeclaration"
];
let U = Q.map((e) => ({
name: e,
fn: X
}));
function X(e, t, r) {
let i = { ...B, ...t.opts }, n = K(e, r, i);
if (n)
return H(n)(t, i);
}
function te({ types: e }) {
let t = new R();
return U.forEach((i) => {
let { name: n, fn: l } = i;
t.addMethod(n, l);
}), { visitor: t.getVisitor() };
}
export {
te as default
};