fixed version control heatmap and activity

This commit is contained in:
will
2026-04-02 20:38:56 +01:00
parent 1da5da43e1
commit 250a7030bf
1777 changed files with 170575 additions and 83 deletions

View File

@@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getAnonymousMeta", {
enumerable: true,
get: function() {
return getAnonymousMeta;
}
});
const _isdocker = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/is-docker"));
const _iswsl = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/is-wsl"));
const _os = /*#__PURE__*/ _interop_require_default(require("os"));
const _ciinfo = /*#__PURE__*/ _interop_require_wildcard(require("./ci-info"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && 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;
}
let traits;
function getAnonymousMeta() {
if (traits) {
return traits;
}
const cpus = _os.default.cpus() || [];
const { NOW_REGION } = process.env;
traits = {
// Software information
systemPlatform: _os.default.platform(),
systemRelease: _os.default.release(),
systemArchitecture: _os.default.arch(),
// Machine information
cpuCount: cpus.length,
cpuModel: cpus.length ? cpus[0].model : null,
cpuSpeed: cpus.length ? cpus[0].speed : null,
memoryInMb: Math.trunc(_os.default.totalmem() / Math.pow(1024, 2)),
// Environment information
isDocker: (0, _isdocker.default)(),
isNowDev: NOW_REGION === "dev1",
isWsl: _iswsl.default,
isCI: _ciinfo.isCI,
ciName: _ciinfo.isCI && _ciinfo.name || null,
nextVersion: "14.2.5"
};
return traits;
}
//# sourceMappingURL=anonymous-meta.js.map

View File

@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
hasNextSupport: null,
isCI: null,
name: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
hasNextSupport: function() {
return hasNextSupport;
},
isCI: function() {
return isCI;
},
name: function() {
return name;
}
});
const _ciinfo = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/ci-info"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const { isCI: _isCI, name: _name } = _ciinfo.default;
const isZeitNow = !!process.env.NOW_BUILDER;
const envStack = process.env.STACK;
const isHeroku = typeof envStack === "string" && envStack.toLowerCase().includes("heroku");
const isCI = isZeitNow || isHeroku || _isCI;
const name = isZeitNow ? "ZEIT Now" : isHeroku ? "Heroku" : _name;
const hasNextSupport = Boolean(isZeitNow);
//# sourceMappingURL=ci-info.js.map

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
const _storage = require("./storage");
const _config = /*#__PURE__*/ _interop_require_default(require("../server/config"));
const _getprojectdir = require("../lib/get-project-dir");
const _constants = require("../shared/lib/constants");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
(async ()=>{
const args = [
...process.argv
];
let dir = args.pop();
const mode = args.pop();
if (!dir || mode !== "dev") {
throw new Error(`Invalid flags should be run as node detached-flush dev ./path-to/project`);
}
dir = (0, _getprojectdir.getProjectDir)(dir);
const config = await (0, _config.default)(_constants.PHASE_DEVELOPMENT_SERVER, dir);
const distDir = _path.default.join(dir, config.distDir || ".next");
const eventsPath = _path.default.join(distDir, "_events.json");
let events;
try {
events = JSON.parse(_fs.default.readFileSync(eventsPath, "utf8"));
} catch (err) {
if (err.code === "ENOENT") {
// no events to process we can exit now
process.exit(0);
}
throw err;
}
const telemetry = new _storage.Telemetry({
distDir
});
await telemetry.record(events);
await telemetry.flush();
// finished flushing events clean-up/exit
_fs.default.unlinkSync(eventsPath);
process.exit(0);
})();
//# sourceMappingURL=detached-flush.js.map

View File

