@vaadin/vaadin-usage-statistics
Advanced tools
Comparing version 2.0.3 to 2.0.4
75
check.js
var fs = require('fs'); | ||
if (process.env.npm_package_config_disabled) { | ||
console.log(` | ||
const disabledForMachine = process.env.npm_package_config_disabled; | ||
let disabledForProject = false; | ||
if (fs.existsSync("../../../package.json")) { | ||
const projectPackageJson = JSON.parse(fs.readFileSync("../../../package.json")); | ||
if (projectPackageJson.vaadin && projectPackageJson.vaadin.disableUsageStatistics) { | ||
disabledForProject = true; | ||
} | ||
} | ||
if (disabledForMachine || disabledForProject) { | ||
if (disabledForMachine) { | ||
console.log(` | ||
You have disabled Vaadin development time usage statistics collection. To re-enable, run: | ||
npm explore @vaadin/vaadin-usage-statistics -- npm run enable | ||
For more details, see https://github.com/vaadin/vaadin-usage-statistics | ||
`); | ||
`); | ||
} else { | ||
console.log(` | ||
You have disabled Vaadin development time usage statistics collection. To re-enable, remove: | ||
"vaadin": { "disableUsageStatistics": true } | ||
from the project package.json | ||
try { | ||
fs.renameSync('vaadin-usage-statistics.js', 'vaadin-usage-statistics.js.bak'); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
console.log('File not found!'); | ||
} else { | ||
throw err; | ||
} | ||
For more details, see https://github.com/vaadin/vaadin-usage-statistics | ||
`); | ||
} | ||
try { | ||
fs.renameSync('vaadin-usage-statistics-optout.js', 'vaadin-usage-statistics.js'); | ||
fs.copyFileSync('vaadin-usage-statistics-optout.js', 'vaadin-usage-statistics.js'); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
console.log('File not found!'); | ||
} else { | ||
throw err; | ||
} | ||
console.log('Error while copying file!'); | ||
throw err; | ||
} | ||
} else { | ||
console.log(` | ||
Vaadin collects development time usage statistics to improve this product. To opt-out, run: | ||
Vaadin collects development time usage statistics to improve this product. To opt-out, either run: | ||
npm explore @vaadin/vaadin-usage-statistics -- npm run disable | ||
to store disable statistics for the machine, or add | ||
"vaadin": { "disableUsageStatistics": true } | ||
to the project package.json and re-run npm install to disable statistics for the project. | ||
For more details, see https://github.com/vaadin/vaadin-usage-statistics | ||
`); | ||
/* restore backup files if previously disabled */ | ||
if (fs.existsSync('vaadin-usage-statistics.js.bak')) { | ||
try { | ||
fs.renameSync('vaadin-usage-statistics.js', 'vaadin-usage-statistics-optout.js'); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
console.log('File not found!'); | ||
} else { | ||
throw err; | ||
} | ||
} | ||
try { | ||
fs.renameSync('vaadin-usage-statistics.js.bak', 'vaadin-usage-statistics.js'); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
console.log('File not found!'); | ||
} else { | ||
throw err; | ||
} | ||
} | ||
try { | ||
fs.copyFileSync('vaadin-usage-statistics-collect.js', 'vaadin-usage-statistics.js'); | ||
} catch (err) { | ||
console.log('Error while copying file!'); | ||
throw err; | ||
} | ||
} | ||
@@ -6,3 +6,3 @@ { | ||
"name": "@vaadin/vaadin-usage-statistics", | ||
"version": "2.0.3", | ||
"version": "2.0.4", | ||
"directories": { | ||
@@ -24,3 +24,3 @@ "test": "test" | ||
"files": [ | ||
"vaadin-usage-statistics.js", | ||
"vaadin-usage-statistics-collect.js", | ||
"vaadin-usage-statistics-optout.js", | ||
@@ -27,0 +27,0 @@ "check.js" |
@@ -22,21 +22,19 @@ # Gathers usage statistics for components used during application development | ||
### Bower | ||
### npm and Vaadin 14+ (using npm) | ||
To opt-out from statistics, install the no-op version of the `vaadin-usage-statistics` package using | ||
Using npm, you can disable it for the machine by running | ||
``` | ||
bower install --save vaadin/vaadin-usage-statistics#optout | ||
npm explore @vaadin/vaadin-usage-statistics -- npm run disable | ||
``` | ||
You can verify this by checking that `vaadin-usage-statistics.html` is empty. | ||
or you can disable it for the project by adding | ||
``` | ||
"vaadin": { "disableUsageStatistics": true } | ||
``` | ||
to your project `package.json` and running `npm install` again (remove `node_modules` if needed). | ||
### npm | ||
You can verify this by checking that `vaadin-usage-statistics.js` contains an empty function. | ||
If you are using npm, run the following command: | ||
``` | ||
npm explore @vaadin/vaadin-usage-statistics -- npm run disable | ||
```` | ||
You can verify this by checking that `vaadin-usage-statistics.js` contains empty function. | ||
### Vaadin 10 - 14 (using Bower) | ||
### Java | ||
If you are using Java, add to your pom.xml: | ||
Add to your pom.xml: | ||
``` | ||
@@ -50,2 +48,11 @@ <dependency> | ||
### Bower | ||
To opt-out from statistics, install the no-op version of the `vaadin-usage-statistics` package using | ||
``` | ||
bower install --save vaadin/vaadin-usage-statistics#optout | ||
``` | ||
You can verify this by checking that `vaadin-usage-statistics.html` is empty. | ||
If you have any questions on the use of the statistics, please contact statistics@vaadin.com. |
@@ -1,500 +0,1 @@ | ||
/* This file is autogenerated from src/vaadin-usage-statistics.tpl.html */ | ||
/* | ||
This script gathers usage statistics from the application running in development mode. | ||
Statistics gathering is automatically disabled and excluded from production builds. | ||
For details and to opt-out, see https://github.com/vaadin/vaadin-usage-statistics. | ||
*/ | ||
/* | ||
FIXME(polymer-modulizer): the above comments were extracted | ||
from HTML and may be out of place here. Review them and | ||
then delete this comment! | ||
*/ | ||
import { runIfDevelopmentMode } from '@vaadin/vaadin-development-mode-detector/vaadin-development-mode-detector.js'; | ||
function maybeGatherAndSendStats() { | ||
/** vaadin-dev-mode:start | ||
(function () { | ||
'use strict'; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { | ||
return typeof obj; | ||
} : function (obj) { | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; | ||
}; | ||
var classCallCheck = function (instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
}; | ||
var createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
}; | ||
}(); | ||
var getPolymerVersion = function getPolymerVersion() { | ||
return window.Polymer && window.Polymer.version; | ||
}; | ||
var StatisticsGatherer = function () { | ||
function StatisticsGatherer(logger) { | ||
classCallCheck(this, StatisticsGatherer); | ||
this.now = new Date().getTime(); | ||
this.logger = logger; | ||
} | ||
createClass(StatisticsGatherer, [{ | ||
key: 'frameworkVersionDetectors', | ||
value: function frameworkVersionDetectors() { | ||
return { | ||
'Flow': function Flow() { | ||
if (window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.clients) { | ||
var flowVersions = Object.keys(window.Vaadin.Flow.clients).map(function (key) { | ||
return window.Vaadin.Flow.clients[key]; | ||
}).filter(function (client) { | ||
return client.getVersionInfo; | ||
}).map(function (client) { | ||
return client.getVersionInfo().flow; | ||
}); | ||
if (flowVersions.length > 0) { | ||
return flowVersions[0]; | ||
} | ||
} | ||
}, | ||
'Vaadin Framework': function VaadinFramework() { | ||
if (window.vaadin && window.vaadin.clients) { | ||
var frameworkVersions = Object.values(window.vaadin.clients).filter(function (client) { | ||
return client.getVersionInfo; | ||
}).map(function (client) { | ||
return client.getVersionInfo().vaadinVersion; | ||
}); | ||
if (frameworkVersions.length > 0) { | ||
return frameworkVersions[0]; | ||
} | ||
} | ||
}, | ||
'AngularJs': function AngularJs() { | ||
if (window.angular && window.angular.version && window.angular.version) { | ||
return window.angular.version.full; | ||
} | ||
}, | ||
'Angular': function Angular() { | ||
if (window.ng) { | ||
var tags = document.querySelectorAll("[ng-version]"); | ||
if (tags.length > 0) { | ||
return tags[0].getAttribute("ng-version"); | ||
} | ||
return "Unknown"; | ||
} | ||
}, | ||
'Backbone.js': function BackboneJs() { | ||
if (window.Backbone) { | ||
return window.Backbone.VERSION; | ||
} | ||
}, | ||
'React': function React() { | ||
var reactSelector = '[data-reactroot], [data-reactid]'; | ||
if (!!document.querySelector(reactSelector)) { | ||
// React does not publish the version by default | ||
return "unknown"; | ||
} | ||
}, | ||
'Ember': function Ember() { | ||
if (window.Em && window.Em.VERSION) { | ||
return window.Em.VERSION; | ||
} else if (window.Ember && window.Ember.VERSION) { | ||
return window.Ember.VERSION; | ||
} | ||
}, | ||
'jQuery': function (_jQuery) { | ||
function jQuery() { | ||
return _jQuery.apply(this, arguments); | ||
} | ||
jQuery.toString = function () { | ||
return _jQuery.toString(); | ||
}; | ||
return jQuery; | ||
}(function () { | ||
if (typeof jQuery === 'function' && jQuery.prototype.jquery !== undefined) { | ||
return jQuery.prototype.jquery; | ||
} | ||
}), | ||
'Polymer': function Polymer() { | ||
var version = getPolymerVersion(); | ||
if (version) { | ||
return version; | ||
} | ||
}, | ||
'LitElement': function LitElement() { | ||
var version = window.litElementVersions && window.litElementVersions[0]; | ||
if (version) { | ||
return version; | ||
} | ||
}, | ||
'LitHtml': function LitHtml() { | ||
var version = window.litHtmlVersions && window.litHtmlVersions[0]; | ||
if (version) { | ||
return version; | ||
} | ||
}, | ||
'Vue.js': function VueJs() { | ||
if (window.Vue) { | ||
return window.Vue.version; | ||
} | ||
} | ||
}; | ||
} | ||
}, { | ||
key: 'getUsedVaadinElements', | ||
value: function getUsedVaadinElements(elements) { | ||
var version = getPolymerVersion(); | ||
var elementClasses = void 0; | ||
if (version && version.indexOf('2') === 0) { | ||
// Polymer 2: components classes are stored in window.Vaadin | ||
elementClasses = Object.keys(window.Vaadin).map(function (c) { | ||
return window.Vaadin[c]; | ||
}).filter(function (c) { | ||
return c.is; | ||
}); | ||
} else { | ||
// Polymer 3: components classes are stored in window.Vaadin.registrations | ||
elementClasses = window.Vaadin.registrations || []; | ||
} | ||
elementClasses.forEach(function (klass) { | ||
var version = klass.version ? klass.version : "0.0.0"; | ||
elements[klass.is] = { version: version }; | ||
}); | ||
} | ||
}, { | ||
key: 'getUsedVaadinThemes', | ||
value: function getUsedVaadinThemes(themes) { | ||
['Lumo', 'Material'].forEach(function (themeName) { | ||
var theme; | ||
var version = getPolymerVersion(); | ||
if (version && version.indexOf('2') === 0) { | ||
// Polymer 2: themes are stored in window.Vaadin | ||
theme = window.Vaadin[themeName]; | ||
} else { | ||
// Polymer 3: themes are stored in custom element registry | ||
theme = customElements.get('vaadin-' + themeName.toLowerCase() + '-styles'); | ||
} | ||
if (theme && theme.version) { | ||
themes[themeName] = { version: theme.version }; | ||
} | ||
}); | ||
} | ||
}, { | ||
key: 'getFrameworks', | ||
value: function getFrameworks(frameworks) { | ||
var detectors = this.frameworkVersionDetectors(); | ||
Object.keys(detectors).forEach(function (framework) { | ||
var detector = detectors[framework]; | ||
try { | ||
var version = detector(); | ||
if (version) { | ||
frameworks[framework] = { "version": version }; | ||
} | ||
} catch (e) {} | ||
}); | ||
} | ||
}, { | ||
key: 'gather', | ||
value: function gather(storage) { | ||
var storedStats = storage.read(); | ||
var gatheredStats = {}; | ||
var types = ["elements", "frameworks", "themes"]; | ||
types.forEach(function (type) { | ||
gatheredStats[type] = {}; | ||
if (!storedStats[type]) { | ||
storedStats[type] = {}; | ||
} | ||
}); | ||
var previousStats = JSON.stringify(storedStats); | ||
this.getUsedVaadinElements(gatheredStats.elements); | ||
this.getFrameworks(gatheredStats.frameworks); | ||
this.getUsedVaadinThemes(gatheredStats.themes); | ||
var now = this.now; | ||
types.forEach(function (type) { | ||
var keys = Object.keys(gatheredStats[type]); | ||
keys.forEach(function (key) { | ||
if (!storedStats[type][key] || _typeof(storedStats[type][key]) != _typeof({})) { | ||
storedStats[type][key] = { "firstUsed": now }; | ||
} | ||
// Discards any previously logged version numebr | ||
storedStats[type][key].version = gatheredStats[type][key].version; | ||
storedStats[type][key].lastUsed = now; | ||
}); | ||
}); | ||
var newStats = JSON.stringify(storedStats); | ||
storage.write(newStats); | ||
if (newStats != previousStats && Object.keys(storedStats).length > 0) { | ||
this.logger.debug("New stats: " + newStats); | ||
} | ||
} | ||
}]); | ||
return StatisticsGatherer; | ||
}(); | ||
var StatisticsStorage = function () { | ||
function StatisticsStorage(key) { | ||
classCallCheck(this, StatisticsStorage); | ||
this.key = key; | ||
} | ||
createClass(StatisticsStorage, [{ | ||
key: 'read', | ||
value: function read() { | ||
var localStorageStatsString = localStorage.getItem(this.key); | ||
try { | ||
return JSON.parse(localStorageStatsString ? localStorageStatsString : '{}'); | ||
} catch (e) { | ||
return {}; | ||
} | ||
} | ||
}, { | ||
key: 'write', | ||
value: function write(data) { | ||
localStorage.setItem(this.key, data); | ||
} | ||
}, { | ||
key: 'clear', | ||
value: function clear() { | ||
localStorage.removeItem(this.key); | ||
} | ||
}, { | ||
key: 'isEmpty', | ||
value: function isEmpty() { | ||
var storedStats = this.read(); | ||
var empty = true; | ||
Object.keys(storedStats).forEach(function (key) { | ||
if (Object.keys(storedStats[key]).length > 0) { | ||
empty = false; | ||
} | ||
}); | ||
return empty; | ||
} | ||
}]); | ||
return StatisticsStorage; | ||
}(); | ||
var StatisticsSender = function () { | ||
function StatisticsSender(url, logger) { | ||
classCallCheck(this, StatisticsSender); | ||
this.url = url; | ||
this.logger = logger; | ||
} | ||
createClass(StatisticsSender, [{ | ||
key: 'send', | ||
value: function send(data, errorHandler) { | ||
var logger = this.logger; | ||
if (navigator.onLine === false) { | ||
logger.debug("Offline, can't send"); | ||
errorHandler(); | ||
return; | ||
} | ||
logger.debug("Sending data to " + this.url); | ||
var req = new XMLHttpRequest(); | ||
req.withCredentials = true; | ||
req.addEventListener("load", function () { | ||
// Stats sent, nothing more to do | ||
logger.debug("Response: " + req.responseText); | ||
}); | ||
req.addEventListener("error", function () { | ||
logger.debug("Send failed"); | ||
errorHandler(); | ||
}); | ||
req.addEventListener("abort", function () { | ||
logger.debug("Send aborted"); | ||
errorHandler(); | ||
}); | ||
req.open("POST", this.url); | ||
req.setRequestHeader("Content-Type", "application/json"); | ||
req.send(data); | ||
} | ||
}]); | ||
return StatisticsSender; | ||
}(); | ||
var StatisticsLogger = function () { | ||
function StatisticsLogger(id) { | ||
classCallCheck(this, StatisticsLogger); | ||
this.id = id; | ||
} | ||
createClass(StatisticsLogger, [{ | ||
key: '_isDebug', | ||
value: function _isDebug() { | ||
return localStorage.getItem("vaadin." + this.id + ".debug"); | ||
} | ||
}, { | ||
key: 'debug', | ||
value: function debug(msg) { | ||
if (this._isDebug()) { | ||
console.info(this.id + ": " + msg); | ||
} | ||
} | ||
}]); | ||
return StatisticsLogger; | ||
}(); | ||
var UsageStatistics = function () { | ||
function UsageStatistics() { | ||
classCallCheck(this, UsageStatistics); | ||
this.now = new Date(); | ||
this.timeNow = this.now.getTime(); | ||
this.gatherDelay = 10; // Delay between loading this file and gathering stats | ||
this.initialDelay = 24 * 60 * 60; | ||
this.logger = new StatisticsLogger("statistics"); | ||
this.storage = new StatisticsStorage("vaadin.statistics.basket"); | ||
this.gatherer = new StatisticsGatherer(this.logger); | ||
this.sender = new StatisticsSender("https://tools.vaadin.com/usage-stats/submit", this.logger); | ||
} | ||
createClass(UsageStatistics, [{ | ||
key: 'maybeGatherAndSend', | ||
value: function maybeGatherAndSend() { | ||
var _this = this; | ||
if (localStorage.getItem(UsageStatistics.optOutKey)) { | ||
return; | ||
} | ||
this.gatherer.gather(this.storage); | ||
setTimeout(function () { | ||
_this.maybeSend(); | ||
}, this.gatherDelay * 1000); | ||
} | ||
}, { | ||
key: 'lottery', | ||
value: function lottery() { | ||
return Math.random() <= 0.05; | ||
} | ||
}, { | ||
key: 'currentMonth', | ||
value: function currentMonth() { | ||
return this.now.getYear() * 12 + this.now.getMonth(); | ||
} | ||
}, { | ||
key: 'maybeSend', | ||
value: function maybeSend() { | ||
var firstUse = Number(localStorage.getItem(UsageStatistics.firstUseKey)); | ||
var monthProcessed = Number(localStorage.getItem(UsageStatistics.monthProcessedKey)); | ||
if (!firstUse) { | ||
// Use a grace period to avoid interfering with tests, incognito mode etc | ||
firstUse = this.timeNow; | ||
localStorage.setItem(UsageStatistics.firstUseKey, firstUse); | ||
} | ||
if (this.timeNow < firstUse + this.initialDelay * 1000) { | ||
this.logger.debug("No statistics will be sent until the initial delay of " + this.initialDelay + "s has passed"); | ||
return; | ||
} | ||
if (this.currentMonth() <= monthProcessed) { | ||
this.logger.debug("This month has already been processed"); | ||
return; | ||
} | ||
localStorage.setItem(UsageStatistics.monthProcessedKey, this.currentMonth()); | ||
// Use random sampling | ||
if (this.lottery()) { | ||
this.logger.debug("Congratulations, we have a winner!"); | ||
} else { | ||
this.logger.debug("Sorry, no stats from you this time"); | ||
return; | ||
} | ||
this.send(); | ||
} | ||
}, { | ||
key: 'send', | ||
value: function send() { | ||
// Ensure we have the latest data | ||
this.gatherer.gather(this.storage); | ||
// Read, send and clean up | ||
var data = this.storage.read(); | ||
data["firstUse"] = Number(localStorage.getItem(UsageStatistics.firstUseKey)); | ||
data["usageStatisticsVersion"] = UsageStatistics.version; | ||
var info = 'This request contains usage statistics gathered from the application running in development mode. \n\nStatistics gathering is automatically disabled and excluded from production builds.\n\nFor details and to opt-out, see https://github.com/vaadin/vaadin-usage-statistics.\n\n\n\n'; | ||
var self = this; | ||
this.sender.send(info + JSON.stringify(data), function () { | ||
// Revert the 'month processed' flag | ||
localStorage.setItem(UsageStatistics.monthProcessedKey, self.currentMonth() - 1); | ||
}); | ||
} | ||
}], [{ | ||
key: 'version', | ||
get: function get$1() { | ||
return '2.0.1'; | ||
} | ||
}, { | ||
key: 'firstUseKey', | ||
get: function get$1() { | ||
return 'vaadin.statistics.firstuse'; | ||
} | ||
}, { | ||
key: 'monthProcessedKey', | ||
get: function get$1() { | ||
return 'vaadin.statistics.monthProcessed'; | ||
} | ||
}, { | ||
key: 'optOutKey', | ||
get: function get$1() { | ||
return 'vaadin.statistics.optout'; | ||
} | ||
}]); | ||
return UsageStatistics; | ||
}(); | ||
try { | ||
window.Vaadin = window.Vaadin || {}; | ||
window.Vaadin.usageStatsChecker = window.Vaadin.usageStatsChecker || new UsageStatistics(); | ||
window.Vaadin.usageStatsChecker.maybeGatherAndSend(); | ||
} catch (e) { | ||
// Intentionally ignored as this is not a problem in the app being developed | ||
} | ||
}()); | ||
vaadin-dev-mode:end **/ | ||
} | ||
export const usageStatistics = function() { | ||
if (typeof runIfDevelopmentMode === 'function') { | ||
return runIfDevelopmentMode(maybeGatherAndSendStats); | ||
} | ||
}; | ||
import './vaadin-usage-statistics-collect.js'; |
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
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
32210
7
57
506
1