@mintlify/cli 4.0.1792 → 4.0.1794
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__/feedback.test.ts +42 -0
- package/bin/cli.js +26 -0
- package/bin/feedback.js +41 -0
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/cli.tsx +37 -0
- package/src/feedback.tsx +36 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { authenticatedFetch } from '../src/authenticatedFetch.js';
|
|
4
|
+
import { API_URL } from '../src/constants.js';
|
|
5
|
+
import { sendFeedback } from '../src/feedback.js';
|
|
6
|
+
|
|
7
|
+
vi.mock('../src/authenticatedFetch.js');
|
|
8
|
+
|
|
9
|
+
const input = { message: 'mint dev crashed', clientId: 'c1', category: 'bug' as const };
|
|
10
|
+
const respond = (status: number) =>
|
|
11
|
+
vi.mocked(authenticatedFetch).mockResolvedValue(new Response('{}', { status }));
|
|
12
|
+
|
|
13
|
+
beforeEach(() => vi.resetAllMocks());
|
|
14
|
+
|
|
15
|
+
describe('mint feedback', () => {
|
|
16
|
+
it('posts the feedback with the cli source', async () => {
|
|
17
|
+
respond(201);
|
|
18
|
+
expect(await sendFeedback(input)).toBeUndefined();
|
|
19
|
+
const [url, init] = vi.mocked(authenticatedFetch).mock.calls[0]!;
|
|
20
|
+
expect(url).toBe(`${API_URL}/api/cli/feedback`);
|
|
21
|
+
expect(init?.method).toBe('POST');
|
|
22
|
+
expect(JSON.parse(String(init?.body))).toEqual({ ...input, source: 'cli' });
|
|
23
|
+
});
|
|
24
|
+
it('asks for login on 401', async () => {
|
|
25
|
+
respond(401);
|
|
26
|
+
expect(await sendFeedback(input)).toContain('mint login');
|
|
27
|
+
});
|
|
28
|
+
it('asks for login when no credentials are stored', async () => {
|
|
29
|
+
vi.mocked(authenticatedFetch).mockRejectedValue(
|
|
30
|
+
new Error('Not authenticated. Run `mint login` to authenticate.')
|
|
31
|
+
);
|
|
32
|
+
expect(await sendFeedback(input)).toContain('mint login');
|
|
33
|
+
});
|
|
34
|
+
it('reports a network failure', async () => {
|
|
35
|
+
vi.mocked(authenticatedFetch).mockRejectedValue(new Error('fetch failed'));
|
|
36
|
+
expect(await sendFeedback(input)).toBe('could not reach the server');
|
|
37
|
+
});
|
|
38
|
+
it('reports a server error', async () => {
|
|
39
|
+
respond(400);
|
|
40
|
+
expect(await sendFeedback(input)).toBe('could not send feedback (HTTP 400)');
|
|
41
|
+
});
|
|
42
|
+
});
|
package/bin/cli.js
CHANGED
|
@@ -27,6 +27,7 @@ import { deployFromGithubActions, isGithubActions } from './deploy-github-action
|
|
|
27
27
|
import { formatGithubSetup, setupGithubDeployment } from './deploy-github-setup.js';
|
|
28
28
|
import { DEPLOY_HELP, deploymentInstructions } from './deploy-instructions.js';
|
|
29
29
|
import { formatDeployment, prepareAgentDeployment } from './deploy.js';
|
|
30
|
+
import { FEEDBACK_CATEGORIES, feedback } from './feedback.js';
|
|
30
31
|
import { formatHandler } from './format.js';
|
|
31
32
|
import { checkPort, checkNodeVersion, autoUpgradeIfNeeded, getVersions, isAI, suppressConsoleWarnings, terminate, } from './helpers.js';
|
|
32
33
|
import { init } from './init.js';
|
|
@@ -542,6 +543,31 @@ export const cli = ({ packageName = 'mint' }) => {
|
|
|
542
543
|
}), (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
543
544
|
yield addDomain(argv.domain, argv.basePath);
|
|
544
545
|
yield terminate(0);
|
|
546
|
+
}))
|
|
547
|
+
.command('feedback <message>', 'Send feedback to the Mintlify team', (yargs) => yargs
|
|
548
|
+
.positional('message', {
|
|
549
|
+
type: 'string',
|
|
550
|
+
demandOption: true,
|
|
551
|
+
description: 'Feedback to send. Leave out API keys, tokens, and other secrets',
|
|
552
|
+
})
|
|
553
|
+
.option('client-id', {
|
|
554
|
+
type: 'string',
|
|
555
|
+
demandOption: true,
|
|
556
|
+
description: 'ID for this report, so the team can tell retries apart',
|
|
557
|
+
})
|
|
558
|
+
.option('category', {
|
|
559
|
+
choices: FEEDBACK_CATEGORIES,
|
|
560
|
+
demandOption: true,
|
|
561
|
+
description: 'Feedback category',
|
|
562
|
+
})
|
|
563
|
+
.example('$0 feedback "mint dev crashes on a missing image" --client-id 7f3a --category bug', 'Report a bug')
|
|
564
|
+
.epilog('Requires mint login. Never include API keys, tokens, passwords, or other secrets in the message.'), (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
565
|
+
const sent = yield feedback({
|
|
566
|
+
message: argv.message,
|
|
567
|
+
clientId: argv.clientId,
|
|
568
|
+
category: argv.category,
|
|
569
|
+
});
|
|
570
|
+
yield terminate(sent ? 0 : 1);
|
|
545
571
|
}))
|
|
546
572
|
.command('config', 'Manage CLI configuration', (yargs) => yargs
|
|
547
573
|
.command('set <key> <value>', 'Set a configuration value', (yargs) => yargs
|
package/bin/feedback.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
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 { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { addLog, ErrorLog, SuccessLog } from '@mintlify/previewing';
|
|
12
|
+
import { authenticatedFetch } from './authenticatedFetch.js';
|
|
13
|
+
import { API_URL } from './constants.js';
|
|
14
|
+
export const FEEDBACK_CATEGORIES = ['bug', 'docs', 'idea'];
|
|
15
|
+
const LOGIN_REQUIRED = 'not logged in. Run `mint login` first, then retry.';
|
|
16
|
+
export function sendFeedback(input) {
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
let res;
|
|
19
|
+
try {
|
|
20
|
+
res = yield authenticatedFetch(`${API_URL}/api/cli/feedback`, {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23
|
+
body: JSON.stringify(Object.assign(Object.assign({}, input), { source: 'cli' })),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const notLoggedIn = error instanceof Error && /not authenticated/i.test(error.message);
|
|
28
|
+
return notLoggedIn ? LOGIN_REQUIRED : 'could not reach the server';
|
|
29
|
+
}
|
|
30
|
+
if (res.status === 401)
|
|
31
|
+
return LOGIN_REQUIRED;
|
|
32
|
+
return res.ok ? undefined : `could not send feedback (HTTP ${res.status})`;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function feedback(input) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const error = yield sendFeedback(input);
|
|
38
|
+
addLog(error ? _jsx(ErrorLog, { message: error }) : _jsx(SuccessLog, { message: "feedback sent" }));
|
|
39
|
+
return !error;
|
|
40
|
+
});
|
|
41
|
+
}
|