dependent-path-update
Version:
A tool to update dependent paths when renaming a file.
89 lines (68 loc) • 3.13 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = _default;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _fs = _interopRequireDefault(require("mz/fs"));
var _path = _interopRequireDefault(require("path"));
var _escapeStringRegexp = _interopRequireDefault(require("escape-string-regexp"));
var _getFiles = _interopRequireDefault(require("./get-files"));
var _getRelativeRequirePath = _interopRequireDefault(require("./get-relative-require-path"));
var _getPotentialPaths = _interopRequireDefault(require("./get-potential-paths"));
const GLOB_DEFAULTS = {
matchBase: true,
absolute: true,
nodir: true,
dot: false,
ignore: ["**/node_modules/**"]
};
async function _default({
from,
to,
exclude,
include = ["."],
projectDir = process.cwd()
}) {
const originalExtReg = `(${(0, _escapeStringRegexp.default)(_path.default.extname(from))})?`;
const originalPath = _path.default.resolve(projectDir, from);
const updatedExt = _path.default.extname(to);
const updatedPath = _path.default.resolve(projectDir, to);
const originalIsIndex = isIndexFile(originalPath);
const updatedIsIndex = isIndexFile(updatedPath);
const changedFiles = {};
const files = await (0, _getFiles.default)(include, (0, _objectSpread2.default)({}, GLOB_DEFAULTS, {
cwd: projectDir,
ignore: GLOB_DEFAULTS.ignore.concat(exclude || [])
}));
await Promise.all(files.map(async file => {
if (file === originalPath) {
return;
}
const relativePathToUpdated = (0, _getRelativeRequirePath.default)(_path.default.dirname(file), removeIndexAndExt(updatedPath));
const validPathsForFile = (0, _getPotentialPaths.default)(projectDir, file, removeIndexAndExt(originalPath)).map(_escapeStringRegexp.default);
if (validPathsForFile[0] === "\\.") {
validPathsForFile[0] += "\\/?";
}
const validPathsRegexp = new RegExp(`(["'])` + // Match a quote
`(.+?:\\s*)?` + // Followed by any characters + spaces (eg: "require: ./abc" for browser.json files)
`(?:${validPathsForFile.join("|")})` + // Followed by any valid relative path to the original file.
`(${originalIsIndex ? "\\/index" : ""}${originalExtReg})?` + // And optional index + extension
`\\1`, // Followed by the closing matching quote
"g");
const originalSource = changedFiles[file] || (await _fs.default.readFile(file, "utf8"));
const updatedSource = originalSource.replace(validPathsRegexp, (_, quote, prefix = "", foundIndex, foundExt) => {
foundIndex = foundIndex !== foundExt;
return quote + prefix + relativePathToUpdated + (foundIndex && updatedIsIndex ? "/index" : "") + ((!updatedIsIndex || foundIndex) && foundExt ? updatedExt : "") + quote;
});
if (originalSource !== updatedSource) {
changedFiles[file] = updatedSource;
}
}));
return changedFiles;
}
function removeIndexAndExt(str) {
return str.replace(/(?:\/index)?\..*$/, "");
}
function isIndexFile(str) {
return /\/index\..*$/.test(str);
}