@@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
EVENT_BUILD_FEATURE_USAGE: null,
EVENT_NAME_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS: null,
eventBuildCompleted: null,
eventBuildFeatureUsage: null,
eventBuildOptimize: null,
eventLintCheckCompleted: null,
eventPackageUsedInGetServerSideProps: null,
eventTypeCheckCompleted: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
EVENT_BUILD_FEATURE_USAGE: function() {
return EVENT_BUILD_FEATURE_USAGE;
},
EVENT_NAME_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS: function() {
return EVENT_NAME_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS;
},
eventBuildCompleted: function() {
return eventBuildCompleted;
},
eventBuildFeatureUsage: function() {
return eventBuildFeatureUsage;
},
eventBuildOptimize: function() {
return eventBuildOptimize;
},
eventLintCheckCompleted: function() {
return eventLintCheckCompleted;
},
eventPackageUsedInGetServerSideProps: function() {
return eventPackageUsedInGetServerSideProps;
},
eventTypeCheckCompleted: function() {
return eventTypeCheckCompleted;
}
});
const REGEXP_DIRECTORY_DUNDER = /[\\/]__[^\\/]+(?<![\\/]__(?:tests|mocks))__[\\/]/i;
const REGEXP_DIRECTORY_TESTS = /[\\/]__(tests|mocks)__[\\/]/i;
const REGEXP_FILE_TEST = /\.(?:spec|test)\.[^.]+$/i;
const EVENT_TYPE_CHECK_COMPLETED = "NEXT_TYPE_CHECK_COMPLETED";
function eventTypeCheckCompleted(event) {
return {
eventName: EVENT_TYPE_CHECK_COMPLETED,
payload: event
};
}
const EVENT_LINT_CHECK_COMPLETED = "NEXT_LINT_CHECK_COMPLETED";
function eventLintCheckCompleted(event) {
return {
eventName: EVENT_LINT_CHECK_COMPLETED,
payload: event
};
}
const EVENT_BUILD_COMPLETED = "NEXT_BUILD_COMPLETED";
function eventBuildCompleted(pagePaths, event) {
return {
eventName: EVENT_BUILD_COMPLETED,
payload: {
...event,
totalPageCount: pagePaths.length,
hasDunderPages: pagePaths.some((path)=>REGEXP_DIRECTORY_DUNDER.test(path)),
hasTestPages: pagePaths.some((path)=>REGEXP_DIRECTORY_TESTS.test(path) || REGEXP_FILE_TEST.test(path)),
totalAppPagesCount: event.totalAppPagesCount
}
};
}
const EVENT_BUILD_OPTIMIZED = "NEXT_BUILD_OPTIMIZED";
function eventBuildOptimize(pagePaths, event) {
return {
eventName: EVENT_BUILD_OPTIMIZED,
payload: {
...event,
totalPageCount: pagePaths.length,
hasDunderPages: pagePaths.some((path)=>REGEXP_DIRECTORY_DUNDER.test(path)),
hasTestPages: pagePaths.some((path)=>REGEXP_DIRECTORY_TESTS.test(path) || REGEXP_FILE_TEST.test(path)),
totalAppPagesCount: event.totalAppPagesCount,
staticAppPagesCount: event.staticAppPagesCount,
serverAppPagesCount: event.serverAppPagesCount,
edgeRuntimeAppCount: event.edgeRuntimeAppCount,
edgeRuntimePagesCount: event.edgeRuntimePagesCount
}
};
}
const EVENT_BUILD_FEATURE_USAGE = "NEXT_BUILD_FEATURE_USAGE";
function eventBuildFeatureUsage(usages) {
return usages.map(({ featureName, invocationCount })=>({
eventName: EVENT_BUILD_FEATURE_USAGE,
payload: {
featureName,
invocationCount
}
}));
}
const EVENT_NAME_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS = "NEXT_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS";
function eventPackageUsedInGetServerSideProps(packagesUsedInServerSideProps) {
return packagesUsedInServerSideProps.map((packageName)=>({
eventName: EVENT_NAME_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS,
payload: {
package: packageName
}
}));
}
//# sourceMappingURL=build.js.map

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && __export(require("./version")) && __export(require("./build")) && __export(require("./plugins"));
_export_star(require("./version"), exports);
_export_star(require("./build"), exports);
_export_star(require("./plugins"), exports);
function _export_star(from, to) {
Object.keys(from).forEach(function(k) {
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
Object.defineProperty(to, k, {
enumerable: true,
get: function() {
return from[k];
}
});
}
});
return from;
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "eventNextPlugins", {
enumerable: true,
get: function() {
return eventNextPlugins;
}
});
const _findup = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/find-up"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const EVENT_PLUGIN_PRESENT = "NEXT_PACKAGE_DETECTED";
async function eventNextPlugins(dir) {
try {
const packageJsonPath = await (0, _findup.default)("package.json", {
cwd: dir
});
if (!packageJsonPath) {
return [];
}
const { dependencies = {}, devDependencies = {} } = require(packageJsonPath);
const deps = {
...devDependencies,
...dependencies
};
return Object.keys(deps).reduce((events, plugin)=>{
const version = deps[plugin];
// Don't add deps without a version set
if (!version) {
return events;
}
events.push({
eventName: EVENT_PLUGIN_PRESENT,
payload: {
packageName: plugin,
packageVersion: version
}
});
return events;
}, []);
} catch (_) {
return [];
}
}
//# sourceMappingURL=plugins.js.map

