@jakubmazanec/cli 0.2.1-unstable.ee5adfc → 0.3.0-next.2fa8a2c
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/README.md +1 -1
- package/build/constants.js +8 -0
- package/build/constants.js.map +7 -0
- package/build/main.js +4 -0
- package/build/main.js.map +7 -0
- package/{dist → build}/program/Command.d.ts +1 -1
- package/build/program/Command.js +70 -0
- package/build/program/Command.js.map +7 -0
- package/{dist → build}/program/CommandAction.d.ts +1 -1
- package/build/program/CommandAction.js +2 -0
- package/build/program/CommandAction.js.map +7 -0
- package/build/program/CommandArguments.js +2 -0
- package/build/program/CommandArguments.js.map +7 -0
- package/build/program/CommandOptions.js +2 -0
- package/build/program/CommandOptions.js.map +7 -0
- package/{dist → build}/program/Program.d.ts +1 -1
- package/build/program/Program.js +191 -0
- package/build/program/Program.js.map +7 -0
- package/build/program/ProgramCreateOptions.js +2 -0
- package/build/program/ProgramCreateOptions.js.map +7 -0
- package/build/program/ProgramDetail.js +2 -0
- package/build/program/ProgramDetail.js.map +7 -0
- package/{dist → build}/program/ProgramError.d.ts +1 -1
- package/build/program/ProgramError.js +6 -0
- package/build/program/ProgramError.js.map +7 -0
- package/build/program/ProgramOptions.js +2 -0
- package/build/program/ProgramOptions.js.map +7 -0
- package/build/program/ProgramStreams.js +2 -0
- package/build/program/ProgramStreams.js.map +7 -0
- package/build/program/getProgramDetail.js +25 -0
- package/build/program/getProgramDetail.js.map +7 -0
- package/build/program.js +13 -0
- package/build/program.js.map +7 -0
- package/build/ui/ErrorDetail.js +2 -0
- package/build/ui/ErrorDetail.js.map +7 -0
- package/build/ui/Failure.js +20 -0
- package/build/ui/Failure.js.map +7 -0
- package/build/ui/Header.js +19 -0
- package/build/ui/Header.js.map +7 -0
- package/build/ui/Help.js +38 -0
- package/build/ui/Help.js.map +7 -0
- package/build/ui/Spinner.js +24 -0
- package/build/ui/Spinner.js.map +7 -0
- package/build/ui/colors.js +12 -0
- package/build/ui/colors.js.map +7 -0
- package/build/ui/form/Form.js +2 -0
- package/build/ui/form/Form.js.map +7 -0
- package/build/ui/form/FormConfig.js +2 -0
- package/build/ui/form/FormConfig.js.map +7 -0
- package/build/ui/form/FormProps.js +2 -0
- package/build/ui/form/FormProps.js.map +7 -0
- package/build/ui/form/FormResult.js +2 -0
- package/build/ui/form/FormResult.js.map +7 -0
- package/build/ui/form/FormRow.js +71 -0
- package/build/ui/form/FormRow.js.map +7 -0
- package/build/ui/form/FormRowConfig.js +2 -0
- package/build/ui/form/FormRowConfig.js.map +7 -0
- package/build/ui/form/FormRowsConfig.js +2 -0
- package/build/ui/form/FormRowsConfig.js.map +7 -0
- package/build/ui/form/FormValue.js +2 -0
- package/build/ui/form/FormValue.js.map +7 -0
- package/build/ui/form/FormValues.js +2 -0
- package/build/ui/form/FormValues.js.map +7 -0
- package/{dist → build}/ui/form/SelectInput.d.ts +1 -1
- package/build/ui/form/SelectInput.js +86 -0
- package/build/ui/form/SelectInput.js.map +7 -0
- package/build/ui/form/SelectInputItem.js +2 -0
- package/build/ui/form/SelectInputItem.js.map +7 -0
- package/build/ui/form/TextInput.js +129 -0
- package/build/ui/form/TextInput.js.map +7 -0
- package/build/ui/form/createForm.js +73 -0
- package/build/ui/form/createForm.js.map +7 -0
- package/build/ui/form.js +15 -0
- package/build/ui/form.js.map +7 -0
- package/build/ui/getErrorDetail.js +65 -0
- package/build/ui/getErrorDetail.js.map +7 -0
- package/build/ui/icons.js +13 -0
- package/build/ui/icons.js.map +7 -0
- package/build/ui/internals/Wrapper.js +48 -0
- package/build/ui/internals/Wrapper.js.map +7 -0
- package/build/ui/internals/programContext.js +4 -0
- package/build/ui/internals/programContext.js.map +7 -0
- package/build/ui/internals/rotate.js +6 -0
- package/build/ui/internals/rotate.js.map +7 -0
- package/build/ui/internals.js +5 -0
- package/build/ui/internals.js.map +7 -0
- package/build/ui/useProgram.js +20 -0
- package/build/ui/useProgram.js.map +7 -0
- package/build/ui.js +12 -0
- package/build/ui.js.map +7 -0
- package/package.json +41 -36
- package/{src → source}/program/CommandAction.ts +1 -1
- package/{src → source}/program/Program.ts +4 -4
- package/{src → source}/ui/Failure.tsx +9 -9
- package/{src → source}/ui/Header.tsx +8 -4
- package/{src → source}/ui/Help.tsx +4 -4
- package/{src → source}/ui/Spinner.tsx +1 -1
- package/{src → source}/ui/form/FormProps.ts +12 -18
- package/{src → source}/ui/form/FormRow.tsx +9 -9
- package/{src → source}/ui/form/FormValue.ts +3 -4
- package/{src → source}/ui/form/SelectInput.tsx +11 -15
- package/{src → source}/ui/form/TextInput.tsx +13 -10
- package/{src → source}/ui/getErrorDetail.ts +1 -1
- package/{src → source}/ui/internals/Wrapper.tsx +4 -4
- package/dist/constants.js +0 -8
- package/dist/constants.js.map +0 -1
- package/dist/main.js +0 -4
- package/dist/main.js.map +0 -1
- package/dist/program/Command.js +0 -63
- package/dist/program/Command.js.map +0 -1
- package/dist/program/CommandAction.js +0 -3
- package/dist/program/CommandAction.js.map +0 -1
- package/dist/program/CommandArguments.js +0 -3
- package/dist/program/CommandArguments.js.map +0 -1
- package/dist/program/CommandOptions.js +0 -3
- package/dist/program/CommandOptions.js.map +0 -1
- package/dist/program/Program.js +0 -168
- package/dist/program/Program.js.map +0 -1
- package/dist/program/ProgramCreateOptions.js +0 -3
- package/dist/program/ProgramCreateOptions.js.map +0 -1
- package/dist/program/ProgramDetail.js +0 -5
- package/dist/program/ProgramDetail.js.map +0 -1
- package/dist/program/ProgramError.js +0 -8
- package/dist/program/ProgramError.js.map +0 -1
- package/dist/program/ProgramOptions.js +0 -3
- package/dist/program/ProgramOptions.js.map +0 -1
- package/dist/program/ProgramStreams.js +0 -5
- package/dist/program/ProgramStreams.js.map +0 -1
- package/dist/program/getProgramDetail.js +0 -27
- package/dist/program/getProgramDetail.js.map +0 -1
- package/dist/program.js +0 -13
- package/dist/program.js.map +0 -1
- package/dist/ui/ErrorDetail.js +0 -5
- package/dist/ui/ErrorDetail.js.map +0 -1
- package/dist/ui/Failure.js +0 -65
- package/dist/ui/Failure.js.map +0 -1
- package/dist/ui/Header.js +0 -26
- package/dist/ui/Header.js.map +0 -1
- package/dist/ui/Help.js +0 -64
- package/dist/ui/Help.js.map +0 -1
- package/dist/ui/Spinner.js +0 -39
- package/dist/ui/Spinner.js.map +0 -1
- package/dist/ui/colors.js +0 -12
- package/dist/ui/colors.js.map +0 -1
- package/dist/ui/form/Form.js +0 -3
- package/dist/ui/form/Form.js.map +0 -1
- package/dist/ui/form/FormConfig.js +0 -3
- package/dist/ui/form/FormConfig.js.map +0 -1
- package/dist/ui/form/FormProps.js +0 -3
- package/dist/ui/form/FormProps.js.map +0 -1
- package/dist/ui/form/FormResult.js +0 -3
- package/dist/ui/form/FormResult.js.map +0 -1
- package/dist/ui/form/FormRow.js +0 -59
- package/dist/ui/form/FormRow.js.map +0 -1
- package/dist/ui/form/FormRowConfig.js +0 -5
- package/dist/ui/form/FormRowConfig.js.map +0 -1
- package/dist/ui/form/FormRowsConfig.js +0 -3
- package/dist/ui/form/FormRowsConfig.js.map +0 -1
- package/dist/ui/form/FormValue.js +0 -3
- package/dist/ui/form/FormValue.js.map +0 -1
- package/dist/ui/form/FormValues.js +0 -3
- package/dist/ui/form/FormValues.js.map +0 -1
- package/dist/ui/form/SelectInput.js +0 -113
- package/dist/ui/form/SelectInput.js.map +0 -1
- package/dist/ui/form/SelectInputItem.js +0 -5
- package/dist/ui/form/SelectInputItem.js.map +0 -1
- package/dist/ui/form/TextInput.js +0 -152
- package/dist/ui/form/TextInput.js.map +0 -1
- package/dist/ui/form/createForm.js +0 -72
- package/dist/ui/form/createForm.js.map +0 -1
- package/dist/ui/form.js +0 -15
- package/dist/ui/form.js.map +0 -1
- package/dist/ui/getErrorDetail.js +0 -72
- package/dist/ui/getErrorDetail.js.map +0 -1
- package/dist/ui/icons.js +0 -13
- package/dist/ui/icons.js.map +0 -1
- package/dist/ui/internals/Wrapper.js +0 -66
- package/dist/ui/internals/Wrapper.js.map +0 -1
- package/dist/ui/internals/programContext.js +0 -6
- package/dist/ui/internals/programContext.js.map +0 -1
- package/dist/ui/internals/rotate.js +0 -17
- package/dist/ui/internals/rotate.js.map +0 -1
- package/dist/ui/internals.js +0 -5
- package/dist/ui/internals.js.map +0 -1
- package/dist/ui/useProgram.js +0 -25
- package/dist/ui/useProgram.js.map +0 -1
- package/dist/ui.js +0 -12
- package/dist/ui.js.map +0 -1
- package/{dist → build}/constants.d.ts +0 -0
- package/{dist → build}/main.d.ts +0 -0
- package/{dist → build}/program/CommandArguments.d.ts +0 -0
- package/{dist → build}/program/CommandOptions.d.ts +0 -0
- package/{dist → build}/program/ProgramCreateOptions.d.ts +0 -0
- package/{dist → build}/program/ProgramDetail.d.ts +0 -0
- package/{dist → build}/program/ProgramOptions.d.ts +0 -0
- package/{dist → build}/program/ProgramStreams.d.ts +0 -0
- package/{dist → build}/program/getProgramDetail.d.ts +0 -0
- package/{dist → build}/program.d.ts +0 -0
- package/{dist → build}/ui/ErrorDetail.d.ts +0 -0
- package/{dist → build}/ui/Failure.d.ts +0 -0
- package/{dist → build}/ui/Header.d.ts +0 -0
- package/{dist → build}/ui/Help.d.ts +0 -0
- package/{dist → build}/ui/Spinner.d.ts +0 -0
- package/{dist → build}/ui/colors.d.ts +0 -0
- package/{dist → build}/ui/form/Form.d.ts +0 -0
- package/{dist → build}/ui/form/FormConfig.d.ts +0 -0
- package/{dist → build}/ui/form/FormProps.d.ts +0 -0
- package/{dist → build}/ui/form/FormResult.d.ts +0 -0
- package/{dist → build}/ui/form/FormRow.d.ts +0 -0
- package/{dist → build}/ui/form/FormRowConfig.d.ts +0 -0
- package/{dist → build}/ui/form/FormRowsConfig.d.ts +0 -0
- package/{dist → build}/ui/form/FormValue.d.ts +0 -0
- package/{dist → build}/ui/form/FormValues.d.ts +0 -0
- package/{dist → build}/ui/form/SelectInputItem.d.ts +0 -0
- package/{dist → build}/ui/form/TextInput.d.ts +0 -0
- package/{dist → build}/ui/form/createForm.d.ts +0 -0
- package/{dist → build}/ui/form.d.ts +3 -3
- package/{dist → build}/ui/getErrorDetail.d.ts +0 -0
- package/{dist → build}/ui/icons.d.ts +0 -0
- package/{dist → build}/ui/internals/Wrapper.d.ts +0 -0
- package/{dist → build}/ui/internals/programContext.d.ts +0 -0
- package/{dist → build}/ui/internals/rotate.d.ts +0 -0
- package/{dist → build}/ui/internals.d.ts +0 -0
- package/{dist → build}/ui/useProgram.d.ts +0 -0
- package/{dist → build}/ui.d.ts +3 -3
- package/{src → source}/constants.ts +0 -0
- package/{src → source}/main.ts +0 -0
- package/{src → source}/program/Command.ts +2 -2
- package/{src → source}/program/CommandArguments.ts +0 -0
- package/{src → source}/program/CommandOptions.ts +0 -0
- package/{src → source}/program/ProgramCreateOptions.ts +0 -0
- package/{src → source}/program/ProgramDetail.ts +0 -0
- package/{src → source}/program/ProgramError.ts +0 -0
- package/{src → source}/program/ProgramOptions.ts +0 -0
- package/{src → source}/program/ProgramStreams.ts +0 -0
- package/{src → source}/program/getProgramDetail.ts +0 -0
- package/{src → source}/program.ts +0 -0
- package/{src → source}/ui/ErrorDetail.ts +0 -0
- package/{src → source}/ui/colors.ts +0 -0
- package/{src → source}/ui/form/Form.ts +0 -0
- package/{src → source}/ui/form/FormConfig.ts +0 -0
- package/{src → source}/ui/form/FormResult.ts +0 -0
- package/{src → source}/ui/form/FormRowConfig.ts +0 -0
- package/{src → source}/ui/form/FormRowsConfig.ts +0 -0
- package/{src → source}/ui/form/FormValues.ts +0 -0
- package/{src → source}/ui/form/SelectInputItem.ts +0 -0
- package/{src → source}/ui/form/createForm.tsx +0 -0
- package/{src → source}/ui/form.ts +3 -3
- package/{src → source}/ui/icons.ts +0 -0
- package/{src → source}/ui/internals/programContext.ts +0 -0
- package/{src → source}/ui/internals/rotate.ts +0 -0
- package/{src → source}/ui/internals.ts +0 -0
- package/{src → source}/ui/useProgram.ts +0 -0
- package/{src → source}/ui.ts +3 -3
|
@@ -6,21 +6,17 @@ import {type FormValues} from './FormValues.js';
|
|
|
6
6
|
|
|
7
7
|
/** A type that creates string literal union type with names of rows that need some props. */
|
|
8
8
|
type FormRowWithPropsNames<C extends FormConfig> = {
|
|
9
|
-
[P in keyof C['rows']]: C['rows'][P]['type'] extends 'text'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
: C['rows'][P]['type'] extends 'select'
|
|
14
|
-
? P
|
|
15
|
-
: never;
|
|
9
|
+
[P in keyof C['rows']]: C['rows'][P]['type'] extends 'text' ? never
|
|
10
|
+
: C['rows'][P]['type'] extends 'confirm' ? never
|
|
11
|
+
: C['rows'][P]['type'] extends 'select' ? P
|
|
12
|
+
: never;
|
|
16
13
|
}[keyof C['rows']];
|
|
17
14
|
|
|
18
|
-
type FormPropsRow<C extends FormRowConfig> =
|
|
19
|
-
? never
|
|
20
|
-
: C['type'] extends 'confirm'
|
|
21
|
-
?
|
|
22
|
-
|
|
23
|
-
? {
|
|
15
|
+
type FormPropsRow<C extends FormRowConfig> =
|
|
16
|
+
C['type'] extends 'text' ? never
|
|
17
|
+
: C['type'] extends 'confirm' ? never
|
|
18
|
+
: C['type'] extends 'select' ?
|
|
19
|
+
{
|
|
24
20
|
choices: Array<{value: string; label: string}>;
|
|
25
21
|
}
|
|
26
22
|
: never;
|
|
@@ -35,11 +31,9 @@ type FormPropsRows<C extends FormConfig> = Pick<
|
|
|
35
31
|
/**
|
|
36
32
|
* Form component props.
|
|
37
33
|
*/
|
|
38
|
-
export type FormProps<C extends FormConfig> =
|
|
39
|
-
number | string | symbol,
|
|
40
|
-
|
|
41
|
-
>
|
|
42
|
-
? BoxProps & {
|
|
34
|
+
export type FormProps<C extends FormConfig> =
|
|
35
|
+
FormPropsRows<C> extends Record<number | string | symbol, never> ?
|
|
36
|
+
BoxProps & {
|
|
43
37
|
/** Props for each row. */
|
|
44
38
|
rows?: null | undefined;
|
|
45
39
|
|
|
@@ -95,15 +95,15 @@ export function FormRow<C extends FormConfig>({
|
|
|
95
95
|
key={String(rowName)}
|
|
96
96
|
label={config.label ?? ''}
|
|
97
97
|
items={
|
|
98
|
-
rows
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
98
|
+
rows ?
|
|
99
|
+
(
|
|
100
|
+
(
|
|
101
|
+
rows as {
|
|
102
|
+
[key: string]: unknown;
|
|
103
|
+
}
|
|
104
|
+
)[rowName as string] as {choices: Array<{value: string; label: string}>}
|
|
105
|
+
).choices
|
|
106
|
+
: []
|
|
107
107
|
}
|
|
108
108
|
focus={focus}
|
|
109
109
|
isComplete={isComplete}
|
|
@@ -5,8 +5,7 @@ export type StringFormValue = {value: string; isComplete: boolean};
|
|
|
5
5
|
/**
|
|
6
6
|
* Form value.
|
|
7
7
|
*/
|
|
8
|
-
export type FormValue<C extends FormRowConfig> =
|
|
9
|
-
? StringFormValue
|
|
10
|
-
: C['type'] extends 'select'
|
|
11
|
-
? StringFormValue
|
|
8
|
+
export type FormValue<C extends FormRowConfig> =
|
|
9
|
+
C['type'] extends 'text' ? StringFormValue
|
|
10
|
+
: C['type'] extends 'select' ? StringFormValue
|
|
12
11
|
: never;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {Box, type BoxProps, Text, useInput
|
|
1
|
+
import {Box, type BoxProps, type Key, Text, useInput} from 'ink';
|
|
2
2
|
import _ from 'lodash';
|
|
3
|
-
import {
|
|
3
|
+
import {useEffect, useRef, useState} from 'react';
|
|
4
4
|
|
|
5
|
-
import {type SelectInputItem} from './SelectInputItem.js';
|
|
6
5
|
import * as colors from '../colors.js';
|
|
7
6
|
import * as icons from '../icons.js';
|
|
8
7
|
import {rotate} from '../internals.js';
|
|
8
|
+
import {type SelectInputItem} from './SelectInputItem.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* {@linkcode SelectInput} component props.
|
|
@@ -41,7 +41,7 @@ type SelectInputProps = BoxProps & {
|
|
|
41
41
|
*/
|
|
42
42
|
export function SelectInput({
|
|
43
43
|
label,
|
|
44
|
-
items
|
|
44
|
+
items,
|
|
45
45
|
focus = true,
|
|
46
46
|
initialIndex = 0,
|
|
47
47
|
limit: userDefinedLimit,
|
|
@@ -116,9 +116,8 @@ export function SelectInput({
|
|
|
116
116
|
{isActive: focus},
|
|
117
117
|
);
|
|
118
118
|
|
|
119
|
-
let visibleItems: SelectInputItem[] =
|
|
120
|
-
? rotate(items, rotatedIndex).slice(0, limit)
|
|
121
|
-
: items;
|
|
119
|
+
let visibleItems: SelectInputItem[] =
|
|
120
|
+
hasLimit ? rotate(items, rotatedIndex).slice(0, limit) : items;
|
|
122
121
|
|
|
123
122
|
return (
|
|
124
123
|
<Box {...boxProps}>
|
|
@@ -130,30 +129,27 @@ export function SelectInput({
|
|
|
130
129
|
<Box marginRight={1}>
|
|
131
130
|
<Text color={colors.highlighted}>{label}</Text>
|
|
132
131
|
</Box>
|
|
133
|
-
{isComplete ?
|
|
132
|
+
{isComplete ?
|
|
134
133
|
<Text color={colors.body}>
|
|
135
134
|
{items[selectedIndex]?.label ?? String(items[selectedIndex]?.value)}
|
|
136
135
|
</Text>
|
|
137
|
-
|
|
138
|
-
<Box flexDirection="column">
|
|
136
|
+
: <Box flexDirection="column">
|
|
139
137
|
{visibleItems.map((item, index) => {
|
|
140
138
|
let isSelected = index === selectedIndex;
|
|
141
139
|
|
|
142
140
|
return (
|
|
143
141
|
<Box key={item.value}>
|
|
144
142
|
<Box marginRight={1}>
|
|
145
|
-
{isSelected ?
|
|
143
|
+
{isSelected ?
|
|
146
144
|
<Text color={colors.selected}>{icons.selectedCircle}</Text>
|
|
147
|
-
|
|
148
|
-
<Text color={colors.unselected}>{icons.unselectedCircle}</Text>
|
|
149
|
-
)}
|
|
145
|
+
: <Text color={colors.unselected}>{icons.unselectedCircle}</Text>}
|
|
150
146
|
</Box>
|
|
151
147
|
<Text color={isSelected ? colors.highlighted : colors.muted}>{item.label}</Text>
|
|
152
148
|
</Box>
|
|
153
149
|
);
|
|
154
150
|
})}
|
|
155
151
|
</Box>
|
|
156
|
-
|
|
152
|
+
}
|
|
157
153
|
</Box>
|
|
158
154
|
</Box>
|
|
159
155
|
);
|
|
@@ -89,9 +89,9 @@ export function TextInput({
|
|
|
89
89
|
|
|
90
90
|
if (showCursor && focus) {
|
|
91
91
|
renderedPlaceholder =
|
|
92
|
-
placeholder.length > 0
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
placeholder.length > 0 ?
|
|
93
|
+
chalk.inverse(placeholder[0]) + chalk[colors.muted](placeholder.slice(1))
|
|
94
|
+
: chalk.inverse(' ');
|
|
95
95
|
|
|
96
96
|
renderedValue = value.length > 0 ? '' : chalk.inverse(' ');
|
|
97
97
|
|
|
@@ -205,18 +205,21 @@ export function TextInput({
|
|
|
205
205
|
<Box marginRight={1}>
|
|
206
206
|
<Text color={colors.highlighted}>{label}</Text>
|
|
207
207
|
</Box>
|
|
208
|
-
{isComplete ?
|
|
208
|
+
{isComplete ?
|
|
209
209
|
<Text color={colors.body}>{value}</Text>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
: <Text color={colors.highlighted}>
|
|
211
|
+
{placeholder ?
|
|
212
|
+
value.length > 0 ?
|
|
213
|
+
renderedValue
|
|
214
|
+
: renderedPlaceholder
|
|
215
|
+
: renderedValue}
|
|
213
216
|
</Text>
|
|
214
|
-
|
|
215
|
-
{validationError ?
|
|
217
|
+
}
|
|
218
|
+
{validationError ?
|
|
216
219
|
<Box marginTop={0}>
|
|
217
220
|
<Text color={colors.warning}>{validationError}</Text>
|
|
218
221
|
</Box>
|
|
219
|
-
|
|
222
|
+
: null}
|
|
220
223
|
</Box>
|
|
221
224
|
</Box>
|
|
222
225
|
);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {Box, Spacer, Text} from 'ink';
|
|
2
|
-
import {
|
|
2
|
+
import {type FC, type PropsWithChildren, useMemo} from 'react';
|
|
3
3
|
import {ErrorBoundary} from 'react-error-boundary';
|
|
4
4
|
|
|
5
|
-
import {programContext} from './programContext.js';
|
|
6
5
|
import {type Program} from '../../program.js';
|
|
7
6
|
import {highlighted, notice} from '../colors.js';
|
|
8
7
|
import {Failure} from '../Failure.js';
|
|
8
|
+
import {programContext} from './programContext.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* {@link Wrapper} component props.
|
|
@@ -28,7 +28,7 @@ export const Wrapper: FC<PropsWithChildren<WrapperProps>> = ({program, children}
|
|
|
28
28
|
return (
|
|
29
29
|
<ErrorBoundary FallbackComponent={Failure}>
|
|
30
30
|
<programContext.Provider value={programContextValue}>
|
|
31
|
-
{program.latestVersion && program.latestVersion !== program.version ?
|
|
31
|
+
{program.latestVersion && program.latestVersion !== program.version ?
|
|
32
32
|
<Box>
|
|
33
33
|
<Box
|
|
34
34
|
flexDirection="column"
|
|
@@ -49,7 +49,7 @@ export const Wrapper: FC<PropsWithChildren<WrapperProps>> = ({program, children}
|
|
|
49
49
|
</Box>
|
|
50
50
|
<Spacer />
|
|
51
51
|
</Box>
|
|
52
|
-
|
|
52
|
+
: null}
|
|
53
53
|
<Box>{children}</Box>
|
|
54
54
|
</programContext.Provider>
|
|
55
55
|
</ErrorBoundary>
|
package/dist/constants.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import url from 'node:url';
|
|
3
|
-
let directory = path.dirname(url.fileURLToPath(import.meta.url));
|
|
4
|
-
export const PACKAGE_PATH = path.resolve(directory, '..');
|
|
5
|
-
export const CACHE_PATH = path.resolve(PACKAGE_PATH, 'node_modules/.cache');
|
|
6
|
-
export const DELIMITER = '$ ';
|
|
7
|
-
|
|
8
|
-
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["import path from 'node:path';\nimport url from 'node:url';\n\nlet directory = path.dirname(url.fileURLToPath(import.meta.url));\n\nexport const PACKAGE_PATH = path.resolve(directory, '..');\nexport const CACHE_PATH = path.resolve(PACKAGE_PATH, 'node_modules/.cache');\n\nexport const DELIMITER = '$ ';\n"],"names":["path","url","directory","dirname","fileURLToPath","PACKAGE_PATH","resolve","CACHE_PATH","DELIMITER"],"mappings":"AAAA,OAAOA,UAAU,YAAY;AAC7B,OAAOC,SAAS,WAAW;AAE3B,IAAIC,YAAYF,KAAKG,OAAO,CAACF,IAAIG,aAAa,CAAC,YAAYH,GAAG;AAE9D,OAAO,MAAMI,eAAeL,KAAKM,OAAO,CAACJ,WAAW,MAAM;AAC1D,OAAO,MAAMK,aAAaP,KAAKM,OAAO,CAACD,cAAc,uBAAuB;AAE5E,OAAO,MAAMG,YAAY,KAAK"}
|
package/dist/main.js
DELETED
package/dist/main.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/main.ts"],"sourcesContent":["export * from './program.js';\nexport * from './ui.js';\n"],"names":[],"mappings":"AAAA,cAAc,eAAe;AAC7B,cAAc,UAAU"}
|
package/dist/program/Command.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { parseArguments } from '@jakubmazanec/args';
|
|
2
|
-
/**
|
|
3
|
-
* Command encapsulates piece of a CLI's logic and is executed when {@link Program} instance parses that command from the command line arguments.
|
|
4
|
-
*/ export class Command {
|
|
5
|
-
name;
|
|
6
|
-
description;
|
|
7
|
-
parameters;
|
|
8
|
-
options;
|
|
9
|
-
allowUnknownOptions;
|
|
10
|
-
allowUnknownParameters;
|
|
11
|
-
action;
|
|
12
|
-
/**
|
|
13
|
-
* @param name Command name, ie. space-separated words consisting only of letters, numbers (but not at the start of the word) or dashes.
|
|
14
|
-
* @param action Function that runs when command is executed.
|
|
15
|
-
* @param options Additionl command options.
|
|
16
|
-
*/ constructor(name, action, { description, parameters, options, allowUnknownOptions, allowUnknownParameters }){
|
|
17
|
-
this.name = name;
|
|
18
|
-
this.action = action;
|
|
19
|
-
if (description) {
|
|
20
|
-
this.description = description;
|
|
21
|
-
}
|
|
22
|
-
if (parameters) {
|
|
23
|
-
this.parameters = parameters;
|
|
24
|
-
} else {
|
|
25
|
-
this.parameters = null;
|
|
26
|
-
}
|
|
27
|
-
if (options) {
|
|
28
|
-
this.options = options;
|
|
29
|
-
} else {
|
|
30
|
-
this.options = null;
|
|
31
|
-
}
|
|
32
|
-
if (allowUnknownOptions) {
|
|
33
|
-
this.allowUnknownOptions = allowUnknownOptions;
|
|
34
|
-
} else {
|
|
35
|
-
this.allowUnknownOptions = false;
|
|
36
|
-
}
|
|
37
|
-
if (allowUnknownParameters) {
|
|
38
|
-
this.allowUnknownParameters = allowUnknownParameters;
|
|
39
|
-
} else {
|
|
40
|
-
this.allowUnknownParameters = false;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Parses a list of command line arguments into an arguments object. Parser is pre-configured based on this command.
|
|
45
|
-
*/ parseArguments(argv) {
|
|
46
|
-
return parseArguments(argv, {
|
|
47
|
-
commands: [
|
|
48
|
-
this.name
|
|
49
|
-
],
|
|
50
|
-
parameters: this.parameters ?? undefined,
|
|
51
|
-
options: this.options ?? undefined,
|
|
52
|
-
allowUnknownOptions: this.allowUnknownOptions,
|
|
53
|
-
allowUnknownParameters: this.allowUnknownParameters
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Executes command action with provided parsed arguments and {@link Program} instance.
|
|
58
|
-
*/ async run(parsedArgs, program) {
|
|
59
|
-
await this.action(parsedArgs, program);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
//# sourceMappingURL=Command.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/Command.ts"],"sourcesContent":["import {\n type Argv,\n parseArguments,\n type OptionsConfig,\n type ParametersConfig,\n type Arguments,\n} from '@jakubmazanec/args';\n\nimport {type CommandAction} from './CommandAction.js';\nimport {type CommandOptions} from './CommandOptions.js';\nimport {type Program} from './Program.js';\n\n/**\n * Command encapsulates piece of a CLI's logic and is executed when {@link Program} instance parses that command from the command line arguments.\n */\nexport class Command<\n A extends string,\n const B extends ParametersConfig | undefined = undefined,\n const C extends OptionsConfig | undefined = undefined,\n D extends boolean = false,\n E extends boolean = false,\n> {\n readonly name: A;\n readonly description?: string;\n readonly parameters: B extends ParametersConfig ? B : null;\n readonly options: C extends OptionsConfig ? C : null;\n readonly allowUnknownOptions: D;\n readonly allowUnknownParameters: E;\n private readonly action: CommandAction<A, B, C, D, E>;\n\n /**\n * @param name Command name, ie. space-separated words consisting only of letters, numbers (but not at the start of the word) or dashes.\n * @param action Function that runs when command is executed.\n * @param options Additionl command options.\n */\n constructor(\n name: A,\n action: CommandAction<A, B, C, D, E>,\n {\n description,\n parameters,\n options,\n allowUnknownOptions,\n allowUnknownParameters,\n }: CommandOptions<NonNullable<B>, NonNullable<C>, D, E>,\n ) {\n this.name = name;\n this.action = action;\n\n if (description) {\n this.description = description;\n }\n\n if (parameters) {\n this.parameters = parameters as B extends ParametersConfig ? B : null;\n } else {\n this.parameters = null as B extends ParametersConfig ? B : null;\n }\n\n if (options) {\n this.options = options as C extends OptionsConfig ? C : null;\n } else {\n this.options = null as C extends OptionsConfig ? C : null;\n }\n\n if (allowUnknownOptions) {\n this.allowUnknownOptions = allowUnknownOptions;\n } else {\n this.allowUnknownOptions = false as D;\n }\n\n if (allowUnknownParameters) {\n this.allowUnknownParameters = allowUnknownParameters;\n } else {\n this.allowUnknownParameters = false as E;\n }\n }\n\n /**\n * Parses a list of command line arguments into an arguments object. Parser is pre-configured based on this command.\n */\n parseArguments(argv: Argv): Arguments<{\n commands: readonly [A];\n parameters: B;\n options: C;\n allowUnknownOptions: D;\n allowUnknownParameters: E;\n }> {\n return parseArguments(argv, {\n commands: [this.name],\n parameters: this.parameters ?? undefined,\n options: this.options ?? undefined,\n allowUnknownOptions: this.allowUnknownOptions,\n allowUnknownParameters: this.allowUnknownParameters,\n } as {\n commands: readonly [A];\n parameters: B;\n options: C;\n allowUnknownOptions: D;\n allowUnknownParameters: E;\n });\n }\n\n /**\n * Executes command action with provided parsed arguments and {@link Program} instance.\n */\n async run(\n parsedArgs: Arguments<{\n commands: readonly [A];\n parameters: B;\n options: C;\n allowUnknownOptions: D;\n allowUnknownParameters: E;\n }>,\n program: Program,\n ): Promise<void> {\n await this.action(parsedArgs, program);\n }\n}\n"],"names":["parseArguments","Command","name","description","parameters","options","allowUnknownOptions","allowUnknownParameters","action","constructor","argv","commands","undefined","run","parsedArgs","program"],"mappings":"AAAA,SAEEA,cAAc,QAIT,qBAAqB;AAM5B;;CAEC,GACD,OAAO,MAAMC;IAOFC,KAAQ;IACRC,YAAqB;IACrBC,WAAkD;IAClDC,QAA4C;IAC5CC,oBAAuB;IACvBC,uBAA0B;IAClBC,OAAqC;IAEtD;;;;GAIC,GACDC,YACEP,IAAO,EACPM,MAAoC,EACpC,EACEL,WAAW,EACXC,UAAU,EACVC,OAAO,EACPC,mBAAmB,EACnBC,sBAAsB,EAC+B,CACvD;QACA,IAAI,CAACL,IAAI,GAAGA;QACZ,IAAI,CAACM,MAAM,GAAGA;QAEd,IAAIL,aAAa;YACf,IAAI,CAACA,WAAW,GAAGA;QACrB;QAEA,IAAIC,YAAY;YACd,IAAI,CAACA,UAAU,GAAGA;QACpB,OAAO;YACL,IAAI,CAACA,UAAU,GAAG;QACpB;QAEA,IAAIC,SAAS;YACX,IAAI,CAACA,OAAO,GAAGA;QACjB,OAAO;YACL,IAAI,CAACA,OAAO,GAAG;QACjB;QAEA,IAAIC,qBAAqB;YACvB,IAAI,CAACA,mBAAmB,GAAGA;QAC7B,OAAO;YACL,IAAI,CAACA,mBAAmB,GAAG;QAC7B;QAEA,IAAIC,wBAAwB;YAC1B,IAAI,CAACA,sBAAsB,GAAGA;QAChC,OAAO;YACL,IAAI,CAACA,sBAAsB,GAAG;QAChC;IACF;IAEA;;GAEC,GACDP,eAAeU,IAAU,EAMtB;QACD,OAAOV,eAAeU,MAAM;YAC1BC,UAAU;gBAAC,IAAI,CAACT,IAAI;aAAC;YACrBE,YAAY,IAAI,CAACA,UAAU,IAAIQ;YAC/BP,SAAS,IAAI,CAACA,OAAO,IAAIO;YACzBN,qBAAqB,IAAI,CAACA,mBAAmB;YAC7CC,wBAAwB,IAAI,CAACA,sBAAsB;QACrD;IAOF;IAEA;;GAEC,GACD,MAAMM,IACJC,UAME,EACFC,OAAgB,EACD;QACf,MAAM,IAAI,CAACP,MAAM,CAACM,YAAYC;IAChC;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/CommandAction.ts"],"sourcesContent":["import {type OptionsConfig, type ParametersConfig, type Arguments} from '@jakubmazanec/args';\n\nimport {type Program} from './Program.js';\n\n/**\n * Command action.\n */\nexport type CommandAction<\n A extends string,\n B extends ParametersConfig | undefined = undefined,\n C extends OptionsConfig | undefined = undefined,\n D extends boolean = false,\n E extends boolean = false,\n> = (\n parsedArgs: Arguments<{\n commands: readonly [A];\n parameters: B;\n options: C;\n allowUnknownOptions: D;\n allowUnknownParameters: E;\n }>,\n program: Program,\n) => Promise<void>;\n"],"names":[],"mappings":"AAAA,WAsBmB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/CommandArguments.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- needed */\nimport {type Command} from './Command.js';\n\n/**\n * Parsed command arguments type.\n */\nexport type CommandArguments<C extends Command<any, any, any, any, any>> = ReturnType<\n C['parseArguments']\n>;\n"],"names":[],"mappings":"AAAA,+DAA+D,GAC/D,WAOE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/CommandOptions.ts"],"sourcesContent":["import {type OptionsConfig, type ParametersConfig} from '@jakubmazanec/args';\n\n/**\n * {@link Command.constructor | Command constructor} options parameter.\n */\nexport type CommandOptions<\n B extends ParametersConfig,\n C extends OptionsConfig,\n D extends boolean,\n E extends boolean,\n> = {\n description?: string;\n parameters?: B | undefined;\n options?: C | undefined;\n allowUnknownOptions?: D | undefined;\n allowUnknownParameters?: E | undefined;\n};\n"],"names":[],"mappings":"AAAA,WAgBE"}
|
package/dist/program/Program.js
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any -- needed */ import fs from 'fs-extra';
|
|
2
|
-
import fetchLatestVersion from 'latest-version';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { ProgramError } from './ProgramError.js';
|
|
5
|
-
import { CACHE_PATH } from '../constants.js';
|
|
6
|
-
import { Wrapper } from '../ui/internals.js';
|
|
7
|
-
import { Failure, Help } from '../ui.js';
|
|
8
|
-
/**
|
|
9
|
-
* Program manages and executes {@link Command} instances attached to it based on parsing command line arguments.
|
|
10
|
-
*/ export class Program {
|
|
11
|
-
/** Program name. */ name;
|
|
12
|
-
/** More readable program name. */ displayName;
|
|
13
|
-
/** Program version. */ version;
|
|
14
|
-
/** Program latest version. */ latestVersion;
|
|
15
|
-
/** Program description. */ description;
|
|
16
|
-
/** Program executable name. */ bin;
|
|
17
|
-
/** Program commands */ commands = [];
|
|
18
|
-
isRendering = false;
|
|
19
|
-
streams = {
|
|
20
|
-
stderr: process.stderr,
|
|
21
|
-
stdin: process.stdin,
|
|
22
|
-
stdout: process.stdout
|
|
23
|
-
};
|
|
24
|
-
/** Custom error boundary fallback component */ ErrorBoundaryFallbackComponent;
|
|
25
|
-
constructor({ name, displayName, version, latestVersion, description, bin, ErrorBoundaryFallbackComponent }){
|
|
26
|
-
if (name) {
|
|
27
|
-
this.name = name;
|
|
28
|
-
}
|
|
29
|
-
if (displayName) {
|
|
30
|
-
this.displayName = displayName;
|
|
31
|
-
}
|
|
32
|
-
if (version) {
|
|
33
|
-
this.version = version;
|
|
34
|
-
}
|
|
35
|
-
if (latestVersion) {
|
|
36
|
-
this.latestVersion = latestVersion;
|
|
37
|
-
}
|
|
38
|
-
if (description) {
|
|
39
|
-
this.description = description;
|
|
40
|
-
}
|
|
41
|
-
if (bin) {
|
|
42
|
-
this.bin = bin;
|
|
43
|
-
}
|
|
44
|
-
if (ErrorBoundaryFallbackComponent) {
|
|
45
|
-
this.ErrorBoundaryFallbackComponent = ErrorBoundaryFallbackComponent;
|
|
46
|
-
} else {
|
|
47
|
-
this.ErrorBoundaryFallbackComponent = Failure;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
static async create({ name, version, description, bin, ErrorBoundaryFallbackComponent, checkForUpdate }) {
|
|
51
|
-
let latestVersion;
|
|
52
|
-
if (checkForUpdate && name) {
|
|
53
|
-
let cachePath = path.join(CACHE_PATH, name, 'latest-version.json');
|
|
54
|
-
let cachedLatestVersion;
|
|
55
|
-
try {
|
|
56
|
-
cachedLatestVersion = await fs.readJson(cachePath);
|
|
57
|
-
} catch {
|
|
58
|
-
// no-op
|
|
59
|
-
}
|
|
60
|
-
// if there is no cache or the cached value is old, refetch and recache
|
|
61
|
-
if (!cachedLatestVersion || Date.now() - cachedLatestVersion.datetime > 86_400_00) {
|
|
62
|
-
latestVersion = await fetchLatestVersion(name);
|
|
63
|
-
await fs.ensureFile(cachePath);
|
|
64
|
-
await fs.writeJson(cachePath, {
|
|
65
|
-
value: latestVersion,
|
|
66
|
-
datetime: Date.now()
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return new this({
|
|
71
|
-
name,
|
|
72
|
-
version,
|
|
73
|
-
latestVersion,
|
|
74
|
-
description,
|
|
75
|
-
bin,
|
|
76
|
-
ErrorBoundaryFallbackComponent
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Adds command to the program.
|
|
81
|
-
*
|
|
82
|
-
* @param command Command to add.
|
|
83
|
-
* @returns Program instance.
|
|
84
|
-
*/ addCommand(command) {
|
|
85
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- it doesn't matter here; `any` is used to make TypeScript happy in this method, but isn't propagated further.
|
|
86
|
-
this.commands.push(command);
|
|
87
|
-
return this;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Renders a React element using Ink and outputs to the configured streams.
|
|
91
|
-
*
|
|
92
|
-
* @param element The React element to render.
|
|
93
|
-
*/ async renderElement(element) {
|
|
94
|
-
if (this.isRendering) {
|
|
95
|
-
throw new ProgramError('NO_NESTED_RENDER');
|
|
96
|
-
} else {
|
|
97
|
-
this.isRendering = true;
|
|
98
|
-
}
|
|
99
|
-
let { render } = await import('ink');
|
|
100
|
-
let { createElement } = await import('react');
|
|
101
|
-
let { stdin, stdout, stderr } = this.streams;
|
|
102
|
-
try {
|
|
103
|
-
render(createElement(Wrapper, {
|
|
104
|
-
program: this
|
|
105
|
-
}, element), {
|
|
106
|
-
exitOnCtrlC: true,
|
|
107
|
-
patchConsole: true,
|
|
108
|
-
stderr,
|
|
109
|
-
stdin,
|
|
110
|
-
stdout
|
|
111
|
-
});
|
|
112
|
-
} catch (error) {
|
|
113
|
-
if (error instanceof Error) {
|
|
114
|
-
await this.renderElement(createElement(this.ErrorBoundaryFallbackComponent, {
|
|
115
|
-
error,
|
|
116
|
-
resetErrorBoundary: ()=>{}
|
|
117
|
-
}));
|
|
118
|
-
}
|
|
119
|
-
} finally{
|
|
120
|
-
this.isRendering = false;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Runs the program.
|
|
125
|
-
*
|
|
126
|
-
* @param argv Unparsed command line arguments.
|
|
127
|
-
*/ async run(argv) {
|
|
128
|
-
let hasCommandRun = false;
|
|
129
|
-
for (let command of this.commands){
|
|
130
|
-
let parsedArgs = command.parseArguments(argv);
|
|
131
|
-
if (parsedArgs.command) {
|
|
132
|
-
hasCommandRun = true;
|
|
133
|
-
if (parsedArgs.errors.length) {
|
|
134
|
-
let { createElement } = await import('react');
|
|
135
|
-
for (let error of parsedArgs.errors){
|
|
136
|
-
process.exitCode = 1;
|
|
137
|
-
await this.renderElement(createElement(this.ErrorBoundaryFallbackComponent, {
|
|
138
|
-
error,
|
|
139
|
-
resetErrorBoundary: ()=>{}
|
|
140
|
-
}));
|
|
141
|
-
}
|
|
142
|
-
} else {
|
|
143
|
-
try {
|
|
144
|
-
await command.run(parsedArgs, this);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
let { createElement } = await import('react');
|
|
147
|
-
if (error instanceof Error) {
|
|
148
|
-
process.exitCode = 1;
|
|
149
|
-
await this.renderElement(createElement(this.ErrorBoundaryFallbackComponent, {
|
|
150
|
-
error,
|
|
151
|
-
resetErrorBoundary: ()=>{}
|
|
152
|
-
}));
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
break;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
if (!hasCommandRun) {
|
|
160
|
-
let { createElement } = await import('react');
|
|
161
|
-
await this.renderElement(createElement(Help, {
|
|
162
|
-
program: this
|
|
163
|
-
}));
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
//# sourceMappingURL=Program.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/Program.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- needed */\nimport {type ParametersConfig, type Argv, type OptionsConfig} from '@jakubmazanec/args';\nimport fs from 'fs-extra';\nimport fetchLatestVersion from 'latest-version';\nimport path from 'path';\nimport {type ComponentType} from 'react';\nimport {type FallbackProps} from 'react-error-boundary';\n\nimport {type Command} from './Command.js';\nimport {type ProgramCreateOptions} from './ProgramCreateOptions.js';\nimport {ProgramError} from './ProgramError.js';\nimport {type ProgramOptions} from './ProgramOptions.js';\nimport {type ProgramStreams} from './ProgramStreams.js';\nimport {CACHE_PATH} from '../constants.js';\nimport {Wrapper} from '../ui/internals.js';\nimport {Failure, Help} from '../ui.js';\n\n/**\n * Program manages and executes {@link Command} instances attached to it based on parsing command line arguments.\n */\nexport class Program {\n /** Program name. */\n readonly name?: string;\n\n /** More readable program name. */\n readonly displayName?: string;\n\n /** Program version. */\n readonly version?: string;\n\n /** Program latest version. */\n readonly latestVersion?: string;\n\n /** Program description. */\n readonly description?: string;\n\n /** Program executable name. */\n readonly bin?: string;\n\n /** Program commands */\n readonly commands: Array<\n Command<string, ParametersConfig | undefined, OptionsConfig | undefined, boolean, boolean>\n > = [];\n\n protected isRendering = false;\n\n readonly streams: ProgramStreams = {\n stderr: process.stderr,\n stdin: process.stdin,\n stdout: process.stdout,\n };\n\n /** Custom error boundary fallback component */\n ErrorBoundaryFallbackComponent: ComponentType<FallbackProps>;\n\n private constructor({\n name,\n displayName,\n version,\n latestVersion,\n description,\n bin,\n ErrorBoundaryFallbackComponent,\n }: ProgramOptions) {\n if (name) {\n this.name = name;\n }\n\n if (displayName) {\n this.displayName = displayName;\n }\n\n if (version) {\n this.version = version;\n }\n\n if (latestVersion) {\n this.latestVersion = latestVersion;\n }\n\n if (description) {\n this.description = description;\n }\n\n if (bin) {\n this.bin = bin;\n }\n\n if (ErrorBoundaryFallbackComponent) {\n this.ErrorBoundaryFallbackComponent = ErrorBoundaryFallbackComponent;\n } else {\n this.ErrorBoundaryFallbackComponent = Failure;\n }\n }\n\n static async create({\n name,\n version,\n description,\n bin,\n ErrorBoundaryFallbackComponent,\n checkForUpdate,\n }: ProgramCreateOptions) {\n let latestVersion: string | undefined;\n\n if (checkForUpdate && name) {\n // first we try to read the cached latest version\n type CachedLatestVersion = {\n value: string;\n datetime: number;\n };\n\n let cachePath = path.join(CACHE_PATH, name, 'latest-version.json');\n let cachedLatestVersion: CachedLatestVersion | undefined;\n\n try {\n cachedLatestVersion = (await fs.readJson(cachePath)) as CachedLatestVersion;\n } catch {\n // no-op\n }\n\n // if there is no cache or the cached value is old, refetch and recache\n if (!cachedLatestVersion || Date.now() - cachedLatestVersion.datetime > 86_400_00) {\n latestVersion = await fetchLatestVersion(name);\n\n await fs.ensureFile(cachePath);\n await fs.writeJson(cachePath, {\n value: latestVersion,\n datetime: Date.now(),\n });\n }\n }\n\n return new this({\n name,\n version,\n latestVersion,\n description,\n bin,\n ErrorBoundaryFallbackComponent,\n });\n }\n\n /**\n * Adds command to the program.\n *\n * @param command Command to add.\n * @returns Program instance.\n */\n addCommand(command: Command<any, any, any, any, any>): this {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- it doesn't matter here; `any` is used to make TypeScript happy in this method, but isn't propagated further.\n this.commands.push(command);\n\n return this;\n }\n\n /**\n * Renders a React element using Ink and outputs to the configured streams.\n *\n * @param element The React element to render.\n */\n async renderElement(element: React.ReactElement): Promise<void> {\n if (this.isRendering) {\n throw new ProgramError('NO_NESTED_RENDER');\n } else {\n this.isRendering = true;\n }\n\n let {render} = await import('ink');\n let {createElement} = await import('react');\n let {stdin, stdout, stderr} = this.streams;\n\n try {\n render(createElement(Wrapper, {program: this}, element), {\n exitOnCtrlC: true,\n patchConsole: true,\n stderr,\n stdin,\n stdout,\n });\n } catch (error: unknown) {\n if (error instanceof Error) {\n await this.renderElement(\n createElement(this.ErrorBoundaryFallbackComponent, {error, resetErrorBoundary: () => {}}),\n );\n }\n } finally {\n this.isRendering = false;\n }\n }\n\n /**\n * Runs the program.\n *\n * @param argv Unparsed command line arguments.\n */\n async run(argv: Argv): Promise<void> {\n let hasCommandRun = false;\n\n for (let command of this.commands) {\n let parsedArgs = command.parseArguments(argv);\n\n if (parsedArgs.command) {\n hasCommandRun = true;\n\n if (parsedArgs.errors.length) {\n let {createElement} = await import('react');\n\n for (let error of parsedArgs.errors) {\n process.exitCode = 1;\n\n await this.renderElement(\n createElement(this.ErrorBoundaryFallbackComponent, {\n error,\n resetErrorBoundary: () => {},\n }),\n );\n }\n } else {\n try {\n await command.run(parsedArgs, this);\n } catch (error: unknown) {\n let {createElement} = await import('react');\n\n if (error instanceof Error) {\n process.exitCode = 1;\n\n await this.renderElement(\n createElement(this.ErrorBoundaryFallbackComponent, {\n error,\n resetErrorBoundary: () => {},\n }),\n );\n }\n }\n\n break;\n }\n }\n }\n\n if (!hasCommandRun) {\n let {createElement} = await import('react');\n\n await this.renderElement(createElement(Help, {program: this}));\n }\n }\n}\n"],"names":["fs","fetchLatestVersion","path","ProgramError","CACHE_PATH","Wrapper","Failure","Help","Program","name","displayName","version","latestVersion","description","bin","commands","isRendering","streams","stderr","process","stdin","stdout","ErrorBoundaryFallbackComponent","create","checkForUpdate","cachePath","join","cachedLatestVersion","readJson","Date","now","datetime","ensureFile","writeJson","value","addCommand","command","push","renderElement","element","render","createElement","program","exitOnCtrlC","patchConsole","error","Error","resetErrorBoundary","run","argv","hasCommandRun","parsedArgs","parseArguments","errors","length","exitCode"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/ProgramCreateOptions.ts"],"sourcesContent":["import {type ComponentType} from 'react';\nimport {type FallbackProps} from 'react-error-boundary';\n\n/**\n * {@link Program.create} options parameter.\n */\nexport type ProgramCreateOptions = {\n /** Program name. */\n name?: string | undefined;\n\n /** More readable program name. */\n displayName?: string | undefined;\n\n /** Program version. */\n version?: string | undefined;\n\n /** Program description. */\n description?: string | undefined;\n\n /** Program executable name. */\n bin?: string | undefined;\n\n /** Custom error boundary fallback component */\n ErrorBoundaryFallbackComponent?: ComponentType<FallbackProps>;\n\n /** Perform check whether a newer version of the program is available. */\n checkForUpdate?: boolean;\n};\n"],"names":[],"mappings":"AAAA,WA2BE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/ProgramDetail.ts"],"sourcesContent":["/**\n * Detailed program information.\n */\nexport type ProgramDetail = {\n name?: string;\n version?: string;\n description?: string;\n bin?: string;\n};\n"],"names":[],"mappings":"AAAA;;CAEC,GACD,WAKE"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { createCustomError } from '@jakubmazanec/error';
|
|
2
|
-
/**
|
|
3
|
-
* A subclass of `Error` that indicates a program failure.
|
|
4
|
-
*/ export const ProgramError = createCustomError('ProgramError', {
|
|
5
|
-
NO_NESTED_RENDER: 'A React render process already exists. This usually occurs by triggering nested render calls.'
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
//# sourceMappingURL=ProgramError.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/ProgramError.ts"],"sourcesContent":["import {createCustomError} from '@jakubmazanec/error';\n\n/**\n * A subclass of `Error` that indicates a program failure.\n */\nexport const ProgramError = createCustomError('ProgramError', {\n NO_NESTED_RENDER:\n 'A React render process already exists. This usually occurs by triggering nested render calls.',\n});\n"],"names":["createCustomError","ProgramError","NO_NESTED_RENDER"],"mappings":"AAAA,SAAQA,iBAAiB,QAAO,sBAAsB;AAEtD;;CAEC,GACD,OAAO,MAAMC,eAAeD,kBAAkB,gBAAgB;IAC5DE,kBACE;AACJ,GAAG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/ProgramOptions.ts"],"sourcesContent":["import {type ComponentType} from 'react';\nimport {type FallbackProps} from 'react-error-boundary';\n\n/**\n * {@link Program.constructor | Program constructor} options parameter.\n */\nexport type ProgramOptions = {\n /** Program name. */\n name?: string | undefined;\n\n /** More readable program name. */\n displayName?: string | undefined;\n\n /** Program version. */\n version?: string | undefined;\n\n /** Program latest version. */\n latestVersion?: string | undefined;\n\n /** Program description. */\n description?: string | undefined;\n\n /** Program executable name. */\n bin?: string | undefined;\n\n /** Custom error boundary fallback component */\n ErrorBoundaryFallbackComponent?: ComponentType<FallbackProps> | undefined;\n\n /** Perform check whether a newer version of the program is available. */\n checkForUpdate?: boolean;\n};\n"],"names":[],"mappings":"AAAA,WA8BE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/program/ProgramStreams.ts"],"sourcesContent":["/**\n * {@link Program} streams;\n */\nexport type ProgramStreams = {\n stderr: NodeJS.WriteStream;\n stdin: NodeJS.ReadStream;\n stdout: NodeJS.WriteStream;\n};\n"],"names":[],"mappings":"AAAA;;CAEC,GACD,WAIE"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates detailed information about a {@lincode Program}.
|
|
3
|
-
*/ export function getProgramDetail(packageJson) {
|
|
4
|
-
let programDetail = {};
|
|
5
|
-
if (packageJson.name) {
|
|
6
|
-
programDetail.name = packageJson.name;
|
|
7
|
-
}
|
|
8
|
-
if (packageJson.version) {
|
|
9
|
-
programDetail.version = packageJson.version;
|
|
10
|
-
}
|
|
11
|
-
if (packageJson.description) {
|
|
12
|
-
programDetail.description = packageJson.description;
|
|
13
|
-
}
|
|
14
|
-
if (packageJson.bin && typeof packageJson.bin !== 'string') {
|
|
15
|
-
let bins = Object.entries(packageJson.bin);
|
|
16
|
-
if (bins.length === 1) {
|
|
17
|
-
let firstBin = bins[0];
|
|
18
|
-
[programDetail.bin] = firstBin;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
if (typeof packageJson.bin === 'string' && packageJson.name) {
|
|
22
|
-
programDetail.bin = packageJson.name;
|
|
23
|
-
}
|
|
24
|
-
return programDetail;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
//# sourceMappingURL=getProgramDetail.js.map
|