@stats-forge/github-stats-forge-cli 0.3.2 → 0.4.0
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.js +3 -0
- package/build/cards.d.ts +23 -5
- package/build/cards.d.ts.map +1 -1
- package/build/cards.js +109 -45
- package/build/index.js +0 -0
- package/build/prompts.d.ts +5 -4
- package/build/prompts.d.ts.map +1 -1
- package/build/prompts.js +51 -10
- package/build/query.d.ts +4 -2
- package/build/query.d.ts.map +1 -1
- package/build/query.js +10 -2
- package/build/saved-card.d.ts +6 -0
- package/build/saved-card.d.ts.map +1 -1
- package/build/saved-card.js +6 -0
- package/build/tokens.d.ts +1 -1
- package/build/tokens.d.ts.map +1 -1
- package/build/tokens.js +2 -2
- package/package.json +4 -3
- package/src/cards.ts +122 -55
- package/src/prompts.ts +64 -14
- package/src/query.ts +7 -4
- package/src/saved-card.ts +7 -7
- package/src/tokens.ts +5 -5
package/bin.js
ADDED
package/build/cards.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { ApiResult, CardConfig } from '@stats-forge/github-stats-forge-core/api';
|
|
2
1
|
/**
|
|
3
2
|
* @file What each card accepts, in the order the prompts walk it.
|
|
4
3
|
*
|
|
5
4
|
* The core schemas validate these params;
|
|
6
5
|
* this catalog is what makes them navigable, so it carries the prose and the choices a schema has no room for.
|
|
7
6
|
*/
|
|
7
|
+
import type { ApiResult, CardConfig } from '@stats-forge/github-stats-forge-core/api';
|
|
8
8
|
/** How a param is asked for, and how the answer becomes a query string value. */
|
|
9
9
|
type OptionKind = 'text' | 'boolean' | 'number' | 'list' | 'choice';
|
|
10
10
|
/** One param of one card. */
|
|
11
|
-
export interface
|
|
11
|
+
export interface CardField {
|
|
12
12
|
/** Query param the answer is written to. */
|
|
13
13
|
name: string;
|
|
14
14
|
/** What the prompt asks. */
|
|
@@ -19,14 +19,28 @@ export interface CardOption {
|
|
|
19
19
|
/** Shown under the prompt, for anything the label cannot say. */
|
|
20
20
|
hint?: string;
|
|
21
21
|
}
|
|
22
|
+
/** Which section of the option menu a param sits in. */
|
|
23
|
+
export type OptionGroup = 'data' | 'display' | 'text' | 'colors';
|
|
24
|
+
/**
|
|
25
|
+
* The menu's sections, in the order it shows them.
|
|
26
|
+
* A section no option sits under is dropped, so a card that counts nothing has none.
|
|
27
|
+
*/
|
|
28
|
+
export declare const OPTION_GROUPS: ReadonlyArray<{
|
|
29
|
+
group: OptionGroup;
|
|
30
|
+
label: string;
|
|
31
|
+
}>;
|
|
32
|
+
/** One optional param of one card. It is required so a new option cannot go ungrouped. */
|
|
33
|
+
export interface CardOption extends CardField {
|
|
34
|
+
group: OptionGroup;
|
|
35
|
+
}
|
|
22
36
|
/** A card, its params, and the core handler that renders it. */
|
|
23
37
|
export interface CardKind {
|
|
24
38
|
id: string;
|
|
25
39
|
label: string;
|
|
26
40
|
/** Whether rendering it calls the GitHub API, and so needs a token. */
|
|
27
41
|
needsToken: boolean;
|
|
28
|
-
/** Asked first
|
|
29
|
-
required: ReadonlyArray<
|
|
42
|
+
/** Asked first, before the menu opens, so no section applies to them. */
|
|
43
|
+
required: ReadonlyArray<CardField>;
|
|
30
44
|
/** Everything else, navigable in any order. */
|
|
31
45
|
options: ReadonlyArray<CardOption>;
|
|
32
46
|
/** @returns The rendered card, or the rendered error. */
|
|
@@ -34,7 +48,11 @@ export interface CardKind {
|
|
|
34
48
|
}
|
|
35
49
|
/** Colors and the theme, which every card accepts. */
|
|
36
50
|
export declare const COMMON_OPTIONS: ReadonlyArray<CardOption>;
|
|
37
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Every card, with the options every card shares beside its own.
|
|
53
|
+
* The shared ones come first so the theme heads the colors section,
|
|
54
|
+
* which is where a card's own color options land behind it.
|
|
55
|
+
*/
|
|
38
56
|
export declare const cards: ReadonlyArray<CardKind>;
|
|
39
57
|
/**
|
|
40
58
|
* @returns The card, or `undefined` when nothing renders under that name.
|
package/build/cards.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../src/cards.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../src/cards.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAEtF,iFAAiF;AACjF,KAAK,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpE,6BAA6B;AAC7B,MAAM,WAAW,SAAS;IACxB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,wFAAwF;IACxF,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAChC,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wDAAwD;AACxD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAK9E,CAAC;AAEF,0FAA0F;AAC1F,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,gEAAgE;AAChE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,UAAU,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,QAAQ,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACnC,+CAA+C;IAC/C,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,yDAAyD;IACzD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;CACnF;AAID,sDAAsD;AACtD,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,UAAU,CAkCpD,CAAC;AAsYF;;;;GAIG;AACH,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC,QAAQ,CAGvC,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,QAAQ,OAAQ,MAAM,KAAG,QAAQ,GAAG,SAAiD,CAAC"}
|
package/build/cards.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file What each card accepts, in the order the prompts walk it.
|
|
3
|
+
*
|
|
4
|
+
* The core schemas validate these params;
|
|
5
|
+
* this catalog is what makes them navigable, so it carries the prose and the choices a schema has no room for.
|
|
6
|
+
*/
|
|
1
7
|
import { contributedTo, gist, org, pin, stats, themes, topLangs, wakatime, } from '@stats-forge/github-stats-forge-core/api';
|
|
8
|
+
/**
|
|
9
|
+
* The menu's sections, in the order it shows them.
|
|
10
|
+
* A section no option sits under is dropped, so a card that counts nothing has none.
|
|
11
|
+
*/
|
|
12
|
+
export const OPTION_GROUPS = [
|
|
13
|
+
{ group: 'data', label: 'What it counts' },
|
|
14
|
+
{ group: 'display', label: 'What it shows' },
|
|
15
|
+
{ group: 'text', label: 'Text and size' },
|
|
16
|
+
{ group: 'colors', label: 'Colors and border' },
|
|
17
|
+
];
|
|
2
18
|
const THEME_NAMES = Object.keys(themes);
|
|
3
19
|
/** Colors and the theme, which every card accepts. */
|
|
4
20
|
export const COMMON_OPTIONS = [
|
|
@@ -6,6 +22,7 @@ export const COMMON_OPTIONS = [
|
|
|
6
22
|
name: 'theme',
|
|
7
23
|
label: 'Theme',
|
|
8
24
|
kind: 'choice',
|
|
25
|
+
group: 'colors',
|
|
9
26
|
choices: THEME_NAMES,
|
|
10
27
|
hint: 'An unknown name falls back to the default theme',
|
|
11
28
|
},
|
|
@@ -13,24 +30,27 @@ export const COMMON_OPTIONS = [
|
|
|
13
30
|
name: 'title_color',
|
|
14
31
|
label: 'Title color',
|
|
15
32
|
kind: 'text',
|
|
33
|
+
group: 'colors',
|
|
16
34
|
hint: 'Hex, no #',
|
|
17
35
|
},
|
|
18
|
-
{ name: 'text_color', label: 'Text color', kind: 'text', hint: 'Hex, no #' },
|
|
19
|
-
{ name: 'icon_color', label: 'Icon color', kind: 'text', hint: 'Hex, no #' },
|
|
36
|
+
{ name: 'text_color', label: 'Text color', kind: 'text', group: 'colors', hint: 'Hex, no #' },
|
|
37
|
+
{ name: 'icon_color', label: 'Icon color', kind: 'text', group: 'colors', hint: 'Hex, no #' },
|
|
20
38
|
{
|
|
21
39
|
name: 'bg_color',
|
|
22
40
|
label: 'Background color',
|
|
23
41
|
kind: 'text',
|
|
42
|
+
group: 'colors',
|
|
24
43
|
hint: 'Hex, no #, or a gradient: angle,color,color',
|
|
25
44
|
},
|
|
26
45
|
{
|
|
27
46
|
name: 'border_color',
|
|
28
47
|
label: 'Border color',
|
|
29
48
|
kind: 'text',
|
|
49
|
+
group: 'colors',
|
|
30
50
|
hint: 'Hex, no #',
|
|
31
51
|
},
|
|
32
|
-
{ name: 'border_radius', label: 'Border radius', kind: 'number' },
|
|
33
|
-
{ name: 'hide_border', label: 'Hide the border', kind: 'boolean' },
|
|
52
|
+
{ name: 'border_radius', label: 'Border radius', kind: 'number', group: 'colors' },
|
|
53
|
+
{ name: 'hide_border', label: 'Hide the border', kind: 'boolean', group: 'colors' },
|
|
34
54
|
];
|
|
35
55
|
/**
|
|
36
56
|
* The two ends of a card's date range.
|
|
@@ -40,14 +60,15 @@ export const COMMON_OPTIONS = [
|
|
|
40
60
|
const rangeOptions = (counted) => {
|
|
41
61
|
const hint = 'A year, a month or a day: 2024, 2024-03, 2024-03-15';
|
|
42
62
|
return [
|
|
43
|
-
{ name: 'from', label: `Count ${counted} from`, kind: 'text', hint },
|
|
44
|
-
{ name: 'to', label: `Count ${counted} up to`, kind: 'text', hint },
|
|
63
|
+
{ name: 'from', label: `Count ${counted} from`, kind: 'text', group: 'data', hint },
|
|
64
|
+
{ name: 'to', label: `Count ${counted} up to`, kind: 'text', group: 'data', hint },
|
|
45
65
|
];
|
|
46
66
|
};
|
|
47
67
|
const LOCALE_OPTION = {
|
|
48
68
|
name: 'locale',
|
|
49
69
|
label: 'Locale',
|
|
50
70
|
kind: 'text',
|
|
71
|
+
group: 'text',
|
|
51
72
|
hint: 'Two-letter code, e.g. es',
|
|
52
73
|
};
|
|
53
74
|
const CARDS = [
|
|
@@ -61,76 +82,88 @@ const CARDS = [
|
|
|
61
82
|
name: 'show',
|
|
62
83
|
label: 'Extra stats to show',
|
|
63
84
|
kind: 'list',
|
|
85
|
+
group: 'display',
|
|
64
86
|
choices: stats.OPTIONS.show,
|
|
65
87
|
},
|
|
66
88
|
{
|
|
67
89
|
name: 'hide',
|
|
68
90
|
label: 'Stats to hide',
|
|
69
91
|
kind: 'list',
|
|
92
|
+
group: 'display',
|
|
70
93
|
choices: stats.OPTIONS.hide,
|
|
71
94
|
},
|
|
72
|
-
{ name: 'show_icons', label: 'Show the stat icons', kind: 'boolean' },
|
|
73
|
-
{ name: 'hide_rank', label: 'Hide the rank circle', kind: 'boolean' },
|
|
95
|
+
{ name: 'show_icons', label: 'Show the stat icons', kind: 'boolean', group: 'display' },
|
|
96
|
+
{ name: 'hide_rank', label: 'Hide the rank circle', kind: 'boolean', group: 'display' },
|
|
74
97
|
{
|
|
75
98
|
name: 'rank_icon',
|
|
76
99
|
label: 'Rank indicator',
|
|
77
100
|
kind: 'choice',
|
|
101
|
+
group: 'display',
|
|
78
102
|
choices: stats.OPTIONS.rank_icon,
|
|
79
103
|
},
|
|
80
104
|
{
|
|
81
105
|
name: 'include_all_commits',
|
|
82
106
|
label: 'Count commits of all time',
|
|
83
107
|
kind: 'boolean',
|
|
108
|
+
group: 'data',
|
|
84
109
|
},
|
|
85
110
|
...rangeOptions('commits'),
|
|
86
111
|
{
|
|
87
112
|
name: 'exclude_repo',
|
|
88
113
|
label: 'Repositories to exclude',
|
|
89
114
|
kind: 'list',
|
|
115
|
+
group: 'data',
|
|
90
116
|
},
|
|
91
117
|
{
|
|
92
118
|
name: 'repo',
|
|
93
119
|
label: 'Repositories the search-based stats are scoped to',
|
|
94
120
|
kind: 'list',
|
|
121
|
+
group: 'data',
|
|
95
122
|
},
|
|
96
123
|
{
|
|
97
124
|
name: 'owner',
|
|
98
125
|
label: 'Owners the search-based stats are scoped to',
|
|
99
126
|
kind: 'list',
|
|
127
|
+
group: 'data',
|
|
100
128
|
},
|
|
101
129
|
{
|
|
102
130
|
name: 'role',
|
|
103
131
|
label: 'Owner affiliations to include',
|
|
104
132
|
kind: 'list',
|
|
133
|
+
group: 'data',
|
|
105
134
|
choices: stats.OPTIONS.role,
|
|
106
135
|
},
|
|
107
136
|
{
|
|
108
137
|
name: 'contribs_include_own_repos',
|
|
109
138
|
label: 'Count contributions to your own repositories',
|
|
110
139
|
kind: 'boolean',
|
|
140
|
+
group: 'data',
|
|
111
141
|
},
|
|
112
|
-
{ name: 'custom_title', label: 'Card title', kind: 'text' },
|
|
113
|
-
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean' },
|
|
114
|
-
{ name: 'card_width', label: 'Card width', kind: 'number' },
|
|
115
|
-
{ name: 'line_height', label: 'Line height', kind: 'number' },
|
|
116
|
-
{ name: 'text_bold', label: 'Bold stat values', kind: 'boolean' },
|
|
142
|
+
{ name: 'custom_title', label: 'Card title', kind: 'text', group: 'text' },
|
|
143
|
+
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean', group: 'text' },
|
|
144
|
+
{ name: 'card_width', label: 'Card width', kind: 'number', group: 'text' },
|
|
145
|
+
{ name: 'line_height', label: 'Line height', kind: 'number', group: 'text' },
|
|
146
|
+
{ name: 'text_bold', label: 'Bold stat values', kind: 'boolean', group: 'text' },
|
|
117
147
|
{
|
|
118
148
|
name: 'number_format',
|
|
119
149
|
label: 'Number format',
|
|
120
150
|
kind: 'choice',
|
|
151
|
+
group: 'text',
|
|
121
152
|
choices: stats.OPTIONS.number_format,
|
|
122
153
|
},
|
|
123
154
|
{
|
|
124
155
|
name: 'number_precision',
|
|
125
156
|
label: 'Decimals kept when abbreviating',
|
|
126
157
|
kind: 'number',
|
|
158
|
+
group: 'text',
|
|
127
159
|
},
|
|
128
160
|
{
|
|
129
161
|
name: 'disable_animations',
|
|
130
162
|
label: 'Disable the animations',
|
|
131
163
|
kind: 'boolean',
|
|
164
|
+
group: 'text',
|
|
132
165
|
},
|
|
133
|
-
{ name: 'ring_color', label: 'Rank ring color', kind: 'text' },
|
|
166
|
+
{ name: 'ring_color', label: 'Rank ring color', kind: 'text', group: 'colors' },
|
|
134
167
|
LOCALE_OPTION,
|
|
135
168
|
],
|
|
136
169
|
render: stats,
|
|
@@ -145,51 +178,59 @@ const CARDS = [
|
|
|
145
178
|
name: 'layout',
|
|
146
179
|
label: 'Layout',
|
|
147
180
|
kind: 'choice',
|
|
181
|
+
group: 'display',
|
|
148
182
|
choices: topLangs.OPTIONS.layout,
|
|
149
183
|
},
|
|
150
|
-
{ name: 'langs_count', label: 'Languages to show', kind: 'number' },
|
|
151
|
-
{ name: 'hide', label: 'Languages to hide', kind: 'list' },
|
|
152
|
-
{ name: 'exclude_repo', label: 'Repositories to exclude', kind: 'list' },
|
|
184
|
+
{ name: 'langs_count', label: 'Languages to show', kind: 'number', group: 'data' },
|
|
185
|
+
{ name: 'hide', label: 'Languages to hide', kind: 'list', group: 'data' },
|
|
186
|
+
{ name: 'exclude_repo', label: 'Repositories to exclude', kind: 'list', group: 'data' },
|
|
153
187
|
{
|
|
154
188
|
name: 'size_weight',
|
|
155
189
|
label: "Weight given to a language's size",
|
|
156
190
|
kind: 'number',
|
|
191
|
+
group: 'data',
|
|
157
192
|
},
|
|
158
193
|
{
|
|
159
194
|
name: 'count_weight',
|
|
160
195
|
label: 'Weight given to its repository count',
|
|
161
196
|
kind: 'number',
|
|
197
|
+
group: 'data',
|
|
162
198
|
},
|
|
163
199
|
{
|
|
164
200
|
name: 'stats_format',
|
|
165
201
|
label: 'Show values as',
|
|
166
202
|
kind: 'choice',
|
|
203
|
+
group: 'display',
|
|
167
204
|
choices: topLangs.OPTIONS.stats_format,
|
|
168
205
|
},
|
|
169
206
|
{
|
|
170
207
|
name: 'hide_progress',
|
|
171
208
|
label: 'Hide the progress bars',
|
|
172
209
|
kind: 'boolean',
|
|
210
|
+
group: 'display',
|
|
173
211
|
},
|
|
174
|
-
{ name: 'hide_values', label: 'Hide the values', kind: 'boolean' },
|
|
212
|
+
{ name: 'hide_values', label: 'Hide the values', kind: 'boolean', group: 'display' },
|
|
175
213
|
{
|
|
176
214
|
name: 'prog_bar_bg_color',
|
|
177
215
|
label: 'Progress bar background color',
|
|
178
216
|
kind: 'text',
|
|
217
|
+
group: 'colors',
|
|
179
218
|
},
|
|
180
219
|
{
|
|
181
220
|
name: 'role',
|
|
182
221
|
label: 'Owner affiliations to include',
|
|
183
222
|
kind: 'list',
|
|
223
|
+
group: 'data',
|
|
184
224
|
choices: topLangs.OPTIONS.role,
|
|
185
225
|
},
|
|
186
|
-
{ name: 'custom_title', label: 'Card title', kind: 'text' },
|
|
187
|
-
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean' },
|
|
188
|
-
{ name: 'card_width', label: 'Card width', kind: 'number' },
|
|
226
|
+
{ name: 'custom_title', label: 'Card title', kind: 'text', group: 'text' },
|
|
227
|
+
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean', group: 'text' },
|
|
228
|
+
{ name: 'card_width', label: 'Card width', kind: 'number', group: 'text' },
|
|
189
229
|
{
|
|
190
230
|
name: 'disable_animations',
|
|
191
231
|
label: 'Disable the animations',
|
|
192
232
|
kind: 'boolean',
|
|
233
|
+
group: 'text',
|
|
193
234
|
},
|
|
194
235
|
LOCALE_OPTION,
|
|
195
236
|
],
|
|
@@ -204,31 +245,35 @@ const CARDS = [
|
|
|
204
245
|
{ name: 'repo', label: 'Repository name', kind: 'text' },
|
|
205
246
|
],
|
|
206
247
|
options: [
|
|
207
|
-
{ name: 'show_owner', label: 'Show the owner', kind: 'boolean' },
|
|
248
|
+
{ name: 'show_owner', label: 'Show the owner', kind: 'boolean', group: 'display' },
|
|
208
249
|
{
|
|
209
250
|
name: 'show',
|
|
210
251
|
label: 'Extra stats to show',
|
|
211
252
|
kind: 'list',
|
|
253
|
+
group: 'display',
|
|
212
254
|
choices: pin.OPTIONS.show,
|
|
213
255
|
},
|
|
214
|
-
{ name: 'show_icons', label: 'Show the stat icons', kind: 'boolean' },
|
|
256
|
+
{ name: 'show_icons', label: 'Show the stat icons', kind: 'boolean', group: 'display' },
|
|
215
257
|
{
|
|
216
258
|
name: 'description_lines_count',
|
|
217
259
|
label: 'Lines the description wraps to',
|
|
218
260
|
kind: 'number',
|
|
261
|
+
group: 'text',
|
|
219
262
|
},
|
|
220
263
|
{
|
|
221
264
|
name: 'browser_rendering',
|
|
222
265
|
label: 'Let the browser wrap the description',
|
|
223
266
|
kind: 'boolean',
|
|
267
|
+
group: 'text',
|
|
224
268
|
},
|
|
225
|
-
{ name: 'card_width', label: 'Card width', kind: 'number' },
|
|
226
|
-
{ name: 'line_height', label: 'Line height', kind: 'number' },
|
|
227
|
-
{ name: 'text_bold', label: 'Bold stat values', kind: 'boolean' },
|
|
269
|
+
{ name: 'card_width', label: 'Card width', kind: 'number', group: 'text' },
|
|
270
|
+
{ name: 'line_height', label: 'Line height', kind: 'number', group: 'text' },
|
|
271
|
+
{ name: 'text_bold', label: 'Bold stat values', kind: 'boolean', group: 'text' },
|
|
228
272
|
{
|
|
229
273
|
name: 'number_format',
|
|
230
274
|
label: 'Number format',
|
|
231
275
|
kind: 'choice',
|
|
276
|
+
group: 'text',
|
|
232
277
|
choices: pin.OPTIONS.number_format,
|
|
233
278
|
},
|
|
234
279
|
LOCALE_OPTION,
|
|
@@ -245,35 +290,40 @@ const CARDS = [
|
|
|
245
290
|
name: 'show',
|
|
246
291
|
label: 'Extra stats to show',
|
|
247
292
|
kind: 'list',
|
|
293
|
+
group: 'display',
|
|
248
294
|
choices: org.OPTIONS.show,
|
|
249
295
|
},
|
|
250
296
|
{
|
|
251
297
|
name: 'hide',
|
|
252
298
|
label: 'Stats to hide',
|
|
253
299
|
kind: 'list',
|
|
300
|
+
group: 'display',
|
|
254
301
|
choices: org.OPTIONS.hide,
|
|
255
302
|
},
|
|
256
|
-
{ name: 'show_icons', label: 'Show the stat icons', kind: 'boolean' },
|
|
303
|
+
{ name: 'show_icons', label: 'Show the stat icons', kind: 'boolean', group: 'display' },
|
|
257
304
|
{
|
|
258
305
|
name: 'hide_description',
|
|
259
306
|
label: "Hide the organization's description",
|
|
260
307
|
kind: 'boolean',
|
|
308
|
+
group: 'display',
|
|
261
309
|
},
|
|
262
|
-
{ name: 'custom_title', label: 'Card title', kind: 'text' },
|
|
263
|
-
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean' },
|
|
264
|
-
{ name: 'card_width', label: 'Card width', kind: 'number' },
|
|
265
|
-
{ name: 'line_height', label: 'Line height', kind: 'number' },
|
|
266
|
-
{ name: 'text_bold', label: 'Bold stat values', kind: 'boolean' },
|
|
310
|
+
{ name: 'custom_title', label: 'Card title', kind: 'text', group: 'text' },
|
|
311
|
+
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean', group: 'text' },
|
|
312
|
+
{ name: 'card_width', label: 'Card width', kind: 'number', group: 'text' },
|
|
313
|
+
{ name: 'line_height', label: 'Line height', kind: 'number', group: 'text' },
|
|
314
|
+
{ name: 'text_bold', label: 'Bold stat values', kind: 'boolean', group: 'text' },
|
|
267
315
|
{
|
|
268
316
|
name: 'number_format',
|
|
269
317
|
label: 'Number format',
|
|
270
318
|
kind: 'choice',
|
|
319
|
+
group: 'text',
|
|
271
320
|
choices: org.OPTIONS.number_format,
|
|
272
321
|
},
|
|
273
322
|
{
|
|
274
323
|
name: 'disable_animations',
|
|
275
324
|
label: 'Disable the animations',
|
|
276
325
|
kind: 'boolean',
|
|
326
|
+
group: 'text',
|
|
277
327
|
},
|
|
278
328
|
LOCALE_OPTION,
|
|
279
329
|
],
|
|
@@ -285,16 +335,18 @@ const CARDS = [
|
|
|
285
335
|
needsToken: true,
|
|
286
336
|
required: [{ name: 'username', label: 'GitHub username', kind: 'text' }],
|
|
287
337
|
options: [
|
|
288
|
-
{ name: 'repos_count', label: 'Repositories to show', kind: 'number' },
|
|
338
|
+
{ name: 'repos_count', label: 'Repositories to show', kind: 'number', group: 'data' },
|
|
289
339
|
{
|
|
290
340
|
name: 'include_own_repos',
|
|
291
341
|
label: 'Include your own repositories',
|
|
292
342
|
kind: 'boolean',
|
|
343
|
+
group: 'data',
|
|
293
344
|
},
|
|
294
345
|
{
|
|
295
346
|
name: 'exclude_repo',
|
|
296
347
|
label: 'Repositories to exclude',
|
|
297
348
|
kind: 'list',
|
|
349
|
+
group: 'data',
|
|
298
350
|
hint: 'Each one an owner/name, or just the name',
|
|
299
351
|
},
|
|
300
352
|
...rangeOptions('contributions'),
|
|
@@ -302,15 +354,17 @@ const CARDS = [
|
|
|
302
354
|
name: 'hide_years',
|
|
303
355
|
label: 'Hide the year marks',
|
|
304
356
|
kind: 'boolean',
|
|
357
|
+
group: 'display',
|
|
305
358
|
hint: 'One mark per contribution year, filled for the years that repo got one',
|
|
306
359
|
},
|
|
307
|
-
{ name: 'custom_title', label: 'Card title', kind: 'text' },
|
|
308
|
-
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean' },
|
|
309
|
-
{ name: 'card_width', label: 'Card width', kind: 'number' },
|
|
360
|
+
{ name: 'custom_title', label: 'Card title', kind: 'text', group: 'text' },
|
|
361
|
+
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean', group: 'text' },
|
|
362
|
+
{ name: 'card_width', label: 'Card width', kind: 'number', group: 'text' },
|
|
310
363
|
{
|
|
311
364
|
name: 'disable_animations',
|
|
312
365
|
label: 'Disable the animations',
|
|
313
366
|
kind: 'boolean',
|
|
367
|
+
group: 'text',
|
|
314
368
|
},
|
|
315
369
|
LOCALE_OPTION,
|
|
316
370
|
],
|
|
@@ -322,11 +376,12 @@ const CARDS = [
|
|
|
322
376
|
needsToken: true,
|
|
323
377
|
required: [{ name: 'id', label: 'Gist ID', kind: 'text' }],
|
|
324
378
|
options: [
|
|
325
|
-
{ name: 'show_owner', label: 'Show the owner', kind: 'boolean' },
|
|
379
|
+
{ name: 'show_owner', label: 'Show the owner', kind: 'boolean', group: 'display' },
|
|
326
380
|
{
|
|
327
381
|
name: 'browser_rendering',
|
|
328
382
|
label: 'Let the browser wrap the description',
|
|
329
383
|
kind: 'boolean',
|
|
384
|
+
group: 'text',
|
|
330
385
|
},
|
|
331
386
|
LOCALE_OPTION,
|
|
332
387
|
],
|
|
@@ -342,34 +397,39 @@ const CARDS = [
|
|
|
342
397
|
name: 'layout',
|
|
343
398
|
label: 'Layout',
|
|
344
399
|
kind: 'choice',
|
|
400
|
+
group: 'display',
|
|
345
401
|
choices: wakatime.OPTIONS.layout,
|
|
346
402
|
},
|
|
347
403
|
{
|
|
348
404
|
name: 'display_format',
|
|
349
405
|
label: 'Show values as',
|
|
350
406
|
kind: 'choice',
|
|
407
|
+
group: 'display',
|
|
351
408
|
choices: wakatime.OPTIONS.display_format,
|
|
352
409
|
},
|
|
353
|
-
{ name: 'langs_count', label: 'Languages to show', kind: 'number' },
|
|
354
|
-
{ name: 'hide', label: 'Languages to hide', kind: 'list' },
|
|
410
|
+
{ name: 'langs_count', label: 'Languages to show', kind: 'number', group: 'data' },
|
|
411
|
+
{ name: 'hide', label: 'Languages to hide', kind: 'list', group: 'data' },
|
|
355
412
|
{
|
|
356
413
|
name: 'hide_progress',
|
|
357
414
|
label: 'Hide the progress bars',
|
|
358
415
|
kind: 'boolean',
|
|
416
|
+
group: 'display',
|
|
359
417
|
},
|
|
360
|
-
{ name: 'custom_title', label: 'Card title', kind: 'text' },
|
|
361
|
-
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean' },
|
|
362
|
-
{ name: 'card_width', label: 'Card width', kind: 'number' },
|
|
363
|
-
{ name: 'line_height', label: 'Line height', kind: 'number' },
|
|
418
|
+
{ name: 'custom_title', label: 'Card title', kind: 'text', group: 'text' },
|
|
419
|
+
{ name: 'hide_title', label: 'Hide the title', kind: 'boolean', group: 'text' },
|
|
420
|
+
{ name: 'card_width', label: 'Card width', kind: 'number', group: 'text' },
|
|
421
|
+
{ name: 'line_height', label: 'Line height', kind: 'number', group: 'text' },
|
|
364
422
|
{
|
|
365
423
|
name: 'disable_animations',
|
|
366
424
|
label: 'Disable the animations',
|
|
367
425
|
kind: 'boolean',
|
|
426
|
+
group: 'text',
|
|
368
427
|
},
|
|
369
428
|
{
|
|
370
429
|
name: 'api_domain',
|
|
371
430
|
label: 'WakaTime instance',
|
|
372
431
|
kind: 'text',
|
|
432
|
+
group: 'data',
|
|
373
433
|
hint: 'Defaults to wakatime.com',
|
|
374
434
|
},
|
|
375
435
|
LOCALE_OPTION,
|
|
@@ -377,10 +437,14 @@ const CARDS = [
|
|
|
377
437
|
render: wakatime,
|
|
378
438
|
},
|
|
379
439
|
];
|
|
380
|
-
/**
|
|
440
|
+
/**
|
|
441
|
+
* Every card, with the options every card shares beside its own.
|
|
442
|
+
* The shared ones come first so the theme heads the colors section,
|
|
443
|
+
* which is where a card's own color options land behind it.
|
|
444
|
+
*/
|
|
381
445
|
export const cards = CARDS.map((card) => ({
|
|
382
446
|
...card,
|
|
383
|
-
options: [...card.options
|
|
447
|
+
options: [...COMMON_OPTIONS, ...card.options],
|
|
384
448
|
}));
|
|
385
449
|
/**
|
|
386
450
|
* @returns The card, or `undefined` when nothing renders under that name.
|
package/build/index.js
CHANGED
|
File without changes
|
package/build/prompts.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { CardKind, CardOption } from './cards.ts';
|
|
2
|
-
import type { Answer } from './query.ts';
|
|
3
1
|
/**
|
|
4
2
|
* @file The navigation itself.
|
|
5
3
|
*
|
|
6
|
-
* A card first, then its required options, then a menu of every other option
|
|
7
|
-
* pick one, answer it, and land back on the
|
|
4
|
+
* A card first, then its required options, then a menu of every other option
|
|
5
|
+
* under the section it belongs to: pick one, answer it, and land back on the
|
|
6
|
+
* menu with the answer beside it.
|
|
8
7
|
*/
|
|
8
|
+
import type { CardKind, CardOption } from './cards.ts';
|
|
9
|
+
import type { Answer } from './query.ts';
|
|
9
10
|
/** @returns The card to render. */
|
|
10
11
|
export declare const pickCard: () => Promise<CardKind>;
|
|
11
12
|
/** How a trip through the option menu ended. */
|
package/build/prompts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGzC,mCAAmC;AACnC,eAAO,MAAM,QAAQ,QAAO,OAAO,CAAC,QAAQ,CAIxC,CAAC;AAuCL,gDAAgD;AAChD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AA8BtD,sDAAsD;AACtD,MAAM,WAAW,IAAI;IACnB,uCAAuC;IACvC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;CAC9C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,SACpB,QAAQ,QACR,IAAI,WACD,MAAM,KACd,OAAO,CAAC,UAAU,CAsDpB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,SAAgB,QAAQ,KAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAY7E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,eAAsB,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAMhF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,QAAa,OAAO,CAAC,MAAM,GAAG,SAAS,CAM3D,CAAC"}
|
package/build/prompts.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { checkbox, confirm, input, password, select } from '@inquirer/prompts';
|
|
2
|
-
import { cards } from './cards.js';
|
|
3
|
-
import { describeAnswer } from './query.js';
|
|
4
1
|
/**
|
|
5
2
|
* @file The navigation itself.
|
|
6
3
|
*
|
|
7
|
-
* A card first, then its required options, then a menu of every other option
|
|
8
|
-
* pick one, answer it, and land back on the
|
|
4
|
+
* A card first, then its required options, then a menu of every other option
|
|
5
|
+
* under the section it belongs to: pick one, answer it, and land back on the
|
|
6
|
+
* menu with the answer beside it.
|
|
9
7
|
*/
|
|
8
|
+
import { styleText } from 'node:util';
|
|
9
|
+
import { checkbox, confirm, input, password, select, Separator } from '@inquirer/prompts';
|
|
10
|
+
import { cards, OPTION_GROUPS } from './cards.js';
|
|
11
|
+
import { describeAnswer, UNSET } from './query.js';
|
|
10
12
|
/** @returns The card to render. */
|
|
11
13
|
export const pickCard = () => select({
|
|
12
14
|
message: 'Which card?',
|
|
@@ -44,6 +46,29 @@ const askOption = async (option, current) => {
|
|
|
44
46
|
});
|
|
45
47
|
return answer.trim() === '' ? undefined : answer.trim();
|
|
46
48
|
};
|
|
49
|
+
/** Rows the list may use: the terminal, less the message, the help line and some air. */
|
|
50
|
+
const menuHeight = () => process.stdout.isTTY ? Math.max(10, process.stdout.rows - 6) : 15;
|
|
51
|
+
/**
|
|
52
|
+
* A section heading, ruled out to the width of the labels under it.
|
|
53
|
+
*
|
|
54
|
+
* @returns A `Separator`, so the cursor steps straight over it.
|
|
55
|
+
*/
|
|
56
|
+
const heading = (label, width) => new Separator(styleText('dim', `── ${label} ${'─'.repeat(Math.max(2, width - label.length))}`));
|
|
57
|
+
/**
|
|
58
|
+
* Typing jumps to the first row whose label starts with what was typed, which is
|
|
59
|
+
* what keeps the three actions one key away however far down the list the cursor sits.
|
|
60
|
+
*
|
|
61
|
+
* @returns The line under the list.
|
|
62
|
+
*/
|
|
63
|
+
const keysHelpTip = (keys) => {
|
|
64
|
+
const all = [
|
|
65
|
+
...keys,
|
|
66
|
+
['type', 'to jump — g generate, s save, q quit'],
|
|
67
|
+
];
|
|
68
|
+
return all
|
|
69
|
+
.map(([key, action]) => `${styleText('bold', key)} ${styleText('dim', action)}`)
|
|
70
|
+
.join(styleText('dim', ' • '));
|
|
71
|
+
};
|
|
47
72
|
/**
|
|
48
73
|
* Walks a card's options until the run asks for the card, or to leave.
|
|
49
74
|
*
|
|
@@ -55,21 +80,37 @@ const askOption = async (option, current) => {
|
|
|
55
80
|
export const navigateOptions = async (card, menu, status) => {
|
|
56
81
|
// The label carries a description after an em dash; the menu wants the name.
|
|
57
82
|
const [name = card.id] = card.label.split(' — ');
|
|
83
|
+
const width = Math.max(...card.options.map((option) => option.label.length));
|
|
58
84
|
for (;;) {
|
|
85
|
+
// A section none of this card's options sit under is dropped, heading and all.
|
|
86
|
+
const sections = OPTION_GROUPS.flatMap(({ group, label }) => {
|
|
87
|
+
const options = card.options.filter((option) => option.group === group);
|
|
88
|
+
if (options.length === 0) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return [
|
|
92
|
+
heading(label, width),
|
|
93
|
+
...options.map((option) => {
|
|
94
|
+
// An unanswered option recedes, so what is set reads as the foreground.
|
|
95
|
+
const answer = describeAnswer(option, menu.answers.get(option.name));
|
|
96
|
+
const value = answer === UNSET ? styleText('dim', answer) : answer;
|
|
97
|
+
return { name: `${option.label.padEnd(width)} ${value}`, value: option };
|
|
98
|
+
}),
|
|
99
|
+
];
|
|
100
|
+
});
|
|
59
101
|
const choice = await select({
|
|
60
102
|
message: status ? `${name} — ${status}` : `${name} — set an option, or generate`,
|
|
61
|
-
pageSize:
|
|
103
|
+
pageSize: menuHeight(),
|
|
104
|
+
theme: { style: { keysHelpTip } },
|
|
62
105
|
// Matched by reference against the values below, so the option objects work.
|
|
63
106
|
// `default` does not accept an explicit undefined, so an unset cursor omits it.
|
|
64
107
|
...(menu.cursor !== undefined && { default: menu.cursor }),
|
|
65
108
|
choices: [
|
|
109
|
+
heading('Actions', width),
|
|
66
110
|
{ name: 'Generate the card', value: 'generate' },
|
|
67
111
|
{ name: 'Save these options', value: 'save' },
|
|
68
112
|
{ name: 'Quit', value: 'quit' },
|
|
69
|
-
...
|
|
70
|
-
name: `${option.label.padEnd(38)} ${describeAnswer(option, menu.answers.get(option.name))}`,
|
|
71
|
-
value: option,
|
|
72
|
-
})),
|
|
113
|
+
...sections,
|
|
73
114
|
],
|
|
74
115
|
});
|
|
75
116
|
menu.cursor = choice;
|