custompatch
Advanced tools
+64
-61
@@ -7,3 +7,4 @@ #!/usr/bin/env node | ||
| const diff = require('diff'); | ||
| const version = require('./package.json').version; | ||
| const { program } = require('commander'); | ||
| const ownPkg = require('./package.json'); | ||
| const npmFolder = path.join(npmDir(),'node_modules','npm','node_modules'); | ||
@@ -60,3 +61,16 @@ | ||
| echo(startColor('whiteBright') + 'CustomPatch' + stopColor() + ' version ' + startColor('greenBright') + version + stopColor() + '\n'); | ||
| const patchFiles = []; | ||
| const asyncResults = []; | ||
| program | ||
| .name('custompatch') | ||
| .usage('[options] [packageName ...]') | ||
| .version(ownPkg.version) | ||
| .description('Tool for patching buggy NPM packages instead of forking them.\nWhen invoked without arguments - apply all patches from the "patches" folder.\nIf one or more package names are specified - create a patch for the given NPM package (already patched by you in your "node_modules" folder) and save it inside "patches" folder.') | ||
| .option('-a, --all', 'Include "package.json" files in the patch, by default these are ignored'); | ||
| program.parse(); | ||
| const programOptions = program.opts(); | ||
| if(!programOptions.version) echo(startColor('whiteBright') + 'CustomPatch' + stopColor() + ' version ' + startColor('greenBright') + ownPkg.version + stopColor() + '\n'); | ||
| if(!fs.existsSync(path.join(curDir, '/node_modules'))) | ||
@@ -68,17 +82,6 @@ { | ||
| process.argv.shift(); // remove Node/NPX | ||
| process.argv.shift(); // remove this script | ||
| const len = process.argv.length; | ||
| const patchFiles = []; | ||
| const asyncResults = []; | ||
| if(len > 0) | ||
| if(program.args.length > 0) | ||
| { | ||
| // create patches | ||
| if(!fs.existsSync(patchDir)) fs.mkdirSync(patchDir); | ||
| for(let i = 0; i < len; i++) | ||
| { | ||
| makePatch(process.argv[i]); | ||
| } | ||
| // create patch for each of the provided package names | ||
| program.args.forEach(makePatch); | ||
| } | ||
@@ -279,36 +282,36 @@ else | ||
| let newStr = fs.readFileSync(newFile, 'utf8'); | ||
| if(pathname === 'package.json') return; // skip "package.json" - comparison is not reliable because NPM reorders keys and also appends many system keys (whose names begin with underscore) | ||
| if(pathname === 'package.json' && !programOptions.all) return; // skip "package.json" - comparison is not reliable because NPM reorders keys and also appends many system keys (whose names begin with underscore) | ||
| /* | ||
| { | ||
| let oldJson = {}, newJson = {}; | ||
| try | ||
| { | ||
| oldJson = JSON.parse(oldStr); | ||
| newJson = JSON.parse(newStr); | ||
| } | ||
| catch(e) | ||
| { | ||
| echo(startColor('redBright') + 'ERROR: ' + stopColor() + 'Could not parse ' + startColor('green') + 'package.json' + stopColor() + ' = ' + startColor('redBright') + e.message + stopColor()); | ||
| return; | ||
| } | ||
| // remove all keys which start with underscore | ||
| let key; | ||
| for(key in oldJson) | ||
| if(key[0] === '_') delete oldJson[key]; | ||
| for(key in newJson) | ||
| if(key[0] === '_') delete newJson[key]; | ||
| // sort the keys | ||
| let oldSorted = {}, newSorted = {}; | ||
| Object.keys(oldJson).sort().forEach(function(key) | ||
| { | ||
| oldSorted[key] = oldJson[key]; | ||
| }); | ||
| Object.keys(newJson).sort().forEach(function(key) | ||
| { | ||
| newSorted[key] = newJson[key]; | ||
| }); | ||
| oldStr = JSON.stringify(oldSorted, null, 2); | ||
| newStr = JSON.stringify(newSorted, null, 2); | ||
| } | ||
| */ | ||
| { | ||
| let oldJson = {}, newJson = {}; | ||
| try | ||
| { | ||
| oldJson = JSON.parse(oldStr); | ||
| newJson = JSON.parse(newStr); | ||
| } | ||
| catch(e) | ||
| { | ||
| echo(startColor('redBright') + 'ERROR: ' + stopColor() + 'Could not parse ' + startColor('green') + 'package.json' + stopColor() + ' = ' + startColor('redBright') + e.message + stopColor()); | ||
| return; | ||
| } | ||
| // remove all keys which start with underscore | ||
| let key; | ||
| for(key in oldJson) | ||
| if(key[0] === '_') delete oldJson[key]; | ||
| for(key in newJson) | ||
| if(key[0] === '_') delete newJson[key]; | ||
| // sort the keys | ||
| let oldSorted = {}, newSorted = {}; | ||
| Object.keys(oldJson).sort().forEach(function(key) | ||
| { | ||
| oldSorted[key] = oldJson[key]; | ||
| }); | ||
| Object.keys(newJson).sort().forEach(function(key) | ||
| { | ||
| newSorted[key] = newJson[key]; | ||
| }); | ||
| oldStr = JSON.stringify(oldSorted, null, 2); | ||
| newStr = JSON.stringify(newSorted, null, 2); | ||
| } | ||
| */ | ||
| if(oldStr !== newStr) patch.write(diff.createTwoFilesPatch(oldFile.replace(tmpDir,''), newFile.replace(path.join(curDir, 'node_modules'),''), oldStr, newStr)); | ||
@@ -369,14 +372,14 @@ } | ||
| /* | ||
| info = | ||
| { | ||
| index: '\vue2-dragula\dist\vue-dragula.js', | ||
| oldFileName: '\vue2-dragula\dist\vue-dragula.js', | ||
| oldHeader: '', | ||
| newFileName: '\vue2-dragula\dist\vue-dragula.js', | ||
| newHeader: '', | ||
| hunks: [object1, object2, ...] | ||
| } | ||
| info = | ||
| { | ||
| index: '\vue2-dragula\dist\vue-dragula.js', | ||
| oldFileName: '\vue2-dragula\dist\vue-dragula.js', | ||
| oldHeader: '', | ||
| newFileName: '\vue2-dragula\dist\vue-dragula.js', | ||
| newHeader: '', | ||
| hunks: [object1, object2, ...] | ||
| } | ||
| */ | ||
| const oldName = path.join(curDir, 'node_modules', pathNormalize(info.index)); | ||
| if(fs.existsSync(oldName)) | ||
| if(fs.existsSync(oldName)) | ||
| { | ||
@@ -455,3 +458,3 @@ // read the original file | ||
| const oldName = path.join(curDir, 'node_modules', pathNormalize(chunk.chunkInfo.index)); | ||
| if(!fs.existsSync(oldName)) | ||
| if(!fs.existsSync(oldName)) | ||
| { | ||
@@ -461,3 +464,3 @@ const folder = path.dirname(oldName); | ||
| { | ||
| echo(startColor('yellowBright') + 'WARNING: Folder ' + stopColor() + startColor('redBright') + path.dirname(pathNormalize(chunk.chunkInfo.index)) + stopColor() + startColor('yellowBright') + ' does not exist - the patch is probably for older version'); | ||
| echo(startColor('yellowBright') + 'WARNING: Folder ' + stopColor() + startColor('redBright') + path.dirname(pathNormalize(chunk.chunkInfo.index)) + stopColor() + startColor('yellowBright') + ' does not exist - the patch is probably for older version'); | ||
| return; | ||
@@ -464,0 +467,0 @@ } |
+4
-3
| { | ||
| "name": "custompatch", | ||
| "version": "1.0.27", | ||
| "version": "1.0.28", | ||
| "description": "Tool for patching buggy NPM packages instead of forking them", | ||
@@ -11,4 +11,4 @@ "author": "IVO GELOV", | ||
| "engines": { | ||
| "node": ">= 8.0.0", | ||
| "npm": ">= 3.0.0" | ||
| "node": ">= 16.1.0", | ||
| "npm": ">= 6.0.0" | ||
| }, | ||
@@ -21,2 +21,3 @@ "keywords": [ | ||
| "dependencies": { | ||
| "commander": "^12.1.0", | ||
| "diff": "^4.0.2", | ||
@@ -23,0 +24,0 @@ "pacote": "^9.5.0", |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
21883
2.36%437
0.69%5
25%+ Added
+ Added