123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- var _chalk = _interopRequireDefault(require("next/dist/compiled/chalk"));
- var _conf = _interopRequireDefault(require("next/dist/compiled/conf"));
- var _crypto = require("crypto");
- var _isDocker = _interopRequireDefault(require("next/dist/compiled/is-docker"));
- var _path = _interopRequireDefault(require("path"));
- var _anonymousMeta = require("./anonymous-meta");
- var ciEnvironment = _interopRequireWildcard(require("./ci-info"));
- var _postPayload = require("./post-payload");
- var _projectId = require("./project-id");
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- function _getRequireWildcardCache() {
- if (typeof WeakMap !== "function") return null;
- var cache = new WeakMap();
- _getRequireWildcardCache = function() {
- return cache;
- };
- return cache;
- }
- function _interopRequireWildcard(obj) {
- if (obj && obj.__esModule) {
- return obj;
- }
- if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
- return {
- default: obj
- };
- }
- var cache = _getRequireWildcardCache();
- if (cache && cache.has(obj)) {
- return cache.get(obj);
- }
- var newObj = {};
- var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
- for(var key in obj){
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
- if (desc && (desc.get || desc.set)) {
- Object.defineProperty(newObj, key, desc);
- } else {
- newObj[key] = obj[key];
- }
- }
- }
- newObj.default = obj;
- if (cache) {
- cache.set(obj, newObj);
- }
- return newObj;
- }
- // This is the key that stores whether or not telemetry is enabled or disabled.
- const TELEMETRY_KEY_ENABLED = "telemetry.enabled";
- // This is the key that specifies when the user was informed about anonymous
- // telemetry collection.
- const TELEMETRY_KEY_NOTIFY_DATE = "telemetry.notifiedAt";
- // This is a quasi-persistent identifier used to dedupe recurring events. It's
- // generated from random data and completely anonymous.
- const TELEMETRY_KEY_ID = `telemetry.anonymousId`;
- // This is the cryptographic salt that is included within every hashed value.
- // This salt value is never sent to us, ensuring privacy and the one-way nature
- // of the hash (prevents dictionary lookups of pre-computed hashes).
- // See the `oneWayHash` function.
- const TELEMETRY_KEY_SALT = `telemetry.salt`;
- function getStorageDirectory(distDir) {
- const isLikelyEphemeral = ciEnvironment.isCI || (0, _isDocker).default();
- if (isLikelyEphemeral) {
- return _path.default.join(distDir, "cache");
- }
- return undefined;
- }
- class Telemetry {
- constructor({ distDir }){
- // Read in the constructor so that .env can be loaded before reading
- const { NEXT_TELEMETRY_DISABLED , NEXT_TELEMETRY_DEBUG } = process.env;
- this.NEXT_TELEMETRY_DISABLED = NEXT_TELEMETRY_DISABLED;
- this.NEXT_TELEMETRY_DEBUG = NEXT_TELEMETRY_DEBUG;
- const storageDirectory = getStorageDirectory(distDir);
- try {
- // `conf` incorrectly throws a permission error during initialization
- // instead of waiting for first use. We need to handle it, otherwise the
- // process may crash.
- this.conf = new _conf.default({
- projectName: "nextjs",
- cwd: storageDirectory
- });
- } catch (_) {
- this.conf = null;
- }
- this.sessionId = (0, _crypto).randomBytes(32).toString("hex");
- this.rawProjectId = (0, _projectId).getRawProjectId();
- this.queue = new Set();
- this.notify();
- }
- notify = ()=>{
- if (this.isDisabled || !this.conf) {
- return;
- }
- // The end-user has already been notified about our telemetry integration. We
- // don't need to constantly annoy them about it.
- // We will re-inform users about the telemetry if significant changes are
- // ever made.
- if (this.conf.get(TELEMETRY_KEY_NOTIFY_DATE, "")) {
- return;
- }
- this.conf.set(TELEMETRY_KEY_NOTIFY_DATE, Date.now().toString());
- console.log(`${_chalk.default.magenta.bold("Attention")}: Next.js now collects completely anonymous telemetry regarding usage.`);
- console.log(`This information is used to shape Next.js' roadmap and prioritize features.`);
- console.log(`You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:`);
- console.log(_chalk.default.cyan("https://nextjs.org/telemetry"));
- console.log();
- };
- get anonymousId() {
- const val = this.conf && this.conf.get(TELEMETRY_KEY_ID);
- if (val) {
- return val;
- }
- const generated = (0, _crypto).randomBytes(32).toString("hex");
- this.conf && this.conf.set(TELEMETRY_KEY_ID, generated);
- return generated;
- }
- get salt() {
- const val = this.conf && this.conf.get(TELEMETRY_KEY_SALT);
- if (val) {
- return val;
- }
- const generated = (0, _crypto).randomBytes(16).toString("hex");
- this.conf && this.conf.set(TELEMETRY_KEY_SALT, generated);
- return generated;
- }
- get isDisabled() {
- if (!!this.NEXT_TELEMETRY_DISABLED || !this.conf) {
- return true;
- }
- return this.conf.get(TELEMETRY_KEY_ENABLED, true) === false;
- }
- setEnabled = (_enabled)=>{
- const enabled = !!_enabled;
- this.conf && this.conf.set(TELEMETRY_KEY_ENABLED, enabled);
- return this.conf && this.conf.path;
- };
- get isEnabled() {
- return !!this.conf && this.conf.get(TELEMETRY_KEY_ENABLED, true) !== false;
- }
- oneWayHash = (payload)=>{
- const hash = (0, _crypto).createHash("sha256");
- // Always prepend the payload value with salt. This ensures the hash is truly
- // one-way.
- hash.update(this.salt);
- // Update is an append operation, not a replacement. The salt from the prior
- // update is still present!
- hash.update(payload);
- return hash.digest("hex");
- };
- get projectId() {
- return this.oneWayHash(this.rawProjectId);
- }
- record = (_events)=>{
- const _this = this;
- // pseudo try-catch
- async function wrapper() {
- return await _this.submitRecord(_events);
- }
- const prom = wrapper().then((value)=>({
- isFulfilled: true,
- isRejected: false,
- value
- })).catch((reason)=>({
- isFulfilled: false,
- isRejected: true,
- reason
- }))// Acts as `Promise#finally` because `catch` transforms the error
- .then((res)=>{
- // Clean up the event to prevent unbounded `Set` growth
- this.queue.delete(prom);
- return res;
- });
- // Track this `Promise` so we can flush pending events
- this.queue.add(prom);
- return prom;
- };
- flush = async ()=>Promise.all(this.queue).catch(()=>null);
- submitRecord = (_events)=>{
- let events;
- if (Array.isArray(_events)) {
- events = _events;
- } else {
- events = [
- _events
- ];
- }
- if (events.length < 1) {
- return Promise.resolve();
- }
- if (this.NEXT_TELEMETRY_DEBUG) {
- // Print to standard error to simplify selecting the output
- events.forEach(({ eventName , payload })=>console.error(`[telemetry] ` + JSON.stringify({
- eventName,
- payload
- }, null, 2)));
- // Do not send the telemetry data if debugging. Users may use this feature
- // to preview what data would be sent.
- return Promise.resolve();
- }
- // Skip recording telemetry if the feature is disabled
- if (this.isDisabled) {
- return Promise.resolve();
- }
- const context = {
- anonymousId: this.anonymousId,
- projectId: this.projectId,
- sessionId: this.sessionId
- };
- const meta = (0, _anonymousMeta).getAnonymousMeta();
- return (0, _postPayload)._postPayload(`https://telemetry.nextjs.org/api/v1/record`, {
- context,
- meta,
- events: events.map(({ eventName , payload })=>({
- eventName,
- fields: payload
- }))
- });
- };
- }
- exports.Telemetry = Telemetry;
- //# sourceMappingURL=storage.js.map
|