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

js-refactor

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-refactor - npm Package Compare versions

Comparing version 1.0.4 to 1.0.5

180

dist/index.js

@@ -20,26 +20,40 @@ #! /usr/bin/env node

const srcRoot = process.cwd();
const args = process.argv;
const subdirOld = args[2];
const subdirNew = args[3];
const srcRoot = process.cwd();
const fromFile = (0, _utils.toAbsolute)(args[2], srcRoot);
const toFile = (0, _utils.toAbsolute)(args[3], srcRoot);
function help() {
console.error('Usage: js-refactor <from-directory> <to-directory>');
}
if (_fs2.default.existsSync(subdirNew)) {
const stat = _fs2.default.statSync(fromFile);
if (!stat) {
help();
throw new Error(`subdirNew exists: ${subdirNew}`);
throw new Error(`fromFile does not exists: ${fromFile}`);
}
if (!_fs2.default.existsSync(subdirOld)) {
if (_fs2.default.existsSync(toFile)) {
help();
throw new Error(`subdirOld does not exists: ${subdirOld}`);
throw new Error(`toFile already exists: ${toFile}`);
}
_fs2.default.renameSync(subdirOld, subdirNew);
_fs2.default.renameSync(fromFile, toFile);
const MATCH_REQUIRE = /require\(['"](.+?)['"]\)/g;
const MATCH_IMPORT = /import .+? from ['"](.+?)['"]/g;
const isDirectory = stat.isDirectory(fromFile);
const subdirOld = isDirectory && fromFile;
const subdirNew = isDirectory && toFile;
function help() {
console.error('Usage: js-refactor <from-file> <to-file>');
}
const MATCH_REQUIRE = /require\s*\(\s*['"]([\s\S]+?)['"]\s*\)/g;
const MATCH_IMPORT = /import[\s\S]+?from\s*['"](.+?)['"]/g;
const MATCH_EXPORT = /export[\s\S]+?from\s*['"](.+?)['"]/g;
const IGNORE_DIR = /\/node_modules\/?$/;
const SELECT_SOURCE_FILE = /\.js$/;
function addSuffix(dep) {
return dep + '.js';
}
function trimSuffix(dep) {
return dep.replace(/\.js$/, '');
}
function shouldFix(file) {

@@ -83,16 +97,49 @@ return (/^src\/|^\.\/|^\.\.\//.test(file)

// fix files within subdir
console.log('processing internal files\n\n');
iterateSourceFiles(subdirNew, { excludes: [IGNORE_DIR] }, ({ file }) => {
const dir = _path2.default.dirname(file);
const wouldBePath = _path2.default.join(subdirOld, _path2.default.relative(subdirNew, file));
const wouldBeDir = _path2.default.dirname(wouldBePath);
const fileContent = _fs2.default.readFileSync(file, { encoding: 'utf8' });
const lines = fileContent.split('\n');
function fixOnlyFile() {
console.log('fix only file\n\n');
let fileContent = _fs2.default.readFileSync(toFile, { encoding: 'utf8' });
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach(re => {
re.lastIndex = 0;
let m;
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];
// 其他模块/文件/包,忽略
if (!shouldFix(dep)) {
continue;
}
const isRela = (0, _utils.isRelative)(dep);
if (!isRela) {
continue;
}
const dirOld = _path2.default.dirname(fromFile);
const dirNew = _path2.default.dirname(toFile);
if ((0, _utils.isSameFile)(dirOld, dirNew)) {
return;
}
const realDep = _path2.default.join(dirOld, dep);
const newDep = _path2.default.relative(dirNew, realDep);
if (isRela && !(0, _utils.isRelative)(newDep)) {
newDep = './' + newDep;
}
lines.forEach((line, ii) => {
[MATCH_IMPORT, MATCH_REQUIRE].forEach(re => {
console.log('update file: %s\n %s\n->%s\n', toFile, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
_fs2.default.writeFileSync(toFile, fileContent);
}
function fixFilesDependingOnOnlyFile() {
console.log('fix files depending on only file\n\n');
iterateSourceFiles(srcRoot, { excludes: [IGNORE_DIR] }, ({ file }) => {
if ((0, _utils.isSameFile)(file, toFile)) {
return;
}
const dir = _path2.default.dirname(file);
let fileContent = _fs2.default.readFileSync(file, { encoding: 'utf8' });
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach(re => {
re.lastIndex = 0;
let m;
while ((m = re.exec(line)) !== null) {
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];

@@ -104,2 +151,40 @@ // 其他模块/文件/包,忽略

const isRela = (0, _utils.isRelative)(dep);
const realDep = _path2.default.join(dir, dep);
if (!(0, _utils.isSameFile)(addSuffix(realDep), fromFile)) {
continue;
}
if (/WebView/.test(dep)) {
console.log('realDep, toFile, isRela, dep', realDep, toFile, isRela, dep);
}
const newDep = _path2.default.relative(dir, trimSuffix(toFile));
if (isRela && !(0, _utils.isRelative)(newDep)) {
newDep = './' + newDep;
}
console.log('update file: %s\n %s\n->%s\n', file, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
_fs2.default.writeFileSync(file, fileContent);
});
}
// fix files within subdir
function fixFilesInSubdir() {
console.log('processing internal files\n\n');
iterateSourceFiles(subdirNew, { excludes: [IGNORE_DIR] }, ({ file }) => {
const dir = _path2.default.dirname(file);
const wouldBePath = _path2.default.join(subdirOld, _path2.default.relative(subdirNew, file));
const wouldBeDir = _path2.default.dirname(wouldBePath);
let fileContent = _fs2.default.readFileSync(file, { encoding: 'utf8' });
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach(re => {
re.lastIndex = 0;
let m;
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];
// 其他模块/文件/包,忽略
if (!shouldFix(dep)) {
continue;
}
const isRela = (0, _utils.isRelative)(dep);
const wouldBeDep = isRelativeToSrcRoot(dep) ? _path2.default.join(srcRoot, dep) : _path2.default.join(wouldBeDir, dep);

@@ -117,24 +202,23 @@ const isInnerFile = (0, _utils.isSuperDir)(subdirOld, wouldBeDep);

const newline = line.substr(0, m.index) + line.substr(m.index).replace(dep, newDep);
console.log('update file: %s\n %s\n->%s\n', file, line, newline);
lines[ii] = newline;
console.log('update file: %s\n %s\n->%s\n', file, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
_fs2.default.writeFileSync(file, fileContent);
});
_fs2.default.writeFileSync(file, lines.join('\n'));
});
}
// fix files outside subdir
console.log('processing external files\n\n');
iterateSourceFiles(srcRoot, { excludes: [d => (0, _utils.isSuperDir)(subdirNew, d), IGNORE_DIR] }, ({ file }) => {
function fixFilesOutsideSubdir() {
console.log('processing external files\n\n');
iterateSourceFiles(srcRoot, { excludes: [d => (0, _utils.isSuperDir)(subdirNew, d), IGNORE_DIR] }, ({ file }) => {
const dir = _path2.default.dirname(file);
const fileContent = _fs2.default.readFileSync(file, { encoding: 'utf8' });
const lines = fileContent.split('\n');
const dir = _path2.default.dirname(file);
let fileContent = _fs2.default.readFileSync(file, { encoding: 'utf8' });
lines.forEach((line, ii) => {
[MATCH_IMPORT, MATCH_REQUIRE].forEach(re => {
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach(re => {
re.lastIndex = 0;
let m;
while ((m = re.exec(line)) !== null) {
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];

@@ -147,3 +231,3 @@ // 其他模块/文件/包,忽略

const oldDepPath = isRelativeToSrcRoot(dep) ? _path2.default.join(srcRoot, dep) : _path2.default.join(dir, dep);
const isAffected = (0, _utils.isSuperDir)(_path2.default.join(srcRoot, subdirOld), oldDepPath);
const isAffected = (0, _utils.isSuperDir)(subdirOld, oldDepPath);
if (!isAffected) {

@@ -157,9 +241,17 @@ continue;

}
const newline = line.substr(0, m.index) + line.substr(m.index).replace(dep, newDep);
console.log('update file: %s\n %s\n->%s\n', file, line, newline);
lines[ii] = newline;
console.log('update file: %s\n %s\n->%s\n', file, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
_fs2.default.writeFileSync(file, fileContent);
});
_fs2.default.writeFileSync(file, lines.join('\n'));
});
}
if (isDirectory) {
fixFilesInSubdir();
fixFilesOutsideSubdir();
} else {
fixOnlyFile();
fixFilesDependingOnOnlyFile();
}

@@ -8,2 +8,4 @@ 'use strict';

exports.isSuperDir = isSuperDir;
exports.toAbsolute = toAbsolute;
exports.isSameFile = isSameFile;

@@ -35,2 +37,13 @@ var _path = require('path');

return addTrailingSlash(childDir).startsWith(addTrailingSlash(superDir));
}
function toAbsolute(f, b) {
if (_path2.default.isAbsolute(f)) {
return f;
}
return _path2.default.join(b, f);
}
function isSameFile(f1, f2) {
return _path2.default.normalize(f1) === _path2.default.normalize(f2);
}
{
"name": "js-refactor",
"version": "1.0.4",
"version": "1.0.5",
"description": "mv file/directory around keeping require and import statements in sync",

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -5,29 +5,46 @@ #! /usr/bin/env node

import traverser from 'directory-traverser';
import { isRelative, isSuperDir } from './utils';
import { isRelative, isSuperDir, toAbsolute, isSameFile } from './utils';
const srcRoot = process.cwd();
const args = process.argv;
const subdirOld = args[2];
const subdirNew = args[3];
const srcRoot = process.cwd();
const fromFile = toAbsolute(args[2], srcRoot);
const toFile = toAbsolute(args[3], srcRoot);
function help() {
console.error('Usage: js-refactor <from-directory> <to-directory>');
}
if (fs.existsSync(subdirNew)) {
const stat = fs.statSync(fromFile);
if (!stat) {
help();
throw new Error(`subdirNew exists: ${subdirNew}`);
throw new Error(`fromFile does not exists: ${fromFile}`);
}
if (!fs.existsSync(subdirOld)) {
if (fs.existsSync(toFile)) {
help();
throw new Error(`subdirOld does not exists: ${subdirOld}`);
throw new Error(`toFile already exists: ${toFile}`);
}
fs.renameSync(subdirOld, subdirNew);
fs.renameSync(fromFile, toFile);
const isDirectory = stat.isDirectory(fromFile);
const subdirOld = isDirectory && fromFile;
const subdirNew = isDirectory && toFile;
const MATCH_REQUIRE = /require\(['"](.+?)['"]\)/g;
const MATCH_IMPORT = /import .+? from ['"](.+?)['"]/g;
function help() {
console.error('Usage: js-refactor <from-file> <to-file>');
}
const MATCH_REQUIRE = /require\s*\(\s*['"]([\s\S]+?)['"]\s*\)/g;
const MATCH_IMPORT = /import[\s\S]+?from\s*['"](.+?)['"]/g;
const MATCH_EXPORT = /export[\s\S]+?from\s*['"](.+?)['"]/g;
const IGNORE_DIR = /\/node_modules\/?$/;
const SELECT_SOURCE_FILE = /\.js$/;
function addSuffix(dep) {
return dep + '.js';
}
function trimSuffix(dep) {
return dep.replace(/\.js$/, '');
}
function shouldFix(file) {

@@ -69,16 +86,53 @@ return /^src\/|^\.\/|^\.\.\//.test(file);

// fix files within subdir
console.log('processing internal files\n\n');
iterateSourceFiles(subdirNew, { excludes: [IGNORE_DIR] }, ({ file }) => {
const dir = path.dirname(file);
const wouldBePath = path.join(subdirOld, path.relative(subdirNew, file));
const wouldBeDir = path.dirname(wouldBePath);
const fileContent = fs.readFileSync(file, { encoding: 'utf8' });
const lines = fileContent.split('\n');
lines.forEach((line, ii) => {
[MATCH_IMPORT, MATCH_REQUIRE].forEach((re) => {
function fixOnlyFile() {
console.log('fix only file\n\n');
let fileContent = fs.readFileSync(toFile, { encoding: 'utf8' });
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach((re) => {
re.lastIndex = 0;
let m;
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];
// 其他模块/文件/包,忽略
if (!shouldFix(dep)) {
continue;
}
const isRela = isRelative(dep);
if (!isRela) {
continue;
}
const dirOld = path.dirname(fromFile);
const dirNew = path.dirname(toFile);
if (isSameFile(dirOld, dirNew)) {
return;
}
const realDep = path.join(dirOld, dep);
const newDep = path.relative(dirNew, realDep);
if (isRela && !isRelative(newDep)) {
newDep = './' + newDep;
}
console.log('update file: %s\n %s\n->%s\n', toFile, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
fs.writeFileSync(toFile, fileContent);
}
function fixFilesDependingOnOnlyFile() {
console.log('fix files depending on only file\n\n');
iterateSourceFiles(srcRoot,
{ excludes: [IGNORE_DIR] },
({ file }) => {
if (isSameFile(file, toFile)) {
return;
}
const dir = path.dirname(file);
let fileContent = fs.readFileSync(file, { encoding: 'utf8' });
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach((re) => {
re.lastIndex = 0;
let m;
while ((m = re.exec(line)) !== null) {
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];

@@ -90,2 +144,38 @@ // 其他模块/文件/包,忽略

const isRela = isRelative(dep);
const realDep = path.join(dir, dep);
if (!isSameFile(addSuffix(realDep), fromFile)) {
continue;
}
const newDep = path.relative(dir, trimSuffix(toFile));
if (isRela && !isRelative(newDep)) {
newDep = './' + newDep;
}
console.log('update file: %s\n %s\n->%s\n', file, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
fs.writeFileSync(file, fileContent);
});
}
// fix files within subdir
function fixFilesInSubdir() {
console.log('processing internal files\n\n');
iterateSourceFiles(subdirNew, { excludes: [IGNORE_DIR] }, ({ file }) => {
const dir = path.dirname(file);
const wouldBePath = path.join(subdirOld, path.relative(subdirNew, file));
const wouldBeDir = path.dirname(wouldBePath);
let fileContent = fs.readFileSync(file, { encoding: 'utf8' });
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach((re) => {
re.lastIndex = 0;
let m;
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];
// 其他模块/文件/包,忽略
if (!shouldFix(dep)) {
continue;
}
const isRela = isRelative(dep);
const wouldBeDep = isRelativeToSrcRoot(dep) ?

@@ -106,27 +196,26 @@ path.join(srcRoot, dep) : path.join(wouldBeDir, dep);

const newline = line.substr(0, m.index) + line.substr(m.index).replace(dep, newDep);
console.log('update file: %s\n %s\n->%s\n', file, line, newline);
lines[ii] = newline;
console.log('update file: %s\n %s\n->%s\n', file, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
fs.writeFileSync(file, fileContent);
});
fs.writeFileSync(file, lines.join('\n'));
});
}
// fix files outside subdir
console.log('processing external files\n\n');
iterateSourceFiles(srcRoot,
{ excludes: [d => isSuperDir(subdirNew, d), IGNORE_DIR] },
({ file }) => {
function fixFilesOutsideSubdir() {
console.log('processing external files\n\n');
iterateSourceFiles(srcRoot,
{ excludes: [d => isSuperDir(subdirNew, d), IGNORE_DIR] },
({ file }) => {
const dir = path.dirname(file);
const fileContent = fs.readFileSync(file, { encoding: 'utf8' });
const lines = fileContent.split('\n');
const dir = path.dirname(file);
let fileContent = fs.readFileSync(file, { encoding: 'utf8' });
lines.forEach((line, ii) => {
[MATCH_IMPORT, MATCH_REQUIRE].forEach((re) => {
[MATCH_IMPORT, MATCH_REQUIRE, MATCH_EXPORT].forEach((re) => {
re.lastIndex = 0;
let m;
while ((m = re.exec(line)) !== null) {
while ((m = re.exec(fileContent)) !== null) {
const dep = m[1];

@@ -140,3 +229,3 @@ // 其他模块/文件/包,忽略

path.join(srcRoot, dep) : path.join(dir, dep);
const isAffected = isSuperDir(path.join(srcRoot, subdirOld), oldDepPath);
const isAffected = isSuperDir(subdirOld, oldDepPath);
if (!isAffected) {

@@ -151,10 +240,17 @@ continue;

}
const newline = line.substr(0, m.index) +
line.substr(m.index).replace(dep, newDep);
console.log('update file: %s\n %s\n->%s\n', file, line, newline);
lines[ii] = newline;
console.log('update file: %s\n %s\n->%s\n', file, dep, newDep);
fileContent = fileContent.substr(0, m.index) + fileContent.substr(m.index).replace(dep, newDep);
re.lastIndex += newDep.length - dep.length;
}
});
fs.writeFileSync(file, fileContent);
});
fs.writeFileSync(file, lines.join('\n'));
});
}
if (isDirectory) {
fixFilesInSubdir();
fixFilesOutsideSubdir();
} else {
fixOnlyFile();
fixFilesDependingOnOnlyFile();
}

@@ -20,1 +20,12 @@ import path from 'path';

}
export function toAbsolute(f, b) {
if (path.isAbsolute(f)) {
return f;
}
return path.join(b, f);
}
export function isSameFile(f1, f2) {
return path.normalize(f1) === path.normalize(f2);
}
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