@scarf/scarf
Advanced tools
Comparing version 1.0.4 to 1.0.5
{ | ||
"name": "@scarf/scarf", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "Scarf is like Google Analytics for your npm packages. Gain insights into how your packages are installed and used, and by which companies.", | ||
@@ -20,3 +20,3 @@ "main": "report.js", | ||
"author": "Scarf Systems", | ||
"license": "MIT", | ||
"license": "Apache-2.0", | ||
"devDependencies": { | ||
@@ -23,0 +23,0 @@ "jest": "^25.3.0", |
@@ -25,2 +25,6 @@ const path = require('path') | ||
function npmExecPath () { | ||
return process.env.npm_execpath | ||
} | ||
const userMessageThrottleTime = 1000 * 60 // 1 minute | ||
@@ -80,6 +84,17 @@ const execTimeout = 3000 | ||
/* | ||
Scarf-js is automatically disabled when being run inside of a yarn install. | ||
The `npm_execpath` environment variable tells us which package manager is | ||
running our install | ||
*/ | ||
function isYarn () { | ||
const execPath = module.exports.npmExecPath() || '' | ||
return ['yarn', 'yarn.js', 'yarnpkg', 'yarn.cmd', 'yarnpkg.cmd'] | ||
.some(packageManBinName => execPath.endsWith(packageManBinName)) | ||
} | ||
function processDependencyTreeOutput (resolve, reject) { | ||
return function (error, stdout, stderr) { | ||
if (error) { | ||
return reject(new Error(`Scarf received an error from npm -ls: ${error}`)) | ||
if (error && !stdout) { | ||
return reject(new Error(`Scarf received an error from npm -ls: ${error} | ${stderr}`)) | ||
} | ||
@@ -121,4 +136,4 @@ | ||
// If any intermediate dependency in the chain of deps that leads to scarf | ||
// has disabled Scarf, we must respect that setting | ||
if (dependencyToReport.anyInChainDisabled) { | ||
// has disabled Scarf, we must respect that setting unless the user overrides it. | ||
if (dependencyToReport.anyInChainDisabled && !userHasOptedIn(dependencyToReport.rootPackage)) { | ||
return reject(new Error('Scarf has been disabled via a package.json in the dependency chain.')) | ||
@@ -143,3 +158,4 @@ } | ||
const scarfApiToken = process.env.SCARF_API_TOKEN | ||
const dependencyInfo = await getDependencyInfo() | ||
const dependencyInfo = await module.exports.getDependencyInfo() | ||
if (!dependencyInfo.parent || !dependencyInfo.parent.name) { | ||
@@ -151,2 +167,6 @@ return Promise.reject(new Error('No parent, nothing to report')) | ||
if (!userHasOptedIn(rootPackage) && isYarn()) { | ||
return Promise.reject(new Error('Package manager is yarn. scarf-js is unable to inform user of analytics. Aborting.')) | ||
} | ||
await new Promise((resolve, reject) => { | ||
@@ -161,3 +181,3 @@ if (dependencyInfo.parent.scarfSettings.defaultOptIn) { | ||
The dependency '${dependencyInfo.parent.name}' is tracking installation | ||
statistics using Scarf (https://scarf.sh), which helps open-source developers | ||
statistics using scarf-js (https://scarf.sh), which helps open-source developers | ||
fund and maintain their projects. Scarf securely logs basic installation | ||
@@ -181,3 +201,3 @@ details when this package is installed. The Scarf npm library is open source | ||
The dependency '${dependencyInfo.parent.name}' would like to track | ||
installation statistics using Scarf (https://scarf.sh), which helps | ||
installation statistics using scarf-js (https://scarf.sh), which helps | ||
open-source developers fund and maintain their projects. Reporting is disabled | ||
@@ -414,2 +434,15 @@ by default for this package. When enabled, Scarf securely logs basic | ||
module.exports = { | ||
redactSensitivePackageInfo, | ||
hasHitRateLimit, | ||
getRateLimitedLogHistory, | ||
rateLimitedUserLog, | ||
tmpFileName, | ||
dirName, | ||
processDependencyTreeOutput, | ||
npmExecPath, | ||
getDependencyInfo, | ||
reportPostInstall | ||
} | ||
if (require.main === module) { | ||
@@ -429,11 +462,1 @@ try { | ||
} | ||
module.exports = { | ||
redactSensitivePackageInfo, | ||
hasHitRateLimit, | ||
getRateLimitedLogHistory, | ||
rateLimitedUserLog, | ||
tmpFileName, | ||
dirName, | ||
processDependencyTreeOutput | ||
} |
@@ -73,5 +73,7 @@ const report = require('../report') | ||
const exampleLsOutput = fs.readFileSync('./test/example-ls-output.json') | ||
await expect(new Promise((resolve, reject) => { | ||
return report.processDependencyTreeOutput(resolve, reject)(null, exampleLsOutput, null) | ||
})).rejects.toEqual(new Error('Scarf has been disabled via a package.json in the dependency chain.')) | ||
const parsedLsOutput = JSON.parse(exampleLsOutput) | ||
@@ -87,2 +89,43 @@ delete (parsedLsOutput.dependencies['scarfed-lib-consumer'].scarfSettings) | ||
}) | ||
test('Disable when package manager is yarn', async () => { | ||
const parsedLsOutput = dependencyTreeScarfEnabled() | ||
await new Promise((resolve, reject) => { | ||
return report.processDependencyTreeOutput(resolve, reject)(null, JSON.stringify(parsedLsOutput), null) | ||
}).then(output => { | ||
expect(output).toBeTruthy() | ||
expect(output.anyInChainDisabled).toBe(false) | ||
}) | ||
// Simulate a yarn install by mocking the env variable npm_execpath | ||
// leading to a yarn executable | ||
report.npmExecPath = jest.fn(() => { | ||
return '/usr/local/lib/node_modules/yarn/bin/yarn.js' | ||
}) | ||
report.getDependencyInfo = jest.fn(() => { | ||
return Promise.resolve({ | ||
scarf: { name: '@scarf/scarf', version: '0.0.1' }, | ||
parent: { name: 'scarfed-library', version: '1.0.0', scarfSettings: { defaultOptIn: true } }, | ||
grandparent: { name: 'scarfed-lib-consumer', version: '1.0.0' } | ||
}) | ||
}) | ||
try { | ||
await report.reportPostInstall() | ||
throw new Error("report.reportPostInstall() didn't throw an error") | ||
} catch (err) { | ||
expect(err.message).toContain('yarn') | ||
} | ||
}) | ||
}) | ||
function dependencyTreeScarfEnabled () { | ||
const exampleLsOutput = fs.readFileSync('./test/example-ls-output.json') | ||
const parsedLsOutput = JSON.parse(exampleLsOutput) | ||
delete (parsedLsOutput.dependencies['scarfed-lib-consumer'].scarfSettings) | ||
return parsedLsOutput | ||
} |
Sorry, the diff of this file is not supported yet
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
39598
604
9