View File

@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "eventSwcLoadFailure", {
enumerable: true,
get: function() {
return eventSwcLoadFailure;
}
});
const _shared = require("../../trace/shared");
const _packagejson = require("next/package.json");
const EVENT_PLUGIN_PRESENT = "NEXT_SWC_LOAD_FAILURE";
async function eventSwcLoadFailure(event) {
const telemetry = _shared.traceGlobals.get("telemetry");
// can't continue if telemetry isn't set
if (!telemetry) return;
let glibcVersion;
let installedSwcPackages;
try {
var _process_report;
// @ts-ignore
glibcVersion = (_process_report = process.report) == null ? void 0 : _process_report.getReport().header.glibcVersionRuntime;
} catch {}
try {
const pkgNames = Object.keys(_packagejson.optionalDependencies || {}).filter((pkg)=>pkg.startsWith("@next/swc"));
const installedPkgs = [];
for (const pkg of pkgNames){
try {
const { version } = require(`${pkg}/package.json`);
installedPkgs.push(`${pkg}@${version}`);
} catch {}
}
if (installedPkgs.length > 0) {
installedSwcPackages = installedPkgs.sort().join(",");
}
} catch {}
telemetry.record({
eventName: EVENT_PLUGIN_PRESENT,
payload: {
nextVersion: _packagejson.version,
glibcVersion,
installedSwcPackages,
arch: process.arch,
platform: process.platform,
nodeVersion: process.versions.node,
wasm: event == null ? void 0 : event.wasm,
nativeBindingsErrorCode: event == null ? void 0 : event.nativeBindingsErrorCode
}
});
// ensure this event is flushed before process exits
await telemetry.flush();
}
//# sourceMappingURL=swc-load-failure.js.map

View File

