@mintlify/cli 4.0.1067 → 4.0.1069
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__test__/telemetry.test.ts +313 -0
- package/__test__/utils.ts +11 -6
- package/bin/cli.js +23 -17
- package/bin/config.js +42 -0
- package/bin/constants.js +4 -0
- package/bin/helpers.js +15 -1
- package/bin/start.js +32 -1
- package/bin/telemetry/client.js +39 -0
- package/bin/telemetry/distinctId.js +62 -0
- package/bin/telemetry/middleware.js +39 -0
- package/bin/telemetry/track.js +65 -0
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/cli.tsx +23 -25
- package/src/config.ts +34 -0
- package/src/constants.ts +5 -0
- package/src/helpers.tsx +16 -0
- package/src/start.ts +22 -1
- package/src/telemetry/client.ts +31 -0
- package/src/telemetry/distinctId.ts +62 -0
- package/src/telemetry/middleware.ts +29 -0
- package/src/telemetry/track.ts +60 -0
- package/vitest.config.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1069",
|
|
4
4
|
"description": "The Mintlify CLI",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"inquirer": "12.3.0",
|
|
63
63
|
"js-yaml": "4.1.0",
|
|
64
64
|
"mdast-util-mdx-jsx": "3.2.0",
|
|
65
|
+
"posthog-node": "5.17.2",
|
|
65
66
|
"react": "19.2.3",
|
|
66
67
|
"semver": "7.7.2",
|
|
67
68
|
"unist-util-visit": "5.0.0",
|
|
@@ -87,5 +88,5 @@
|
|
|
87
88
|
"vitest": "2.1.9",
|
|
88
89
|
"vitest-mock-process": "1.0.4"
|
|
89
90
|
},
|
|
90
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "10c9be1d7e8d3ccf3f86df9498a1e334090b401e"
|
|
91
92
|
}
|
package/src/cli.tsx
CHANGED
|
@@ -24,12 +24,11 @@ import yargs from 'yargs';
|
|
|
24
24
|
import { hideBin } from 'yargs/helpers';
|
|
25
25
|
|
|
26
26
|
import { accessibilityCheck } from './accessibilityCheck.js';
|
|
27
|
+
import { setTelemetryEnabled } from './config.js';
|
|
27
28
|
import {
|
|
28
29
|
checkPort,
|
|
29
|
-
checkForMintJson,
|
|
30
30
|
checkNodeVersion,
|
|
31
|
-
|
|
32
|
-
checkForDocsJson,
|
|
31
|
+
autoUpgradeIfNeeded,
|
|
33
32
|
getVersions,
|
|
34
33
|
suppressConsoleWarnings,
|
|
35
34
|
terminate,
|
|
@@ -39,17 +38,34 @@ import { init } from './init.js';
|
|
|
39
38
|
import { mdxLinter } from './mdxLinter.js';
|
|
40
39
|
import { migrateMdx } from './migrateMdx.js';
|
|
41
40
|
import { scrapeSite, scrapePage, scrapeOpenApi } from './scrape.js';
|
|
41
|
+
import { createTelemetryMiddleware } from './telemetry/middleware.js';
|
|
42
|
+
import { trackTelemetryPreferenceChange } from './telemetry/track.js';
|
|
42
43
|
import { update } from './update.js';
|
|
43
44
|
import { addWorkflow } from './workflow.js';
|
|
44
45
|
|
|
45
46
|
export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
47
|
+
const telemetryMiddleware = createTelemetryMiddleware();
|
|
46
48
|
render(<Logs />);
|
|
47
49
|
|
|
48
50
|
return (
|
|
49
51
|
yargs(hideBin(process.argv))
|
|
50
52
|
.scriptName(packageName)
|
|
53
|
+
.option('telemetry', {
|
|
54
|
+
type: 'boolean',
|
|
55
|
+
alias: 't',
|
|
56
|
+
description: 'Enable or disable anonymous usage telemetry',
|
|
57
|
+
})
|
|
58
|
+
.middleware(async (argv) => {
|
|
59
|
+
if (argv.telemetry !== undefined && argv._.length === 0) {
|
|
60
|
+
await setTelemetryEnabled(argv.telemetry);
|
|
61
|
+
await trackTelemetryPreferenceChange({ enabled: argv.telemetry });
|
|
62
|
+
addLog(<SuccessLog message={`telemetry ${argv.telemetry ? 'enabled' : 'disabled'}`} />);
|
|
63
|
+
await terminate(0);
|
|
64
|
+
}
|
|
65
|
+
}, true)
|
|
51
66
|
.middleware(checkNodeVersion)
|
|
52
67
|
.middleware(suppressConsoleWarnings)
|
|
68
|
+
.middleware(telemetryMiddleware)
|
|
53
69
|
.command(
|
|
54
70
|
'dev',
|
|
55
71
|
'initialize a local preview environment',
|
|
@@ -91,6 +107,7 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
91
107
|
.example('mintlify dev', 'run with default settings (opens in browser)')
|
|
92
108
|
.example('mintlify dev --no-open', 'run without opening in browser'),
|
|
93
109
|
async (argv) => {
|
|
110
|
+
await autoUpgradeIfNeeded();
|
|
94
111
|
const port = await checkPort(argv);
|
|
95
112
|
const { cli: cliVersion } = getVersions();
|
|
96
113
|
if (port != undefined) {
|
|
@@ -255,11 +272,7 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
255
272
|
description: 'also check links inside <Snippet> components',
|
|
256
273
|
}),
|
|
257
274
|
async (argv) => {
|
|
258
|
-
|
|
259
|
-
if (!hasMintJson) {
|
|
260
|
-
await checkForDocsJson();
|
|
261
|
-
}
|
|
262
|
-
|
|
275
|
+
await autoUpgradeIfNeeded();
|
|
263
276
|
addLog(<SpinnerLog message="checking for broken links..." />);
|
|
264
277
|
try {
|
|
265
278
|
const graph = await buildGraph(undefined, {
|
|
@@ -337,10 +350,7 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
337
350
|
})
|
|
338
351
|
.epilog('example: `mintlify rename introduction.mdx overview.mdx`'),
|
|
339
352
|
async ({ from, to, force }) => {
|
|
340
|
-
|
|
341
|
-
if (!hasMintJson) {
|
|
342
|
-
await checkForDocsJson();
|
|
343
|
-
}
|
|
353
|
+
await autoUpgradeIfNeeded();
|
|
344
354
|
await renameFilesAndUpdateLinksInContent(from, to, force);
|
|
345
355
|
await terminate(0);
|
|
346
356
|
}
|
|
@@ -354,18 +364,6 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
354
364
|
await terminate(0);
|
|
355
365
|
}
|
|
356
366
|
)
|
|
357
|
-
.command(
|
|
358
|
-
'upgrade',
|
|
359
|
-
'upgrade mint.json file to docs.json (current format)',
|
|
360
|
-
() => undefined,
|
|
361
|
-
async () => {
|
|
362
|
-
const hasMintJson = await checkForMintJson();
|
|
363
|
-
if (!hasMintJson) {
|
|
364
|
-
await checkForDocsJson();
|
|
365
|
-
}
|
|
366
|
-
await upgradeConfig();
|
|
367
|
-
}
|
|
368
|
-
)
|
|
369
367
|
.command(
|
|
370
368
|
'migrate-mdx',
|
|
371
369
|
'migrate mdx openapi endpoint pages to x-mint extensions and docs.json',
|
|
@@ -571,6 +569,6 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
|
|
|
571
569
|
.alias('h', 'help')
|
|
572
570
|
.alias('v', 'version')
|
|
573
571
|
|
|
574
|
-
.
|
|
572
|
+
.parseAsync()
|
|
575
573
|
);
|
|
576
574
|
};
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { ensureDir } from 'fs-extra';
|
|
3
|
+
|
|
4
|
+
import { CLI_CONFIG_FILE, CONFIG_DIR } from './constants.js';
|
|
5
|
+
|
|
6
|
+
interface MintlifyConfig {
|
|
7
|
+
telemetryEnabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function readConfig(): MintlifyConfig {
|
|
11
|
+
try {
|
|
12
|
+
const raw = fs.readFileSync(CLI_CONFIG_FILE, 'utf-8');
|
|
13
|
+
return JSON.parse(raw) as MintlifyConfig;
|
|
14
|
+
} catch {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function writeConfig(updates: Partial<MintlifyConfig>): Promise<void> {
|
|
20
|
+
await ensureDir(CONFIG_DIR);
|
|
21
|
+
const existing = readConfig();
|
|
22
|
+
fs.writeFileSync(CLI_CONFIG_FILE, JSON.stringify({ ...existing, ...updates }, null, 2));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isTelemetryEnabled(): boolean {
|
|
26
|
+
if (process.env.CLI_TEST_MODE === 'true') return false;
|
|
27
|
+
if (process.env.MINTLIFY_TELEMETRY_DISABLED === '1') return false;
|
|
28
|
+
if (process.env.DO_NOT_TRACK === '1') return false;
|
|
29
|
+
return readConfig().telemetryEnabled !== false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function setTelemetryEnabled(enabled: boolean): Promise<void> {
|
|
33
|
+
await writeConfig({ telemetryEnabled: enabled });
|
|
34
|
+
}
|
package/src/constants.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
|
|
3
4
|
export const HOME_DIR = os.homedir();
|
|
4
5
|
export const CMD_EXEC_PATH = process.cwd();
|
|
6
|
+
|
|
7
|
+
export const CONFIG_DIR = path.join(HOME_DIR, '.config', 'mintlify');
|
|
8
|
+
export const CLI_CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
9
|
+
export const TELEMETRY_ASYNC_TIMEOUT_MS = 10_000;
|
package/src/helpers.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
SpinnerLog,
|
|
10
10
|
removeLastLog,
|
|
11
11
|
LOCAL_LINKED_CLI_VERSION,
|
|
12
|
+
WarningLog,
|
|
12
13
|
} from '@mintlify/previewing';
|
|
13
14
|
import { upgradeToDocsConfig, validatePathWithinCwd } from '@mintlify/validation';
|
|
14
15
|
import detect from 'detect-port';
|
|
@@ -23,6 +24,7 @@ import type { ArgumentsCamelCase } from 'yargs';
|
|
|
23
24
|
import yargs from 'yargs';
|
|
24
25
|
|
|
25
26
|
import { CMD_EXEC_PATH } from './constants.js';
|
|
27
|
+
import { shutdownPostHog } from './telemetry/client.js';
|
|
26
28
|
|
|
27
29
|
export const checkPort = async (argv: ArgumentsCamelCase): Promise<number | undefined> => {
|
|
28
30
|
const initialPort = typeof argv.port === 'number' ? argv.port : 3000;
|
|
@@ -93,6 +95,19 @@ export const checkForDocsJson = async () => {
|
|
|
93
95
|
}
|
|
94
96
|
};
|
|
95
97
|
|
|
98
|
+
export const autoUpgradeIfNeeded = async () => {
|
|
99
|
+
const hasMintJson = await checkForMintJson();
|
|
100
|
+
if (!hasMintJson) return;
|
|
101
|
+
|
|
102
|
+
const docsJsonPath = path.join(CMD_EXEC_PATH, 'docs.json');
|
|
103
|
+
const hasDocsJson = await fse.pathExists(docsJsonPath);
|
|
104
|
+
if (!hasDocsJson) {
|
|
105
|
+
addLog(<WarningLog message="Legacy mint.json detected, auto-upgrading to docs.json" />);
|
|
106
|
+
addLog(<SpinnerLog message="upgrading mint.json to docs.json..." />);
|
|
107
|
+
await upgradeConfig();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
96
111
|
export const upgradeConfig = async () => {
|
|
97
112
|
try {
|
|
98
113
|
const mintJsonPath = path.join(CMD_EXEC_PATH, 'mint.json');
|
|
@@ -183,6 +198,7 @@ export const readLocalOpenApiFile = async (
|
|
|
183
198
|
export const terminate = async (code: number) => {
|
|
184
199
|
// Wait for the logs to be fully rendered before exiting
|
|
185
200
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
201
|
+
await shutdownPostHog();
|
|
186
202
|
process.exit(code);
|
|
187
203
|
};
|
|
188
204
|
|
package/src/start.ts
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { cli } from './cli.js';
|
|
3
|
+
import { shutdownPostHog } from './telemetry/client.js';
|
|
3
4
|
|
|
4
5
|
const packageName = process.env.MINTLIFY_PACKAGE_NAME ?? 'mint';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
cli({ packageName }).catch((err: unknown) => {
|
|
8
|
+
console.error(err instanceof Error ? err.message : err);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
async function shutdown(exitCode: number): Promise<never> {
|
|
13
|
+
await shutdownPostHog();
|
|
14
|
+
process.exit(exitCode);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
process.once('beforeExit', async () => {
|
|
18
|
+
try {
|
|
19
|
+
await shutdownPostHog();
|
|
20
|
+
} catch {}
|
|
21
|
+
});
|
|
22
|
+
process.on('SIGINT', () => {
|
|
23
|
+
void shutdown(130);
|
|
24
|
+
});
|
|
25
|
+
process.on('SIGTERM', () => {
|
|
26
|
+
void shutdown(143);
|
|
27
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PostHog } from 'posthog-node';
|
|
2
|
+
|
|
3
|
+
import { TELEMETRY_ASYNC_TIMEOUT_MS } from '../constants.js';
|
|
4
|
+
|
|
5
|
+
const POSTHOG_API_KEY = 'phc_eNuN6Ojnk9O7uWfC17z12AK85fNR0BY6IiGVy0Gfwzw';
|
|
6
|
+
const POSTHOG_HOST = 'https://ph.mintlify.com';
|
|
7
|
+
|
|
8
|
+
let client: PostHog | null = null;
|
|
9
|
+
|
|
10
|
+
export function getPostHogClient(): PostHog {
|
|
11
|
+
if (!client) {
|
|
12
|
+
client = new PostHog(POSTHOG_API_KEY, {
|
|
13
|
+
host: POSTHOG_HOST,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return client;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function shutdownPostHog(): Promise<void> {
|
|
20
|
+
if (!client) return;
|
|
21
|
+
try {
|
|
22
|
+
await Promise.race([
|
|
23
|
+
client.shutdown(),
|
|
24
|
+
new Promise<void>((resolve) => {
|
|
25
|
+
const t = setTimeout(resolve, TELEMETRY_ASYNC_TIMEOUT_MS);
|
|
26
|
+
t.unref();
|
|
27
|
+
}),
|
|
28
|
+
]);
|
|
29
|
+
} catch {}
|
|
30
|
+
client = null;
|
|
31
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
|
|
6
|
+
import { CONFIG_DIR } from '../constants.js';
|
|
7
|
+
|
|
8
|
+
const ID_FILE = path.join(CONFIG_DIR, 'anonymous-id');
|
|
9
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
10
|
+
|
|
11
|
+
function readValidIdFromFile(): string | null {
|
|
12
|
+
try {
|
|
13
|
+
const raw = fs.readFileSync(ID_FILE, 'utf-8').trim();
|
|
14
|
+
if (UUID_RE.test(raw)) return raw;
|
|
15
|
+
} catch {}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function stableMachineDistinctId(): string {
|
|
20
|
+
const h = crypto.createHash('sha256');
|
|
21
|
+
h.update(os.hostname());
|
|
22
|
+
h.update('\0');
|
|
23
|
+
h.update(os.homedir());
|
|
24
|
+
h.update('\0');
|
|
25
|
+
h.update(process.env.USER ?? process.env.USERNAME ?? '');
|
|
26
|
+
const hex = h.digest('hex').slice(0, 32);
|
|
27
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function tryPersistId(id: string): void {
|
|
31
|
+
fs.mkdirSync(path.dirname(ID_FILE), { recursive: true });
|
|
32
|
+
fs.writeFileSync(ID_FILE, id, { flag: 'wx' });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getDistinctId(): string {
|
|
36
|
+
const existing = readValidIdFromFile();
|
|
37
|
+
if (existing) return existing;
|
|
38
|
+
|
|
39
|
+
const randomId = crypto.randomUUID();
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
tryPersistId(randomId);
|
|
43
|
+
return readValidIdFromFile() ?? randomId;
|
|
44
|
+
} catch (err) {
|
|
45
|
+
const code = (err as NodeJS.ErrnoException).code;
|
|
46
|
+
if (code === 'EEXIST') {
|
|
47
|
+
const concurrent = readValidIdFromFile();
|
|
48
|
+
if (concurrent) return concurrent;
|
|
49
|
+
try {
|
|
50
|
+
fs.writeFileSync(ID_FILE, randomId);
|
|
51
|
+
} catch {}
|
|
52
|
+
return readValidIdFromFile() ?? randomId;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const stable = stableMachineDistinctId();
|
|
57
|
+
try {
|
|
58
|
+
fs.mkdirSync(path.dirname(ID_FILE), { recursive: true });
|
|
59
|
+
fs.writeFileSync(ID_FILE, stable);
|
|
60
|
+
} catch {}
|
|
61
|
+
return readValidIdFromFile() ?? stable;
|
|
62
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getVersions } from '../helpers.js';
|
|
2
|
+
import { trackCommand } from './track.js';
|
|
3
|
+
|
|
4
|
+
const SCRAPE_SUBCOMMANDS = new Set(['page', 'site', 'openapi']);
|
|
5
|
+
|
|
6
|
+
export function getSanitizedCommandForTelemetry(_: (string | number)[]): string {
|
|
7
|
+
const parts = _.filter((p): p is string => typeof p === 'string');
|
|
8
|
+
if (parts.length === 0) return '';
|
|
9
|
+
const first = parts[0]!;
|
|
10
|
+
const second = parts[1];
|
|
11
|
+
if (first === 'scrape' && second !== undefined && SCRAPE_SUBCOMMANDS.has(second)) {
|
|
12
|
+
return `scrape ${second}`;
|
|
13
|
+
}
|
|
14
|
+
return first;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createTelemetryMiddleware(): (argv: { _: (string | number)[] }) => Promise<void> {
|
|
18
|
+
let tracked = false;
|
|
19
|
+
return async function telemetryMiddleware(argv: { _: (string | number)[] }): Promise<void> {
|
|
20
|
+
const command = argv._[0];
|
|
21
|
+
if (typeof command === 'string') {
|
|
22
|
+
if (tracked) return;
|
|
23
|
+
tracked = true;
|
|
24
|
+
const sanitizedCommand = getSanitizedCommandForTelemetry(argv._);
|
|
25
|
+
const { cli: cliVersion } = getVersions();
|
|
26
|
+
void trackCommand({ command: sanitizedCommand, cliVersion });
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
|
|
3
|
+
import { isTelemetryEnabled } from '../config.js';
|
|
4
|
+
import { TELEMETRY_ASYNC_TIMEOUT_MS } from '../constants.js';
|
|
5
|
+
import { getVersions } from '../helpers.js';
|
|
6
|
+
import { getPostHogClient } from './client.js';
|
|
7
|
+
import { getDistinctId } from './distinctId.js';
|
|
8
|
+
|
|
9
|
+
export interface TrackCommandOptions {
|
|
10
|
+
command: string;
|
|
11
|
+
cliVersion?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function captureWithTimeout(
|
|
15
|
+
event: string,
|
|
16
|
+
properties: Record<string, unknown>
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
await Promise.race([
|
|
19
|
+
getPostHogClient()
|
|
20
|
+
.captureImmediate({
|
|
21
|
+
distinctId: getDistinctId(),
|
|
22
|
+
event,
|
|
23
|
+
properties,
|
|
24
|
+
})
|
|
25
|
+
.catch(() => {}),
|
|
26
|
+
new Promise<void>((resolve) => {
|
|
27
|
+
const t = setTimeout(resolve, TELEMETRY_ASYNC_TIMEOUT_MS);
|
|
28
|
+
t.unref();
|
|
29
|
+
}),
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function trackCommand({ command, cliVersion }: TrackCommandOptions): Promise<void> {
|
|
34
|
+
if (!isTelemetryEnabled()) return;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
await captureWithTimeout('cli.command.executed', {
|
|
38
|
+
command,
|
|
39
|
+
cli_version: cliVersion,
|
|
40
|
+
os: os.platform(),
|
|
41
|
+
arch: os.arch(),
|
|
42
|
+
node_version: process.version,
|
|
43
|
+
});
|
|
44
|
+
} catch {}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function trackTelemetryPreferenceChange(options: { enabled: boolean }): Promise<void> {
|
|
48
|
+
if (process.env.CLI_TEST_MODE === 'true') return;
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const { cli: cliVersion } = getVersions();
|
|
52
|
+
await captureWithTimeout('cli.telemetry.preference_changed', {
|
|
53
|
+
enabled: options.enabled,
|
|
54
|
+
cli_version: cliVersion,
|
|
55
|
+
os: os.platform(),
|
|
56
|
+
arch: os.arch(),
|
|
57
|
+
node_version: process.version,
|
|
58
|
+
});
|
|
59
|
+
} catch {}
|
|
60
|
+
}
|