@mintlify/cli 4.0.1084 → 4.0.1086

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/bin/cli.js CHANGED
@@ -16,9 +16,10 @@ import path from 'path';
16
16
  import yargs from 'yargs';
17
17
  import { hideBin } from 'yargs/helpers';
18
18
  import { accessibilityCheck } from './accessibilityCheck.js';
19
+ import { analyticsBuilder } from './analytics/index.js';
19
20
  import { setTelemetryEnabled } from './config.js';
20
- import { CMD_EXEC_PATH } from './constants.js';
21
- import { checkPort, checkNodeVersion, autoUpgradeIfNeeded, getVersions, suppressConsoleWarnings, terminate, } from './helpers.js';
21
+ import { getConfigValue, setConfigValue, clearConfigValue } from './config.js';
22
+ import { CMD_EXEC_PATH, checkPort, checkNodeVersion, autoUpgradeIfNeeded, getVersions, suppressConsoleWarnings, terminate, } from './helpers.js';
22
23
  import { init } from './init.js';
23
24
  import { login } from './login.js';
24
25
  import { logout } from './logout.js';
@@ -248,18 +249,71 @@ export const cli = ({ packageName = 'mint' }) => {
248
249
  }
249
250
  yield terminate(1);
250
251
  }))
251
- .command('status', false, () => undefined, () => __awaiter(void 0, void 0, void 0, function* () {
252
+ .command('status', 'View current authentication status', () => undefined, () => __awaiter(void 0, void 0, void 0, function* () {
252
253
  yield status();
253
254
  yield terminate(0);
254
255
  }))
255
- .command('logout', false, () => undefined, () => __awaiter(void 0, void 0, void 0, function* () {
256
+ .command('logout', 'logout of your mintlify account', () => undefined, () => __awaiter(void 0, void 0, void 0, function* () {
256
257
  yield logout();
257
258
  yield terminate(0);
258
259
  }))
259
- .command('login', false, () => undefined, () => __awaiter(void 0, void 0, void 0, function* () {
260
+ .command('login', 'authenticate your account to mintlify', () => undefined, () => __awaiter(void 0, void 0, void 0, function* () {
260
261
  yield login();
261
262
  yield terminate(0);
262
263
  }))
264
+ .command('config', 'manage CLI configuration', (yargs) => yargs
265
+ .command('set <key> <value>', 'set a configuration value', (yargs) => yargs
266
+ .positional('key', {
267
+ type: 'string',
268
+ demandOption: true,
269
+ description: 'Config key (e.g. subdomain)',
270
+ })
271
+ .positional('value', {
272
+ type: 'string',
273
+ demandOption: true,
274
+ description: 'Config value',
275
+ }), (argv) => __awaiter(void 0, void 0, void 0, function* () {
276
+ const validKeys = ['subdomain', 'dateFrom', 'dateTo'];
277
+ if (!validKeys.includes(argv.key)) {
278
+ addLog(_jsx(ErrorLog, { message: `Unknown config key: "${argv.key}". Valid keys: ${validKeys.join(', ')}` }));
279
+ yield terminate(1);
280
+ return;
281
+ }
282
+ yield setConfigValue(argv.key, argv.value);
283
+ addLog(_jsx(SuccessLog, { message: `${argv.key} = "${argv.value}"` }));
284
+ yield terminate(0);
285
+ }))
286
+ .command('get <key>', 'get a configuration value', (yargs) => yargs.positional('key', {
287
+ type: 'string',
288
+ demandOption: true,
289
+ description: 'Config key (e.g. subdomain, dateFrom, dateTo)',
290
+ }), (argv) => __awaiter(void 0, void 0, void 0, function* () {
291
+ const validKeys = ['subdomain', 'dateFrom', 'dateTo'];
292
+ if (!validKeys.includes(argv.key)) {
293
+ addLog(_jsx(ErrorLog, { message: `Unknown config key: "${argv.key}". Valid keys: ${validKeys.join(', ')}` }));
294
+ yield terminate(1);
295
+ return;
296
+ }
297
+ const val = getConfigValue(argv.key);
298
+ addLog(_jsx(Text, { children: val !== null && val !== void 0 ? val : 'not set' }));
299
+ yield terminate(0);
300
+ }))
301
+ .command('clear <key>', 'remove a configuration value', (yargs) => yargs.positional('key', {
302
+ type: 'string',
303
+ demandOption: true,
304
+ description: 'Config key (e.g. subdomain, dateFrom, dateTo)',
305
+ }), (argv) => __awaiter(void 0, void 0, void 0, function* () {
306
+ const validKeys = ['subdomain', 'dateFrom', 'dateTo'];
307
+ if (!validKeys.includes(argv.key)) {
308
+ addLog(_jsx(ErrorLog, { message: `Unknown config key: "${argv.key}". Valid keys: ${validKeys.join(', ')}` }));
309
+ yield terminate(1);
310
+ return;
311
+ }
312
+ yield clearConfigValue(argv.key);
313
+ addLog(_jsx(SuccessLog, { message: `${argv.key} cleared` }));
314
+ yield terminate(0);
315
+ }))
316
+ .demandCommand(1, 'specify a subcommand: set, get, or clear'))
263
317
  .command('update', 'update the CLI to the latest version', () => undefined, () => __awaiter(void 0, void 0, void 0, function* () {
264
318
  yield update({ packageName });
265
319
  yield terminate(0);
@@ -337,6 +391,7 @@ export const cli = ({ packageName = 'mint' }) => {
337
391
  yield terminate(1);
338
392
  }
339
393
  }))
394
+ .command('analytics', 'view analytics for your documentation', analyticsBuilder)
340
395
  // Print the help menu when the user enters an invalid command.
341
396
  .strictCommands()
342
397
  .demandCommand(1, 'unknown command. see above for the list of supported commands.')
package/bin/config.js CHANGED
@@ -40,3 +40,17 @@ export function setTelemetryEnabled(enabled) {
40
40
  yield writeConfig({ telemetryEnabled: enabled });
41
41
  });
42
42
  }
43
+ export function getConfigValue(key) {
44
+ const config = readConfig();
45
+ return config[key];
46
+ }
47
+ export function setConfigValue(key, value) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ yield writeConfig({ [key]: value });
50
+ });
51
+ }
52
+ export function clearConfigValue(key) {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ yield writeConfig({ [key]: undefined });
55
+ });
56
+ }
package/bin/constants.js CHANGED
@@ -1,11 +1,19 @@
1
- var _a;
1
+ var _a, _b;
2
+ import { LOCAL_LINKED_CLI_VERSION } from '@mintlify/previewing';
2
3
  import os from 'os';
3
4
  import path from 'path';
5
+ import { getCliVersion } from './helpers.js';
4
6
  export const HOME_DIR = os.homedir();
5
- export const CMD_EXEC_PATH = process.cwd();
6
7
  export const CONFIG_DIR = path.join(HOME_DIR, '.config', 'mintlify');
7
8
  export const CLI_CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
8
9
  export const TELEMETRY_ASYNC_TIMEOUT_MS = 10000;
9
- export const DASHBOARD_URL = (_a = process.env.MINTLIFY_DASHBOARD_URL) !== null && _a !== void 0 ? _a : 'http://localhost:3000';
10
- export const TOKEN_ENDPOINT = 'https://test.stytch.com/v1/public/project-test-2d86347b-dfdb-4609-be69-12d8146220bd/oauth2/token';
11
- export const STYTCH_CLIENT_ID = 'connected-app-test-b597afb3-304a-420f-bc13-dacca566c59f';
10
+ export const CALLBACK_PORT = 11582;
11
+ const IS_LOCAL_BUILD = process.env.CLI_TEST_MODE === 'true' ? true : getCliVersion() == LOCAL_LINKED_CLI_VERSION;
12
+ export const API_URL = (_a = process.env.MINTLIFY_API_URL) !== null && _a !== void 0 ? _a : (IS_LOCAL_BUILD ? 'http://localhost:5000' : 'https://leaves.mintlify.com');
13
+ export const DASHBOARD_URL = (_b = process.env.MINTLIFY_DASHBOARD_URL) !== null && _b !== void 0 ? _b : (IS_LOCAL_BUILD ? 'http://localhost:3000' : 'https://dashboard.mintlify.com');
14
+ const DEV_TOKEN_ENDPOINT = 'https://test.stytch.com/v1/public/project-test-2d86347b-dfdb-4609-be69-12d8146220bd/oauth2/token';
15
+ const DEV_STYTCH_CLIENT_ID = 'connected-app-test-b597afb3-304a-420f-bc13-dacca566c59f';
16
+ const PROD_TOKEN_ENDPOINT = 'https://api.stytch.com/v1/public/project-live-731b7a04-9ac3-4923-90b8-0806d4aa29d4/oauth2/token';
17
+ const PROD_STYTCH_CLIENT_ID = 'connected-app-live-d813eedd-dbb0-434b-a1f9-2ce69e5efc49';
18
+ export const TOKEN_ENDPOINT = IS_LOCAL_BUILD ? DEV_TOKEN_ENDPOINT : PROD_TOKEN_ENDPOINT;
19
+ export const STYTCH_CLIENT_ID = IS_LOCAL_BUILD ? DEV_STYTCH_CLIENT_ID : PROD_STYTCH_CLIENT_ID;
package/bin/helpers.js CHANGED
@@ -21,8 +21,8 @@ import { exec, execSync } from 'node:child_process';
21
21
  import { promisify } from 'node:util';
22
22
  import path from 'path';
23
23
  import yargs from 'yargs';
24
- import { CMD_EXEC_PATH } from './constants.js';
25
24
  import { shutdownPostHog } from './telemetry/client.js';
25
+ export const CMD_EXEC_PATH = process.cwd();
26
26
  export const checkPort = (argv) => __awaiter(void 0, void 0, void 0, function* () {
27
27
  const initialPort = typeof argv.port === 'number' ? argv.port : 3000;
28
28
  if (initialPort === (yield detect(initialPort)))
package/bin/keyring.js CHANGED
@@ -12,10 +12,13 @@ const ACCESS_TOKEN_ACCOUNT = 'access_token';
12
12
  const REFRESH_TOKEN_ACCOUNT = 'refresh_token';
13
13
  function getKeytar() {
14
14
  return __awaiter(this, void 0, void 0, function* () {
15
+ var _a;
15
16
  try {
16
- return yield import('keytar');
17
+ const mod = yield import('keytar');
18
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- ESM wraps CJS in { default: ... } at runtime despite types
19
+ return (_a = mod.default) !== null && _a !== void 0 ? _a : mod;
17
20
  }
18
- catch (_a) {
21
+ catch (_b) {
19
22
  throw new Error('keytar is required for credential storage but is not installed. Install it with: npm install keytar');
20
23
  }
21
24
  });
package/bin/login.js CHANGED
@@ -14,6 +14,7 @@ import chalk from 'chalk';
14
14
  import { Box, Text } from 'ink';
15
15
  import open from 'open';
16
16
  import { calculatePKCECodeChallenge, randomNonce, randomPKCECodeVerifier, randomState, } from 'openid-client';
17
+ import { startCallbackServer } from './callbackServer.js';
17
18
  import { DASHBOARD_URL, STYTCH_CLIENT_ID, TOKEN_ENDPOINT } from './constants.js';
18
19
  import { storeCredentials } from './keyring.js';
19
20
  export function login() {
@@ -28,12 +29,13 @@ export function login() {
28
29
  authorizeUrl.searchParams.set('state', state);
29
30
  authorizeUrl.searchParams.set('code_challenge', codeChallenge);
30
31
  const url = authorizeUrl.toString();
32
+ const { codePromise, close: closeServer } = yield startCallbackServer();
31
33
  addLog(_jsxs(Box, { flexDirection: "column", gap: 1, paddingY: 1, children: [_jsxs(Text, { bold: true, children: [_jsx(Text, { color: "green", children: "\u25C6 " }), "A browser window will open for Mintlify authentication"] }), _jsxs(Box, { flexDirection: "column", paddingLeft: 3, gap: 1, children: [_jsx(Text, { dimColor: true, children: "If your browser doesn't open automatically, copy this URL:" }), _jsx(Text, { color: "cyan", children: url })] })] }));
32
34
  open(url).catch(() => { });
33
35
  addLog(_jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "\u256D\u2500 Paste the authorization code from your browser" }), _jsx(Text, { dimColor: true, children: "\u2502" })] }));
34
36
  // Let ink finish rendering before inquirer takes over stdout
35
37
  yield new Promise((resolve) => setTimeout(resolve, 50));
36
- const code = yield input({
38
+ const inputPromise = input({
37
39
  message: '█',
38
40
  theme: {
39
41
  prefix: chalk.dim(' │'),
@@ -42,6 +44,18 @@ export function login() {
42
44
  },
43
45
  },
44
46
  });
47
+ let code;
48
+ try {
49
+ code = yield Promise.race([codePromise, inputPromise]);
50
+ }
51
+ catch (_c) {
52
+ closeServer();
53
+ inputPromise.cancel();
54
+ addLog(_jsx(Text, { color: "red", children: "\u2716 Login cancelled." }));
55
+ return;
56
+ }
57
+ closeServer();
58
+ inputPromise.cancel();
45
59
  const res = yield fetch(TOKEN_ENDPOINT, {
46
60
  method: 'POST',
47
61
  headers: { 'Content-Type': 'application/json' },
package/bin/status.js CHANGED
@@ -7,13 +7,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- var _a;
11
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
11
  import { addLog } from '@mintlify/previewing';
13
12
  import { Text } from 'ink';
14
13
  import { z } from 'zod';
14
+ import { API_URL } from './constants.js';
15
15
  import { getAccessToken } from './keyring.js';
16
- const API_URL = (_a = process.env.MINTLIFY_API_URL) !== null && _a !== void 0 ? _a : 'http://localhost:5000';
17
16
  const StatusResponseSchema = z.object({
18
17
  user: z.object({ email: z.string() }),
19
18
  org: z.object({ name: z.string() }),
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { PostHog } from 'posthog-node';
11
- import { TELEMETRY_ASYNC_TIMEOUT_MS } from '../constants.js';
11
+ const TELEMETRY_ASYNC_TIMEOUT_MS = 10000;
12
12
  const POSTHOG_API_KEY = 'phc_eNuN6Ojnk9O7uWfC17z12AK85fNR0BY6IiGVy0Gfwzw';
13
13
  const POSTHOG_HOST = 'https://ph.mintlify.com';
14
14
  let client = null;