@@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "eventCliSession", {
enumerable: true,
get: function() {
return eventCliSession;
}
});
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const EVENT_VERSION = "NEXT_CLI_SESSION_STARTED";
function hasBabelConfig(dir) {
try {
var _res_options_presets, _res_options, _res_options_plugins, _res_options1;
const noopFile = _path.default.join(dir, "noop.js");
const res = require("next/dist/compiled/babel/core").loadPartialConfig({
cwd: dir,
filename: noopFile,
sourceFileName: noopFile
});
const isForTooling = ((_res_options = res.options) == null ? void 0 : (_res_options_presets = _res_options.presets) == null ? void 0 : _res_options_presets.every((e)=>{
var _e_file;
return (e == null ? void 0 : (_e_file = e.file) == null ? void 0 : _e_file.request) === "next/babel";
})) && ((_res_options1 = res.options) == null ? void 0 : (_res_options_plugins = _res_options1.plugins) == null ? void 0 : _res_options_plugins.length) === 0;
return res.hasFilesystemConfig() && !isForTooling;
} catch {
return false;
}
}
function eventCliSession(dir, nextConfig, event) {
var _nextConfig_experimental_staleTimes, _nextConfig_experimental_staleTimes1;
// This should be an invariant, if it fails our build tooling is broken.
if (typeof "14.2.5" !== "string") {
return [];
}
const { images, i18n } = nextConfig || {};
const payload = {
nextVersion: "14.2.5",
nodeVersion: process.version,
cliCommand: event.cliCommand,
isSrcDir: event.isSrcDir,
hasNowJson: event.hasNowJson,
isCustomServer: event.isCustomServer,
hasNextConfig: nextConfig.configOrigin !== "default",
buildTarget: "default",
hasWebpackConfig: typeof (nextConfig == null ? void 0 : nextConfig.webpack) === "function",
hasBabelConfig: hasBabelConfig(dir),
imageEnabled: !!images,
imageFutureEnabled: !!images,
basePathEnabled: !!(nextConfig == null ? void 0 : nextConfig.basePath),
i18nEnabled: !!i18n,
locales: (i18n == null ? void 0 : i18n.locales) ? i18n.locales.join(",") : null,
localeDomainsCount: (i18n == null ? void 0 : i18n.domains) ? i18n.domains.length : null,
localeDetectionEnabled: !i18n ? null : i18n.localeDetection !== false,
imageDomainsCount: (images == null ? void 0 : images.domains) ? images.domains.length : null,
imageRemotePatternsCount: (images == null ? void 0 : images.remotePatterns) ? images.remotePatterns.length : null,
imageSizes: (images == null ? void 0 : images.imageSizes) ? images.imageSizes.join(",") : null,
imageLoader: images == null ? void 0 : images.loader,
imageFormats: (images == null ? void 0 : images.formats) ? images.formats.join(",") : null,
nextConfigOutput: (nextConfig == null ? void 0 : nextConfig.output) || null,
trailingSlashEnabled: !!(nextConfig == null ? void 0 : nextConfig.trailingSlash),
reactStrictMode: !!(nextConfig == null ? void 0 : nextConfig.reactStrictMode),
webpackVersion: event.webpackVersion || null,
turboFlag: event.turboFlag || false,
appDir: event.appDir,
pagesDir: event.pagesDir,
staticStaleTime: ((_nextConfig_experimental_staleTimes = nextConfig.experimental.staleTimes) == null ? void 0 : _nextConfig_experimental_staleTimes.static) ?? null,
dynamicStaleTime: ((_nextConfig_experimental_staleTimes1 = nextConfig.experimental.staleTimes) == null ? void 0 : _nextConfig_experimental_staleTimes1.dynamic) ?? null
};
return [
{
eventName: EVENT_VERSION,
payload
}
];
}
//# sourceMappingURL=version.js.map

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "flushAndExit", {
enumerable: true,
get: function() {
return flushAndExit;
}
});
const _shared = require("../trace/shared");
async function flushAndExit(code) {
let telemetry = _shared.traceGlobals.get("telemetry");
if (telemetry) {
await telemetry.flush();
}
process.exit(code);
}
//# sourceMappingURL=flush-and-exit.js.map

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "_postPayload", {
enumerable: true,
get: function() {
return _postPayload;
}
});
const _asyncretry = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/async-retry"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _postPayload(endpoint, body, signal) {
if (!signal && "timeout" in AbortSignal) {
signal = AbortSignal.timeout(5000);
}
return (0, _asyncretry.default)(()=>fetch(endpoint, {
method: "POST",
body: JSON.stringify(body),
headers: {
"content-type": "application/json"
},
signal
}).then((res)=>{
if (!res.ok) {
const err = new Error(res.statusText);
err.response = res;
throw err;
}
}), {
minTimeout: 500,
retries: 1,
factor: 1
}).catch(()=>{
// We swallow errors when telemetry cannot be sent
})// Ensure promise is voided
.then(()=>{}, ()=>{});
}
//# sourceMappingURL=post-payload.js.map

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getRawProjectId", {
enumerable: true,
get: function() {
return getRawProjectId;
}
});
const _child_process = require("child_process");
// Q: Why does Next.js need a project ID? Why is it looking at my git remote?
// A:
// Next.js' telemetry is and always will be completely anonymous. Because of
// this, we need a way to differentiate different projects to track feature
// usage accurately. For example, to prevent a feature from appearing to be
// constantly `used` and then `unused` when switching between local projects.
// To reiterate,
// we **never** can read your actual git remote. The value is hashed one-way
// with random salt data, making it impossible for us to reverse or try to
// guess the remote by re-computing hashes.
async function _getProjectIdByGit() {
try {
let resolve, reject;
const promise = new Promise((res, rej)=>{
resolve = res;
reject = rej;
});
(0, _child_process.exec)(`git config --local --get remote.origin.url`, {
timeout: 1000,
windowsHide: true
}, (error, stdout)=>{
if (error) {
reject(error);
return;
}
resolve(stdout);
});
return String(await promise).trim();
} catch (_) {
return null;
}
}
async function getRawProjectId() {
return await _getProjectIdByGit() || process.env.REPOSITORY_URL || process.cwd();
}
//# sourceMappingURL=project-id.js.map

