@mintlify/cli 4.0.1085 → 4.0.1087

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.
@@ -27,7 +27,7 @@ vi.mock('fs-extra', () => ({
27
27
  },
28
28
  }));
29
29
 
30
- vi.mock('../src/constants.js', () => ({
30
+ vi.mock('../src/helpers.js', () => ({
31
31
  CMD_EXEC_PATH: '/fake/project',
32
32
  }));
33
33
 
@@ -13,8 +13,7 @@ import { getConfigObj, getConfigPath } from '@mintlify/prebuild';
13
13
  import { addLog, ErrorLog, WarningLog } from '@mintlify/previewing';
14
14
  import { Text } from 'ink';
15
15
  import { checkDocsColors } from './accessibility.js';
16
- import { CMD_EXEC_PATH } from './constants.js';
17
- import { checkForDocsJson } from './helpers.js';
16
+ import { CMD_EXEC_PATH, checkForDocsJson } from './helpers.js';
18
17
  export const accessibilityCheck = () => __awaiter(void 0, void 0, void 0, function* () {
19
18
  try {
20
19
  yield checkForDocsJson();
@@ -7,8 +7,7 @@ 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
- const API_BASE = (_a = process.env.MINTLIFY_API_URL) !== null && _a !== void 0 ? _a : 'http://localhost:5000';
10
+ import { API_URL } from '../constants.js';
12
11
  function getAuthHeaders() {
13
12
  return __awaiter(this, void 0, void 0, function* () {
14
13
  try {
@@ -28,7 +27,7 @@ function getAuthHeaders() {
28
27
  }
29
28
  function request(path_1) {
30
29
  return __awaiter(this, arguments, void 0, function* (path, params = {}) {
31
- const url = new URL(`${API_BASE}/api/cli/analytics${path}`);
30
+ const url = new URL(`${API_URL}/api/cli/analytics${path}`);
32
31
  for (const [key, value] of Object.entries(params)) {
33
32
  if (value !== undefined)
34
33
  url.searchParams.set(key, String(value));
@@ -0,0 +1,65 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { CALLBACK_PORT, DASHBOARD_URL } from './constants.js';
11
+ export function startCallbackServer() {
12
+ return __awaiter(this, void 0, void 0, function* () {
13
+ const { default: http } = yield import('http');
14
+ let resolveCode;
15
+ let rejectCode;
16
+ let closed = false;
17
+ const codePromise = new Promise((res, rej) => {
18
+ resolveCode = res;
19
+ rejectCode = rej;
20
+ });
21
+ const server = http.createServer((req, res) => {
22
+ res.setHeader('Access-Control-Allow-Origin', DASHBOARD_URL);
23
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
24
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
25
+ if (req.method === 'OPTIONS') {
26
+ res.writeHead(204);
27
+ res.end();
28
+ return;
29
+ }
30
+ if (req.method === 'POST') {
31
+ let body = '';
32
+ req.on('data', (chunk) => {
33
+ body += chunk;
34
+ });
35
+ req.on('end', () => {
36
+ try {
37
+ const { code } = JSON.parse(body);
38
+ res.writeHead(200, { 'Content-Type': 'application/json' });
39
+ res.end(JSON.stringify({ ok: true }));
40
+ closed = true;
41
+ server.close();
42
+ resolveCode(code);
43
+ }
44
+ catch (_a) {
45
+ res.writeHead(400);
46
+ res.end(JSON.stringify({ error: 'invalid body' }));
47
+ }
48
+ });
49
+ }
50
+ else {
51
+ res.writeHead(405);
52
+ res.end();
53
+ }
54
+ });
55
+ server.listen(CALLBACK_PORT, 'localhost');
56
+ const close = () => {
57
+ if (!closed) {
58
+ closed = true;
59
+ server.close();
60
+ rejectCode(new Error('Login cancelled'));
61
+ }
62
+ };
63
+ return { codePromise, close };
64
+ });
65
+ }
package/bin/cli.js CHANGED
@@ -19,8 +19,7 @@ import { accessibilityCheck } from './accessibilityCheck.js';
19
19
  import { analyticsBuilder } from './analytics/index.js';
20
20
  import { setTelemetryEnabled } from './config.js';
21
21
  import { getConfigValue, setConfigValue, clearConfigValue } from './config.js';
22
- import { CMD_EXEC_PATH } from './constants.js';
23
- import { checkPort, checkNodeVersion, autoUpgradeIfNeeded, getVersions, suppressConsoleWarnings, terminate, } from './helpers.js';
22
+ import { CMD_EXEC_PATH, checkPort, checkNodeVersion, autoUpgradeIfNeeded, getVersions, suppressConsoleWarnings, terminate, } from './helpers.js';
24
23
  import { init } from './init.js';
25
24
  import { login } from './login.js';
26
25
  import { logout } from './logout.js';
@@ -250,15 +249,15 @@ export const cli = ({ packageName = 'mint' }) => {
250
249
  }
251
250
  yield terminate(1);
252
251
  }))
253
- .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* () {
254
253
  yield status();
255
254
  yield terminate(0);
256
255
  }))
257
- .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* () {
258
257
  yield logout();
259
258
  yield terminate(0);
260
259
  }))
261
- .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* () {
262
261
  yield login();
263
262
  yield terminate(0);
264
263
  }))
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/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;