Skip to content

Commit 37510ee

Browse files
committed
Breaking: Remove async message feature (#1322)
1 parent b35b6bb commit 37510ee

File tree

12 files changed

+45
-104
lines changed

12 files changed

+45
-104
lines changed

packages/checkbox/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
isNumberKey,
1212
isEnterKey,
1313
Separator,
14-
type PromptConfig,
1514
} from '@inquirer/core';
1615
import type {} from '@inquirer/type';
1716
import chalk from 'chalk';
@@ -26,7 +25,8 @@ type Choice<Value> = {
2625
type?: never;
2726
};
2827

29-
type Config<Value> = PromptConfig<{
28+
type Config<Value> = {
29+
message: string;
3030
prefix?: string;
3131
pageSize?: number;
3232
instructions?: string | boolean;
@@ -36,7 +36,7 @@ type Config<Value> = PromptConfig<{
3636
validate?: (
3737
items: ReadonlyArray<Item<Value>>,
3838
) => boolean | string | Promise<string | boolean>;
39-
}>;
39+
};
4040

4141
type Item<Value> = Separator | Choice<Value>;
4242

packages/confirm/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import {
55
useKeypress,
66
isEnterKey,
77
usePrefix,
8-
type PromptConfig,
98
} from '@inquirer/core';
109
import type {} from '@inquirer/type';
1110

12-
type ConfirmConfig = PromptConfig<{
11+
type ConfirmConfig = {
12+
message: string;
1313
default?: boolean;
1414
transformer?: (value: boolean) => string;
15-
}>;
15+
};
1616

1717
export default createPrompt<boolean, ConfirmConfig>((config, done) => {
1818
const { transformer = (answer) => (answer ? 'yes' : 'no') } = config;

packages/core/core.test.mts

-38
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,6 @@ import {
1818
} from './src/index.mjs';
1919

2020
describe('createPrompt()', () => {
21-
it('handle async function message', async () => {
22-
const viewFunction = vi.fn(() => '');
23-
const prompt = createPrompt(viewFunction);
24-
const promise = Promise.resolve('Async message:');
25-
const renderingDone = render(prompt, { message: () => promise });
26-
27-
// Initially, we leave a few ms for message to resolve
28-
expect(viewFunction).not.toHaveBeenCalled();
29-
30-
const { answer } = await renderingDone;
31-
expect(viewFunction).toHaveBeenLastCalledWith(
32-
expect.objectContaining({ message: 'Async message:' }),
33-
expect.any(Function),
34-
);
35-
36-
answer.cancel();
37-
await expect(answer).rejects.toBeInstanceOf(Error);
38-
});
39-
40-
it('handle deferred message', async () => {
41-
const viewFunction = vi.fn(() => '');
42-
const prompt = createPrompt(viewFunction);
43-
const promise = Promise.resolve('Async message:');
44-
const renderingDone = render(prompt, { message: promise });
45-
46-
// Initially, we leave a few ms for message to resolve
47-
expect(viewFunction).not.toHaveBeenCalled();
48-
49-
const { answer } = await renderingDone;
50-
expect(viewFunction).toHaveBeenLastCalledWith(
51-
expect.objectContaining({ message: 'Async message:' }),
52-
expect.any(Function),
53-
);
54-
55-
answer.cancel();
56-
await expect(answer).rejects.toBeInstanceOf(Error);
57-
});
58-
5921
it('onKeypress: allow to implement custom behavior on keypress', async () => {
6022
const Prompt = (config: { message: string }, done: (value: string) => void) => {
6123
const [value, setValue] = useState('');

packages/core/src/index.mts

+1-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ export { useMemo } from './lib/use-memo.mjs';
66
export { useRef } from './lib/use-ref.mjs';
77
export { useKeypress } from './lib/use-keypress.mjs';
88
export { usePagination } from './lib/pagination/use-pagination.mjs';
9-
export {
10-
createPrompt,
11-
type PromptConfig,
12-
type AsyncPromptConfig,
13-
} from './lib/create-prompt.mjs';
9+
export { createPrompt } from './lib/create-prompt.mjs';
1410
export { Separator } from './lib/Separator.mjs';
1511
export { type InquirerReadline } from './lib/read-line.type.mjs';

packages/core/src/lib/create-prompt.mts

+10-37
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,12 @@ import ScreenManager from './screen-manager.mjs';
66
import type { InquirerReadline } from './read-line.type.mjs';
77
import { withHooks, effectScheduler } from './hook-engine.mjs';
88

9-
// @deprecated Prefer using `PromptConfig<{ ... }>` instead
10-
export type AsyncPromptConfig = {
11-
message: string | Promise<string> | (() => Promise<string>);
12-
};
13-
14-
export type PromptConfig<Config> = Prettify<AsyncPromptConfig & Config>;
15-
16-
type ResolvedPromptConfig = { message: string };
17-
189
type ViewFunction<Value, Config> = (
19-
config: Prettify<Config & ResolvedPromptConfig>,
10+
config: Prettify<Config>,
2011
done: (value: Value) => void,
2112
) => string | [string, string | undefined];
2213

23-
// Take an AsyncPromptConfig and resolves all it's values.
24-
async function getPromptConfig<Config extends AsyncPromptConfig>(
25-
config: Config,
26-
): Promise<Config & ResolvedPromptConfig> {
27-
const message =
28-
typeof config.message === 'function' ? config.message() : config.message;
29-
30-
return {
31-
...config,
32-
message: await message,
33-
};
34-
}
35-
36-
export function createPrompt<Value, Config extends AsyncPromptConfig>(
37-
view: ViewFunction<Value, Config>,
38-
) {
14+
export function createPrompt<Value, Config>(view: ViewFunction<Value, Config>) {
3915
const prompt: Prompt<Value, Config> = (config, context) => {
4016
// Default `input` to stdin
4117
const input = context?.input ?? process.stdin;
@@ -98,12 +74,12 @@ export function createPrompt<Value, Config extends AsyncPromptConfig>(
9874
});
9975
}
10076

101-
function workLoop(resolvedConfig: Config & ResolvedPromptConfig) {
77+
function workLoop(resolvedConfig: Config) {
10278
store.index = 0;
10379
store.handleChange = () => workLoop(resolvedConfig);
10480

10581
try {
106-
const nextView = view(resolvedConfig, done);
82+
const nextView = view(config, done);
10783

10884
const [content, bottomContent] =
10985
typeof nextView === 'string' ? [nextView] : nextView;
@@ -116,16 +92,13 @@ export function createPrompt<Value, Config extends AsyncPromptConfig>(
11692
}
11793
}
11894

119-
// TODO: we should display a loader while we get the default options.
120-
getPromptConfig(config).then((resolvedConfig) => {
121-
workLoop(resolvedConfig);
95+
workLoop(config);
12296

123-
// Re-renders only happen when the state change; but the readline cursor could change position
124-
// and that also requires a re-render (and a manual one because we mute the streams).
125-
// We set the listener after the initial workLoop to avoid a double render if render triggered
126-
// by a state change sets the cursor to the right position.
127-
store.rl.input.on('keypress', checkCursorPos);
128-
}, reject);
97+
// Re-renders only happen when the state change; but the readline cursor could change position
98+
// and that also requires a re-render (and a manual one because we mute the streams).
99+
// We set the listener after the initial workLoop to avoid a double render if render triggered
100+
// by a state change sets the cursor to the right position.
101+
store.rl.input.on('keypress', checkCursorPos);
129102
});
130103
});
131104

packages/editor/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ import {
77
useKeypress,
88
usePrefix,
99
isEnterKey,
10-
type PromptConfig,
1110
type InquirerReadline,
1211
} from '@inquirer/core';
1312
import type {} from '@inquirer/type';
1413

15-
type EditorConfig = PromptConfig<{
14+
type EditorConfig = {
15+
message: string;
1616
default?: string;
1717
postfix?: string;
1818
waitForUseInput?: boolean;
1919
validate?: (value: string) => boolean | string | Promise<string | boolean>;
20-
}>;
20+
};
2121

2222
export default createPrompt<string, EditorConfig>((config, done) => {
2323
const { waitForUseInput = true, validate = () => true } = config;

packages/expand/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
useKeypress,
55
usePrefix,
66
isEnterKey,
7-
type PromptConfig,
87
} from '@inquirer/core';
98
import type {} from '@inquirer/type';
109
import chalk from 'chalk';
@@ -14,11 +13,12 @@ type ExpandChoice =
1413
| { key: string; value: string }
1514
| { key: string; name: string; value: string };
1615

17-
type ExpandConfig = PromptConfig<{
16+
type ExpandConfig = {
17+
message: string;
1818
choices: ReadonlyArray<ExpandChoice>;
1919
default?: string;
2020
expanded?: boolean;
21-
}>;
21+
};
2222

2323
const helpChoice = {
2424
key: 'h',

packages/input/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ import {
55
usePrefix,
66
isEnterKey,
77
isBackspaceKey,
8-
type PromptConfig,
98
} from '@inquirer/core';
109
import type {} from '@inquirer/type';
1110
import chalk from 'chalk';
1211

13-
type InputConfig = PromptConfig<{
12+
type InputConfig = {
13+
message: string;
1414
default?: string;
1515
transformer?: (value: string, { isFinal }: { isFinal: boolean }) => string;
1616
validate?: (value: string) => boolean | string | Promise<string | boolean>;
17-
}>;
17+
};
1818

1919
export default createPrompt<string, InputConfig>((config, done) => {
2020
const { validate = () => true } = config;

packages/password/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import {
44
useKeypress,
55
usePrefix,
66
isEnterKey,
7-
type PromptConfig,
87
} from '@inquirer/core';
98
import chalk from 'chalk';
109
import ansiEscapes from 'ansi-escapes';
1110

12-
type PasswordConfig = PromptConfig<{
11+
type PasswordConfig = {
12+
message: string;
1313
mask?: boolean | string;
1414
validate?: (value: string) => boolean | string | Promise<string | boolean>;
15-
}>;
15+
};
1616

1717
export default createPrompt<string, PasswordConfig>((config, done) => {
1818
const { validate = () => true } = config;

packages/prompts/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,16 @@ exec < /dev/tty
234234
node my-script.js
235235
```
236236

237+
## Wait for config
238+
239+
Maybe some question configuration require to await a value.
240+
241+
```js
242+
import { confirm } from '@inquirer/prompts';
243+
244+
const answer = await confirm({ message: await getMessage() });
245+
```
246+
237247
# Community prompts
238248

239249
If you created a cool prompt, [send us a PR adding it](https://github.com/SBoudrias/Inquirer.js/edit/master/README.md) to the list below!

packages/rawlist/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
usePrefix,
66
isEnterKey,
77
Separator,
8-
type PromptConfig,
98
} from '@inquirer/core';
109
import type {} from '@inquirer/type';
1110
import chalk from 'chalk';
@@ -18,9 +17,10 @@ type Choice<Value> = {
1817
key?: string;
1918
};
2019

21-
type RawlistConfig<Value> = PromptConfig<{
20+
type RawlistConfig<Value> = {
21+
message: string;
2222
choices: ReadonlyArray<Choice<Value> | Separator>;
23-
}>;
23+
};
2424

2525
function isSelectableChoice<T>(
2626
choice: undefined | Separator | Choice<T>,

packages/select/src/index.mts

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
isDownKey,
1212
isNumberKey,
1313
Separator,
14-
type PromptConfig,
1514
} from '@inquirer/core';
1615
import type {} from '@inquirer/type';
1716
import chalk from 'chalk';
@@ -26,12 +25,13 @@ type Choice<Value> = {
2625
type?: never;
2726
};
2827

29-
type SelectConfig<Value> = PromptConfig<{
28+
type SelectConfig<Value> = {
29+
message: string;
3030
choices: ReadonlyArray<Choice<Value> | Separator>;
3131
pageSize?: number;
3232
loop?: boolean;
3333
default?: unknown;
34-
}>;
34+
};
3535

3636
type Item<Value> = Separator | Choice<Value>;
3737

0 commit comments

Comments
 (0)