View File

@@ -0,0 +1,290 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Telemetry", {
enumerable: true,
get: function() {
return Telemetry;
}
});
const _picocolors = require("../lib/picocolors");
const _conf = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/conf"));
const _crypto = require("crypto");
const _isdocker = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/is-docker"));
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
const _anonymousmeta = require("./anonymous-meta");
const _ciinfo = /*#__PURE__*/ _interop_require_wildcard(require("./ci-info"));
const _postpayload = require("./post-payload");
const _projectid = require("./project-id");
const _ponyfill = require("next/dist/compiled/@edge-runtime/ponyfill");
const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && 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 = _ciinfo.isCI || (0, _isdocker.default)();
if (isLikelyEphemeral) {
return _path.default.join(distDir, "cache");
}
return undefined;
}
class Telemetry {
constructor({ distDir }){
this.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(`${(0, _picocolors.magenta)((0, _picocolors.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((0, _picocolors.cyan)("https://nextjs.org/telemetry"));
console.log();
};
this.setEnabled = (_enabled)=>{
const enabled = !!_enabled;
this.conf && this.conf.set(TELEMETRY_KEY_ENABLED, enabled);
return this.conf && this.conf.path;
};
this.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");
};
this.record = (_events, deferred)=>{
const prom = (deferred ? // flushDetached we can skip starting the initial
// submitRecord which will then be cancelled
new Promise((resolve)=>resolve({
isFulfilled: true,
isRejected: false,
value: _events
})) : this.submitRecord(_events)).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
if (!deferred) {
this.queue.delete(prom);
}
return res;
});
prom._events = Array.isArray(_events) ? _events : [
_events
];
prom._controller = prom._controller;
// Track this `Promise` so we can flush pending events
this.queue.add(prom);
return prom;
};
this.flush = async ()=>Promise.all(this.queue).catch(()=>null);
// writes current events to disk and spawns separate
// detached process to submit the records without blocking
// the main process from exiting
this.flushDetached = (mode, dir)=>{
const allEvents = [];
this.queue.forEach((item)=>{
try {
var _item__controller;
(_item__controller = item._controller) == null ? void 0 : _item__controller.abort();
allEvents.push(...item._events);
} catch (_) {
// if we fail to abort ignore this event
}
});
_fs.default.mkdirSync(this.distDir, {
recursive: true
});
_fs.default.writeFileSync(_path.default.join(this.distDir, "_events.json"), JSON.stringify(allEvents));
// Note: cross-spawn is not used here as it causes
// a new command window to appear when we don't want it to
const child_process = require("child_process");
// we use spawnSync when debugging to ensure logs are piped
// correctly to stdout/stderr
const spawn = this.NEXT_TELEMETRY_DEBUG ? child_process.spawnSync : child_process.spawn;
spawn(process.execPath, [
require.resolve("./detached-flush"),
mode,
dir
], {
detached: !this.NEXT_TELEMETRY_DEBUG,
windowsHide: true,
shell: false,
...this.NEXT_TELEMETRY_DEBUG ? {
stdio: "inherit"
} : {}
});
};
this.submitRecord = async (_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: await this.getProjectId(),
sessionId: this.sessionId
};
const meta = (0, _anonymousmeta.getAnonymousMeta)();
const postController = new _ponyfill.AbortController();
const res = (0, _postpayload._postPayload)(`https://telemetry.nextjs.org/api/v1/record`, {
context,
meta,
events: events.map(({ eventName, payload })=>({
eventName,
fields: payload
}))
}, postController.signal);
res._controller = postController;
return res;
};
// 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;
this.distDir = distDir;
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.queue = new Set();
this.notify();
}
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;
}
get isEnabled() {
return !this.NEXT_TELEMETRY_DISABLED && !!this.conf && this.conf.get(TELEMETRY_KEY_ENABLED, true) !== false;
}
async getProjectId() {
this.loadProjectId = this.loadProjectId || (0, _projectid.getRawProjectId)();
return this.oneWayHash(await this.loadProjectId);
}
}
//# sourceMappingURL=storage.js.map