@mintlify/cli 4.0.1422 → 4.0.1423

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/welcome.js CHANGED
@@ -23,7 +23,10 @@ const GROUPS = [
23
23
  },
24
24
  {
25
25
  title: 'Insights',
26
- commands: [{ name: 'automations', description: 'Create and manage automations' }],
26
+ commands: [
27
+ { name: 'analytics', description: 'View analytics for your site' },
28
+ { name: 'automations', description: 'Create and manage automations' },
29
+ ],
27
30
  },
28
31
  {
29
32
  title: 'Account',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintlify/cli",
3
- "version": "4.0.1422",
3
+ "version": "4.0.1423",
4
4
  "description": "The Mintlify CLI",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -101,5 +101,5 @@
101
101
  "vitest": "2.1.9",
102
102
  "vitest-mock-process": "1.0.4"
103
103
  },
104
- "gitHead": "8631a49a928983c1958ca93c7414d56f68f46d4c"
104
+ "gitHead": "0bf9113a0575e8b3cb79385417245bfb301e4ccf"
105
105
  }
@@ -0,0 +1,153 @@
1
+ import { authenticatedFetch } from '../authenticatedFetch.js';
2
+ import { API_URL } from '../constants.js';
3
+ import type {
4
+ AssistantThreadResponse,
5
+ BucketThreadsResponse,
6
+ BucketsResponse,
7
+ ConversationResponse,
8
+ FeedbackByPageResponse,
9
+ FeedbackResponse,
10
+ KpiResponse,
11
+ SearchResponse,
12
+ ViewsResponse,
13
+ VisitorsResponse,
14
+ } from './types.js';
15
+
16
+ type Params = Record<string, string | number | undefined>;
17
+
18
+ async function request<T>(path: string, params: Params = {}): Promise<T> {
19
+ const url = new URL(`${API_URL}/api/cli/analytics${path}`);
20
+ for (const [key, value] of Object.entries(params)) {
21
+ if (value !== undefined) url.searchParams.set(key, String(value));
22
+ }
23
+
24
+ const res = await authenticatedFetch(url.toString(), {
25
+ headers: { Accept: 'application/json' },
26
+ });
27
+
28
+ if (!res.ok) {
29
+ const body = await res.text().catch(() => '');
30
+ throw new Error(`API error (${res.status}): ${body || res.statusText}`);
31
+ }
32
+
33
+ return res.json() as Promise<T>;
34
+ }
35
+
36
+ export function getKpi(
37
+ opts: {
38
+ dateFrom: string;
39
+ dateTo: string;
40
+ page?: string;
41
+ },
42
+ subdomain?: string
43
+ ) {
44
+ return request<KpiResponse>('/kpi', { ...opts, subdomain });
45
+ }
46
+
47
+ export function getFeedback(
48
+ opts: {
49
+ dateFrom: string;
50
+ dateTo: string;
51
+ limit?: number;
52
+ cursor?: string;
53
+ source?: string;
54
+ status?: string;
55
+ },
56
+ subdomain?: string
57
+ ) {
58
+ return request<FeedbackResponse>('/feedback', { ...opts, subdomain });
59
+ }
60
+
61
+ export function getFeedbackByPage(
62
+ opts: {
63
+ dateFrom: string;
64
+ dateTo: string;
65
+ limit?: number;
66
+ source?: string;
67
+ status?: string;
68
+ },
69
+ subdomain?: string
70
+ ) {
71
+ return request<FeedbackByPageResponse>('/feedback/by-page', { ...opts, subdomain });
72
+ }
73
+
74
+ export function getConversations(
75
+ opts: {
76
+ dateFrom: string;
77
+ dateTo: string;
78
+ limit?: number;
79
+ cursor?: string;
80
+ },
81
+ subdomain?: string
82
+ ) {
83
+ return request<ConversationResponse>('/assistant', { ...opts, subdomain });
84
+ }
85
+
86
+ export function getAssistantThread(threadId: string, subdomain?: string) {
87
+ return request<AssistantThreadResponse>(`/assistant/threads/${encodeURIComponent(threadId)}`, {
88
+ subdomain,
89
+ });
90
+ }
91
+
92
+ export function getSearches(
93
+ opts: {
94
+ dateFrom: string;
95
+ dateTo: string;
96
+ limit?: number;
97
+ cursor?: string;
98
+ },
99
+ subdomain?: string
100
+ ) {
101
+ return request<SearchResponse>('/searches', { ...opts, subdomain });
102
+ }
103
+
104
+ export function getViews(
105
+ opts: {
106
+ dateFrom: string;
107
+ dateTo: string;
108
+ limit?: number;
109
+ offset?: number;
110
+ },
111
+ subdomain?: string
112
+ ) {
113
+ return request<ViewsResponse>('/views', { ...opts, subdomain });
114
+ }
115
+
116
+ export function getVisitors(
117
+ opts: {
118
+ dateFrom: string;
119
+ dateTo: string;
120
+ limit?: number;
121
+ offset?: number;
122
+ },
123
+ subdomain?: string
124
+ ) {
125
+ return request<VisitorsResponse>('/visitors', { ...opts, subdomain });
126
+ }
127
+
128
+ export function getBuckets(
129
+ opts: {
130
+ dateFrom?: string;
131
+ dateTo?: string;
132
+ topK?: number;
133
+ },
134
+ subdomain?: string
135
+ ) {
136
+ return request<BucketsResponse>('/conversations/buckets', { ...opts, subdomain });
137
+ }
138
+
139
+ export function getBucketThreads(
140
+ bucketId: string,
141
+ opts: {
142
+ dateFrom?: string;
143
+ dateTo?: string;
144
+ limit?: number;
145
+ cursor?: string;
146
+ },
147
+ subdomain?: string
148
+ ) {
149
+ return request<BucketThreadsResponse>(`/conversations/buckets/${encodeURIComponent(bucketId)}`, {
150
+ ...opts,
151
+ subdomain,
152
+ });
153
+ }
@@ -0,0 +1,6 @@
1
+ export function formatLocalDate(date: Date): string {
2
+ const year = date.getFullYear();
3
+ const month = String(date.getMonth() + 1).padStart(2, '0');
4
+ const day = String(date.getDate()).padStart(2, '0');
5
+ return `${year}-${month}-${day}`;
6
+ }
@@ -0,0 +1,50 @@
1
+ import type {
2
+ ConversationResponse,
3
+ FeedbackByPageResponse,
4
+ FeedbackResponse,
5
+ SearchResponse,
6
+ } from './types.js';
7
+
8
+ export function filterSearchResponse(
9
+ data: SearchResponse,
10
+ filters: { query?: string; page?: string }
11
+ ): SearchResponse {
12
+ let searches = data.searches;
13
+
14
+ if (filters.query) {
15
+ const query = filters.query.toLowerCase();
16
+ searches = searches.filter((row) => row.searchQuery.toLowerCase().includes(query));
17
+ }
18
+ const page = filters.page;
19
+ if (page) {
20
+ searches = searches.filter((row) => row.topClickedPage?.includes(page));
21
+ }
22
+
23
+ return { ...data, searches };
24
+ }
25
+
26
+ export function filterFeedbackByPageResponse(
27
+ data: FeedbackByPageResponse,
28
+ page?: string
29
+ ): FeedbackByPageResponse {
30
+ if (!page) return data;
31
+ return { ...data, feedback: data.feedback.filter((row) => row.path.includes(page)) };
32
+ }
33
+
34
+ export function filterFeedbackResponse(data: FeedbackResponse, page?: string): FeedbackResponse {
35
+ if (!page) return data;
36
+ return { ...data, feedback: data.feedback.filter((row) => row.path.includes(page)) };
37
+ }
38
+
39
+ export function filterConversationResponse(
40
+ data: ConversationResponse,
41
+ page?: string
42
+ ): ConversationResponse {
43
+ if (!page) return data;
44
+ return {
45
+ ...data,
46
+ conversations: data.conversations.filter((conversation) =>
47
+ conversation.sources.some((source) => source.url.includes(page))
48
+ ),
49
+ };
50
+ }
@@ -0,0 +1,13 @@
1
+ export function num(n: number): string {
2
+ return n.toLocaleString('en-US');
3
+ }
4
+
5
+ export function pct(n: number, total: number): string {
6
+ if (total === 0) return '\u2014';
7
+ return ((n / total) * 100).toFixed(1) + '%';
8
+ }
9
+
10
+ export function truncate(s: string, max: number): string {
11
+ if (s.length <= max) return s;
12
+ return s.slice(0, max - 1) + '\u2026';
13
+ }