Comparing version 3.2.1 to 4.0.0
154
bin/crx.js
@@ -5,8 +5,10 @@ #!/usr/bin/env node | ||
var fs = require("fs"); | ||
var rsa = require('node-rsa'); | ||
var Promise = require('es6-promise').Promise; | ||
var rsa = require("node-rsa"); | ||
var {promisify} = require("util"); | ||
var writeFile = promisify(fs.writeFile); | ||
var readFile = promisify(fs.readFile); | ||
var program = require("commander"); | ||
var ChromeExtension = require(".."); | ||
var pkg = require('../package.json'); | ||
var pkg = require("../package.json"); | ||
@@ -31,6 +33,12 @@ var resolve = path.resolve; | ||
.description("pack [directory] into a .crx extension") | ||
.option("-o, --output <file>", "write the crx content to <file> instead of stdout") | ||
.option( | ||
"-o, --output <file>", | ||
"write the crx content to <file> instead of stdout" | ||
) | ||
.option("--zip-output <file>", "write the zip content to <file>") | ||
.option("-p, --private-key <file>", "relative path to private key [key.pem]") | ||
.option("-b, --max-buffer <total>", "max amount of memory allowed to generate the crx, in byte") | ||
.option( | ||
"-b, --max-buffer <total>", | ||
"max amount of memory allowed to generate the crx, in byte" | ||
) | ||
.action(pack); | ||
@@ -40,18 +48,2 @@ | ||
/** | ||
* Read a specified key file from disk | ||
* @param {String} keyPath path to the key to read | ||
* @returns {Promise} | ||
*/ | ||
function readKeyFile(keyPath) { | ||
return new Promise(function (resolve, reject) { | ||
fs.readFile(keyPath, function (err, data) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(data); | ||
} | ||
}); | ||
}); | ||
} | ||
@@ -64,19 +56,8 @@ /** | ||
function generateKeyFile(keyPath) { | ||
return new Promise(function(resolve, reject) { | ||
var key = new rsa({b: 2048}), | ||
keyVal = key.exportKey('pkcs1-private-pem'); | ||
fs.writeFile(keyPath, keyVal, function(err){ | ||
if (err) { | ||
throw err; | ||
} | ||
console.log('Key file has been generated at %s', keyPath); | ||
resolve(keyVal); | ||
}); | ||
}); | ||
return Promise.resolve(new rsa({ b: 2048 })) | ||
.then(key => key.exportKey("pkcs1-private-pem")) | ||
.then(keyVal => writeFile(keyPath, keyVal)); | ||
} | ||
function keygen (dir, program) { | ||
function keygen(dir, program) { | ||
dir = dir ? resolve(cwd, dir) : cwd; | ||
@@ -86,5 +67,5 @@ | ||
fs.exists(keyPath, function (exists) { | ||
fs.exists(keyPath, function(exists) { | ||
if (exists && !program.force) { | ||
throw new Error('key.pem already exists in the given location.'); | ||
throw new Error("key.pem already exists in the given location."); | ||
} | ||
@@ -96,10 +77,16 @@ | ||
function pack (dir, program) { | ||
function pack(dir, program) { | ||
var input = dir ? resolve(cwd, dir) : cwd; | ||
var keyPath = program.privateKey ? resolve(cwd, program.privateKey) : join(input, "key.pem"); | ||
var keyPath = program.privateKey | ||
? resolve(cwd, program.privateKey) | ||
: join(input, "key.pem"); | ||
var output; | ||
if (program.output) { | ||
if (path.extname(program.output) !== '.crx') { | ||
throw new Error('-o file is expected to have a `.crx` suffix: [' + program.output + '] was given.'); | ||
if (path.extname(program.output) !== ".crx") { | ||
throw new Error( | ||
"-o file is expected to have a `.crx` suffix: [" + | ||
program.output + | ||
"] was given." | ||
); | ||
} | ||
@@ -109,4 +96,8 @@ } | ||
if (program.zipOutput) { | ||
if (path.extname(program.zipOutput) !== '.zip') { | ||
throw new Error('--zip-output file is expected to have a `.zip` suffix: [' + program.zipOutput + '] was given.'); | ||
if (path.extname(program.zipOutput) !== ".zip") { | ||
throw new Error( | ||
"--zip-output file is expected to have a `.zip` suffix: [" + | ||
program.zipOutput + | ||
"] was given." | ||
); | ||
} | ||
@@ -117,42 +108,53 @@ } | ||
rootDirectory: input, | ||
maxBuffer: program.maxBuffer | ||
maxBuffer: program.maxBuffer | ||
}); | ||
readKeyFile(keyPath).then(null, function (err) { | ||
// If the key file doesn't exist, create one | ||
if (err.code === 'ENOENT') { | ||
return generateKeyFile(keyPath); | ||
} else { | ||
throw err; | ||
} | ||
}).then(function (key) { | ||
crx.privateKey = key; | ||
}).then(function () { | ||
crx.load().then(function () { | ||
return crx.loadContents(); | ||
}).then(function (zipBuffer) { | ||
if (program.zipOutput) { | ||
var outFile = resolve(cwd, program.zipOutput); | ||
fs.createWriteStream(outFile).end(zipBuffer); | ||
readFile(keyPath) | ||
.then(null, function(err) { | ||
// If the key file doesn't exist, create one | ||
if (err.code === "ENOENT") { | ||
return generateKeyFile(keyPath); | ||
} else { | ||
throw err; | ||
} | ||
}) | ||
.then(function(key) { | ||
crx.privateKey = key; | ||
}) | ||
.then(function() { | ||
crx | ||
.load() | ||
.then(() => crx.loadContents()) | ||
.then(function(fileBuffer) { | ||
if (program.zipOutput) { | ||
var outFile = resolve(cwd, program.zipOutput); | ||
return crx.pack(zipBuffer); | ||
}).then(function (crxBuffer) { | ||
fs.createWriteStream(outFile).end(fileBuffer); | ||
} | ||
else { | ||
return crx.pack(fileBuffer); | ||
} | ||
}) | ||
.then(function(crxBuffer) { | ||
if (program.zipOutput) { | ||
return; | ||
} | ||
else if (program.output) { | ||
output = program.output; | ||
} | ||
else { | ||
output = path.basename(cwd) + ".crx"; | ||
} | ||
if (program.output) { | ||
output = program.output; | ||
} else { | ||
output = path.basename(cwd) + '.crx'; | ||
} | ||
var outFile = resolve(cwd, output); | ||
(outFile ? fs.createWriteStream(outFile) : process.stdout).end(crxBuffer); | ||
}).then(function () { | ||
console.log('%s has been generated in %s', output, cwd); | ||
var outFile = resolve(cwd, output); | ||
if (outFile) { | ||
fs.createWriteStream(outFile).end(crxBuffer); | ||
} | ||
else { | ||
process.stdout.end(crxBuffer); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
module.exports = program; |
## Change Log | ||
### 3.2.1 (2016/10/13 13:13 +00:00) | ||
### 4.0.0 (2019/02/03 15:57 +00:00) | ||
- [#95](https://github.com/oncletom/crx/pull/95) Release crx@4 (@oncletom) | ||
- [#93](https://github.com/oncletom/crx/pull/93) fix demo code (@g8up) | ||
- [#88](https://github.com/oncletom/crx/pull/88) Bump Node.js version requirement (@oncletom) | ||
- [#90](https://github.com/oncletom/crx/pull/90) Fix syntax in module usage (@blimmer) | ||
- [#83](https://github.com/oncletom/crx/pull/83) Update dependencies (@oncletom) | ||
- [#81](https://github.com/oncletom/crx/pull/81) Fix extension ID calculation from path (@oncletom, @conioh) | ||
- [#76](https://github.com/oncletom/crx/pull/76) Add Appveyor configuration to test build on Windows (@oncletom) | ||
- [#71](https://github.com/oncletom/crx/pull/71) Remove the manifest data from cache on crx.load() (@binhqx) | ||
- [#75](https://github.com/oncletom/crx/pull/75) [Snyk Update] New fixes for 1 vulnerable dependency path (@snyk-bot) | ||
### v3.2.1 (2016/10/13 13:13 +00:00) | ||
- [#67](https://github.com/oncletom/crx/pull/67) Drop iojs from package.engines (@dsblv) | ||
@@ -5,0 +16,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"description": "crx is a utility to package Google Chrome extensions via a Node API and the command line", | ||
"version": "3.2.1", | ||
"version": "4.0.0", | ||
"license": "MIT", | ||
@@ -18,6 +18,7 @@ "homepage": "https://github.com/oncletom/crx", | ||
"engines": { | ||
"node": ">=0.10" | ||
"node": ">=10" | ||
}, | ||
"scripts": { | ||
"test": "nyc tape ./test/*.js", | ||
"posttest": "eslint src/*.js bin/crx.js", | ||
"version": "npm run changelog && git add CHANGELOG.md", | ||
@@ -37,13 +38,13 @@ "changelog": "github-changes -o oncletom -r crx -n ${npm_package_version} --only-pulls --use-commit-body" | ||
"dependencies": { | ||
"archiver": "^1.1.0", | ||
"commander": "^2.5.0", | ||
"es6-promise": "^3.0.0", | ||
"node-rsa": "^0.2.10" | ||
"archiver": "^3.0.0", | ||
"commander": "^2.19.0", | ||
"node-rsa": "^1.0.3" | ||
}, | ||
"devDependencies": { | ||
"adm-zip": "^0.4.7", | ||
"adm-zip": "^0.4.13", | ||
"eslint": "^5.13.0", | ||
"github-changes": "^1.0.0", | ||
"nyc": "^8.3.0", | ||
"tape": "^4.6.0" | ||
"nyc": "^13.1.0", | ||
"tape": "^4.9.2" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# crx [![Build Status](https://secure.travis-ci.org/oncletom/crx.svg)](http://travis-ci.org/oncletom/crx) | ||
# crx [![Build Status](https://secure.travis-ci.org/oncletom/crx.svg)](http://travis-ci.org/oncletom/crx) [![Build status](https://ci.appveyor.com/api/projects/status/i8v95qmgwwxic5wn?svg=true)](https://ci.appveyor.com/project/oncletom/crx) | ||
@@ -13,3 +13,3 @@ > crx is a utility to **package Google Chrome extensions** via a *Node API* and the *command line*. It is written **purely in JavaScript** and **does not require OpenSSL**! | ||
**Compatibility**: this extension is compatible with `node>=0.10`. | ||
**Compatibility**: this extension is compatible with `node>=10`. | ||
@@ -24,13 +24,16 @@ ## Install | ||
Asynchronous functions returns an [ES6 Promise](https://github.com/jakearchibald/es6-promise). | ||
Asynchronous functions returns a native ECMAScript Promise. | ||
```js | ||
const fs = require("fs"); | ||
const ChromeExtension = require("crx"); | ||
const crx = new ChromeExtension( | ||
codebase: "http://localhost:8000/myFirstExtension.crx", | ||
privateKey: fs.readFileSync("./key.pem")) | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const ChromeExtension = require('crx'); | ||
const crx = new ChromeExtension({ | ||
codebase: 'http://localhost:8000/myExtension.crx', | ||
privateKey: fs.readFileSync('./key.pem') | ||
}); | ||
crx.load("./myFirstExtension")) | ||
crx.load( path.resolve(__dirname, './myExtension') ) | ||
.then(crx => crx.pack()) | ||
@@ -40,4 +43,7 @@ .then(crxBuffer => { | ||
fs.writeFile("../update.xml"), updateXML); | ||
fs.writeFile("../myFirstExtension.crx"), crxBuffer); | ||
fs.writeFile('../update.xml', updateXML); | ||
fs.writeFile('../myExtension.crx', crxBuffer); | ||
}) | ||
.catch(err=>{ | ||
console.error( err ); | ||
}); | ||
@@ -117,3 +123,3 @@ ``` | ||
### crx -h | ||
### crx --help | ||
@@ -180,24 +186,4 @@ Show information about using this utility, generated by [commander](https://github.com/visionmedia/commander.js). | ||
Copyright | ||
--------- | ||
# License | ||
Copyright (c) 2016 Jed Schmidt, Thomas Parisot and collaborators | ||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
[MIT License](LICENSE). |
186
src/crx.js
@@ -1,3 +0,2 @@ | ||
/* global require, process, Buffer, module */ | ||
'use strict'; | ||
"use strict"; | ||
@@ -10,39 +9,22 @@ var fs = require("fs"); | ||
var archiver = require("archiver"); | ||
var Promise = require("es6-promise").Promise; | ||
var resolve = require("./resolver.js"); | ||
function ChromeExtension(attrs) { | ||
if ((this instanceof ChromeExtension) !== true) { | ||
return new ChromeExtension(attrs); | ||
} | ||
const DEFAULTS = { | ||
appId: null, | ||
rootDirectory: "", | ||
publicKey: null, | ||
privateKey: null, | ||
codebase: null, | ||
path: null, | ||
src: "**", | ||
}; | ||
/* | ||
Defaults | ||
*/ | ||
this.appId = null; | ||
class ChromeExtension { | ||
constructor(attrs) { | ||
// Setup defaults | ||
Object.assign(this, DEFAULTS, attrs); | ||
this.rootDirectory = ''; | ||
this.publicKey = null; | ||
this.privateKey = null; | ||
this.codebase = null; | ||
this.path = null; | ||
this.src = '**'; | ||
/* | ||
Copying attributes | ||
*/ | ||
for (var name in attrs) { | ||
this[name] = attrs[name]; | ||
this.loaded = false; | ||
} | ||
this.loaded = false; | ||
} | ||
ChromeExtension.prototype = { | ||
/** | ||
@@ -60,3 +42,3 @@ * Packs the content of the extension in a crx file. | ||
*/ | ||
pack: function (contentsBuffer) { | ||
pack (contentsBuffer) { | ||
if (!this.loaded) { | ||
@@ -72,3 +54,3 @@ return this.load().then(this.pack.bind(this, contentsBuffer)); | ||
return Promise.all(packP).then(function(outputs){ | ||
return Promise.all(packP).then(function(outputs) { | ||
var publicKey = outputs[0]; | ||
@@ -83,3 +65,3 @@ var contents = outputs[1]; | ||
}); | ||
}, | ||
} | ||
@@ -92,17 +74,19 @@ /** | ||
*/ | ||
load: function (path) { | ||
load (path) { | ||
var selfie = this; | ||
return resolve(path || selfie.rootDirectory) | ||
.then(function(metadata){ | ||
selfie.path = metadata.path; | ||
selfie.src = metadata.src; | ||
return resolve(path || selfie.rootDirectory).then(function(metadata) { | ||
selfie.path = metadata.path; | ||
selfie.src = metadata.src; | ||
selfie.manifest = require(join(selfie.path, "manifest.json")); | ||
selfie.loaded = true; | ||
var manifestPath = join(selfie.path, "manifest.json"); | ||
delete require.cache[manifestPath]; | ||
return selfie; | ||
}); | ||
}, | ||
selfie.manifest = require(manifestPath); | ||
selfie.loaded = true; | ||
return selfie; | ||
}); | ||
} | ||
/** | ||
@@ -116,8 +100,8 @@ * Writes data into the extension workable directory. | ||
*/ | ||
writeFile: function (path, data) { | ||
writeFile (path, data) { | ||
var absPath = join(this.path, path); | ||
/* istanbul ignore next */ | ||
return new Promise(function(resolve, reject){ | ||
fs.writeFile(absPath, data, function (err) { | ||
return new Promise(function(resolve, reject) { | ||
fs.writeFile(absPath, data, function(err) { | ||
if (err) { | ||
@@ -130,3 +114,3 @@ return reject(err); | ||
}); | ||
}, | ||
} | ||
@@ -146,8 +130,10 @@ /** | ||
*/ | ||
generatePublicKey: function () { | ||
generatePublicKey () { | ||
var privateKey = this.privateKey; | ||
return new Promise(function(resolve, reject){ | ||
return new Promise(function(resolve, reject) { | ||
if (!privateKey) { | ||
return reject('Impossible to generate a public key: privateKey option has not been defined or is empty.'); | ||
return reject( | ||
"Impossible to generate a public key: privateKey option has not been defined or is empty." | ||
); | ||
} | ||
@@ -157,5 +143,5 @@ | ||
resolve(key.exportKey('pkcs8-public-der')); | ||
resolve(key.exportKey("pkcs8-public-der")); | ||
}); | ||
}, | ||
} | ||
@@ -170,4 +156,4 @@ /** | ||
*/ | ||
generateSignature: function (contents) { | ||
return new Buffer( | ||
generateSignature (contents) { | ||
return Buffer.from( | ||
crypto | ||
@@ -179,3 +165,3 @@ .createSign("sha1") | ||
); | ||
}, | ||
} | ||
@@ -188,14 +174,16 @@ /** | ||
*/ | ||
loadContents: function () { | ||
loadContents () { | ||
var selfie = this; | ||
return new Promise(function(resolve, reject){ | ||
var archive = archiver('zip'); | ||
var contents = new Buffer(''); | ||
return new Promise(function(resolve, reject) { | ||
var archive = archiver("zip"); | ||
var contents = Buffer.from(""); | ||
if (!selfie.loaded) { | ||
throw new Error('crx.load needs to be called first in order to prepare the workspace.'); | ||
throw new Error( | ||
"crx.load needs to be called first in order to prepare the workspace." | ||
); | ||
} | ||
archive.on('error', reject); | ||
archive.on("error", reject); | ||
@@ -209,7 +197,7 @@ /* | ||
*/ | ||
archive.on('data', function (buf) { | ||
archive.on("data", function(buf) { | ||
contents = Buffer.concat([contents, buf]); | ||
}); | ||
archive.on('finish', function () { | ||
archive.on("finish", function() { | ||
resolve(contents); | ||
@@ -222,7 +210,7 @@ }); | ||
matchBase: true, | ||
ignore: ['*.pem', '.git', '*.crx'] | ||
ignore: ["*.pem", ".git", "*.crx"] | ||
}) | ||
.finalize(); | ||
}); | ||
}, | ||
} | ||
@@ -239,3 +227,3 @@ /** | ||
*/ | ||
generatePackage: function (signature, publicKey, contents) { | ||
generatePackage (signature, publicKey, contents) { | ||
var keyLength = publicKey.length; | ||
@@ -246,3 +234,3 @@ var sigLength = signature.length; | ||
var crx = new Buffer(length); | ||
var crx = Buffer.alloc(length); | ||
@@ -260,3 +248,3 @@ crx.write("Cr24" + new Array(13).join("\x00"), "binary"); | ||
return crx; | ||
}, | ||
} | ||
@@ -273,16 +261,32 @@ /** | ||
*/ | ||
generateAppId: function (publicKey) { | ||
publicKey = publicKey || this.publicKey; | ||
if (typeof publicKey !== 'string' && !(publicKey instanceof Buffer)) { | ||
throw new Error('Public key is neither set, nor given'); | ||
generateAppId (keyOrPath) { | ||
keyOrPath = keyOrPath || this.publicKey; | ||
if (typeof keyOrPath !== "string" && !(keyOrPath instanceof Buffer)) { | ||
throw new Error("Public key is neither set, nor given"); | ||
} | ||
// Handling Windows Path | ||
// Possibly to be moved in a different method | ||
if (typeof keyOrPath === "string") { | ||
var charCode = keyOrPath.charCodeAt(0); | ||
// 65 (A) < charCode < 122 (z) | ||
if (charCode >= 65 && charCode <= 122 && keyOrPath[1] === ":") { | ||
keyOrPath = keyOrPath[0].toUpperCase() + keyOrPath.slice(1); | ||
keyOrPath = Buffer.from(keyOrPath, "utf-16le"); | ||
} | ||
} | ||
return crypto | ||
.createHash("sha256") | ||
.update(publicKey) | ||
.digest("hex") | ||
.slice(0, 32) | ||
.replace(/./g, function (x) { | ||
return (parseInt(x, 16) + 10).toString(26); | ||
}); | ||
}, | ||
.update(keyOrPath) | ||
.digest() | ||
.toString("hex") | ||
.split("") | ||
.map(x => (parseInt(x, 16) + 0x0a).toString(26)) | ||
.join("") | ||
.slice(0, 32); | ||
} | ||
@@ -296,3 +300,3 @@ /** | ||
*/ | ||
generateUpdateXML: function () { | ||
generateUpdateXML () { | ||
if (!this.codebase) { | ||
@@ -302,13 +306,11 @@ throw new Error("No URL provided for update.xml."); | ||
return new Buffer( | ||
"<?xml version='1.0' encoding='UTF-8'?>\n" + | ||
"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n" + | ||
" <app appid='" + (this.appId || this.generateAppId()) + "'>\n" + | ||
" <updatecheck codebase='" + this.codebase + "' version='" + this.manifest.version + "' />\n" + | ||
" </app>\n" + | ||
"</gupdate>" | ||
); | ||
return Buffer.from(`<?xml version='1.0' encoding='UTF-8'?> | ||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'> | ||
<app appid='${this.appId || this.generateAppId()}'> | ||
<updatecheck codebase='${this.codebase}' version='${this.manifest.version}' /> | ||
</app> | ||
</gupdate>`); | ||
} | ||
}; | ||
} | ||
module.exports = ChromeExtension; |
@@ -1,14 +0,12 @@ | ||
'use strict'; | ||
"use strict"; | ||
var path = require("path"); | ||
var join = path.join; | ||
var Promise = require("es6-promise").Promise; | ||
module.exports = function resolve(pathOrFiles) { | ||
return new Promise(function(resolve, reject){ | ||
return new Promise(function(resolve, reject) { | ||
// legacy and original mode | ||
if (typeof pathOrFiles === 'string') { | ||
if (typeof pathOrFiles === "string") { | ||
return resolve({ | ||
path: pathOrFiles, | ||
src: '**', | ||
src: "**" | ||
}); | ||
@@ -19,5 +17,5 @@ } | ||
else if (Array.isArray(pathOrFiles)) { | ||
var manifestFile = ''; | ||
var manifestFile = ""; | ||
pathOrFiles.some(function(f){ | ||
pathOrFiles.some(function(f) { | ||
if (/(^|\/)manifest.json$/.test(f)) { | ||
@@ -30,3 +28,5 @@ manifestFile = f; | ||
if (!manifestFile) { | ||
return reject(new Error('Unable to locate a manifest file in your list of files.')) | ||
return reject( | ||
new Error("Unable to locate a manifest file in your list of files.") | ||
); | ||
} | ||
@@ -38,6 +38,11 @@ | ||
path: path.resolve(manifestDir), | ||
src: '{' + pathOrFiles.map(function(f){ | ||
return path.relative(manifestDir, f); | ||
}).join(',') + '}' | ||
}) | ||
src: | ||
"{" + | ||
pathOrFiles | ||
.map(function(f) { | ||
return path.relative(manifestDir, f); | ||
}) | ||
.join(",") + | ||
"}" | ||
}); | ||
} | ||
@@ -47,5 +52,9 @@ | ||
else { | ||
reject(new Error('load path is none of a folder location nor a list of files to pack')) | ||
reject( | ||
new Error( | ||
"load path is none of a folder location nor a list of files to pack" | ||
) | ||
); | ||
} | ||
}); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
3
24450
5
9
446
185
1
+ Addedarchiver@3.1.1(transitive)
+ Addedarchiver-utils@2.1.0(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedbl@4.1.0(transitive)
+ Addedcompress-commons@2.1.1(transitive)
+ Addedcrc32-stream@3.0.1(transitive)
+ Addedlodash.defaults@4.2.0(transitive)
+ Addedlodash.difference@4.5.0(transitive)
+ Addedlodash.flatten@4.4.0(transitive)
+ Addedlodash.isplainobject@4.0.6(transitive)
+ Addedlodash.union@4.6.0(transitive)
+ Addednode-rsa@1.1.1(transitive)
+ Addednormalize-path@3.0.0(transitive)
+ Addedreadable-stream@3.6.2(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedtar-stream@2.2.0(transitive)
+ Addedzip-stream@2.1.3(transitive)
- Removedes6-promise@^3.0.0
- Removedarchiver@1.3.0(transitive)
- Removedarchiver-utils@1.3.0(transitive)
- Removedasn1@0.2.3(transitive)
- Removedbl@1.2.3(transitive)
- Removedbuffer-alloc@1.2.0(transitive)
- Removedbuffer-alloc-unsafe@1.1.0(transitive)
- Removedbuffer-fill@1.0.0(transitive)
- Removedcompress-commons@1.2.2(transitive)
- Removedcrc32-stream@2.0.0(transitive)
- Removedes6-promise@3.3.1(transitive)
- Removedlodash@3.3.0(transitive)
- Removednode-rsa@0.2.30(transitive)
- Removednormalize-path@2.1.1(transitive)
- Removedremove-trailing-separator@1.1.0(transitive)
- Removedtar-stream@1.6.2(transitive)
- Removedto-buffer@1.1.1(transitive)
- Removedwalkdir@0.0.11(transitive)
- Removedxtend@4.0.2(transitive)
- Removedzip-stream@1.2.0(transitive)
Updatedarchiver@^3.0.0
Updatedcommander@^2.19.0
Updatednode-rsa@^1.0.3