@tanstack/cli
Version:
TanStack CLI
141 lines (140 loc) • 4.23 kB
JavaScript
import { randomUUID } from 'node:crypto';
import { existsSync } from 'node:fs';
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { homedir } from 'node:os';
import { dirname, join } from 'node:path';
export const TELEMETRY_NOTICE_VERSION = 1;
function createDefaultTelemetryConfig() {
return {
distinctId: randomUUID(),
enabled: true,
noticeVersion: 0,
};
}
function getHomeDirectory() {
return process.env.HOME || homedir();
}
function isTelemetryConfig(value) {
if (!value || typeof value !== 'object') {
return false;
}
const record = value;
return (typeof record.distinctId === 'string' &&
typeof record.enabled === 'boolean' &&
typeof record.noticeVersion === 'number');
}
function getDisabledByEnvironment() {
if (process.env.DO_NOT_TRACK === '1') {
return 'env';
}
if (process.env.TANSTACK_CLI_TELEMETRY_DISABLED === '1') {
return 'env';
}
if (process.env.CI) {
return 'ci';
}
return undefined;
}
export function getTelemetryConfigPath() {
const xdgConfigHome = process.env.XDG_CONFIG_HOME?.trim();
if (xdgConfigHome) {
return join(xdgConfigHome, 'tanstack', 'cli.json');
}
const homeDirectory = getHomeDirectory().trim();
if (homeDirectory) {
return join(homeDirectory, '.config', 'tanstack', 'cli.json');
}
return join(process.cwd(), '.tanstack', 'cli.json');
}
async function readTelemetryConfigFile(configPath) {
if (!existsSync(configPath)) {
return undefined;
}
try {
const raw = await readFile(configPath, 'utf8');
const parsed = JSON.parse(raw);
if (!isTelemetryConfig(parsed)) {
return undefined;
}
return parsed;
}
catch {
return undefined;
}
}
async function writeTelemetryConfigFile(configPath, config) {
await mkdir(dirname(configPath), { recursive: true });
await writeFile(configPath, JSON.stringify(config, null, 2));
}
async function readOrCreateTelemetryConfig(createIfMissing) {
const configPath = getTelemetryConfigPath();
const existingConfig = await readTelemetryConfigFile(configPath);
if (existingConfig || !createIfMissing) {
return {
config: existingConfig,
configPath,
};
}
const createdConfig = createDefaultTelemetryConfig();
await writeTelemetryConfigFile(configPath, createdConfig);
return {
config: createdConfig,
configPath,
};
}
export async function getTelemetryStatus(opts) {
const disabledBy = getDisabledByEnvironment();
const { config, configPath } = await readOrCreateTelemetryConfig(opts?.createIfMissing ?? !disabledBy);
if (!config) {
return {
configPath,
disabledBy,
distinctId: undefined,
enabled: false,
noticeVersion: 0,
};
}
if (disabledBy) {
return {
configPath,
disabledBy,
distinctId: config.distinctId,
enabled: false,
noticeVersion: config.noticeVersion,
};
}
if (!config.enabled) {
return {
configPath,
disabledBy: 'config',
distinctId: config.distinctId,
enabled: false,
noticeVersion: config.noticeVersion,
};
}
return {
configPath,
distinctId: config.distinctId,
enabled: true,
noticeVersion: config.noticeVersion,
};
}
export async function markTelemetryNoticeSeen() {
const { config, configPath } = await readOrCreateTelemetryConfig(true);
if (!config || config.noticeVersion >= TELEMETRY_NOTICE_VERSION) {
return;
}
await writeTelemetryConfigFile(configPath, {
...config,
noticeVersion: TELEMETRY_NOTICE_VERSION,
});
}
export async function setTelemetryEnabled(enabled) {
const { config, configPath } = await readOrCreateTelemetryConfig(true);
const nextConfig = {
...(config || createDefaultTelemetryConfig()),
enabled,
};
await writeTelemetryConfigFile(configPath, nextConfig);
return nextConfig;
}