@shopify/cli-kit 3.44.1 → 3.45.0-pre.1

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.
Files changed (93) hide show
  1. package/README.md +15 -7
  2. package/assets/cli-ruby/lib/project_types/extension/messages/messages.rb +0 -2
  3. package/assets/cli-ruby/lib/project_types/theme/commands/pull.rb +6 -0
  4. package/assets/cli-ruby/lib/project_types/theme/commands/push.rb +6 -0
  5. package/assets/cli-ruby/lib/shopify_cli/constants.rb +1 -0
  6. package/assets/cli-ruby/lib/shopify_cli/environment.rb +4 -0
  7. package/assets/cli-ruby/lib/shopify_cli/theme/dev_server/proxy.rb +3 -0
  8. package/assets/cli-ruby/lib/shopify_cli/theme/extension/dev_server.rb +3 -3
  9. package/assets/cli-ruby/lib/shopify_cli/theme/extension/host_theme.rb +4 -4
  10. package/assets/cli-ruby/lib/shopify_cli/theme/extension/syncer/extension_serve_job.rb +4 -6
  11. package/assets/cli-ruby/lib/shopify_cli/theme/extension/ui/host_theme_raw_progress_bar.rb +40 -0
  12. package/assets/cli-ruby/vendor/deps/cli-ui/lib/cli/ui/progress_plain.rb +50 -0
  13. package/assets/cli-ruby/vendor/deps/cli-ui/lib/cli/ui.rb +15 -14
  14. package/dist/private/node/api/graphql.js +12 -23
  15. package/dist/private/node/api/graphql.js.map +1 -1
  16. package/dist/private/node/api.d.ts +1 -1
  17. package/dist/private/node/api.js +28 -9
  18. package/dist/private/node/api.js.map +1 -1
  19. package/dist/private/node/constants.d.ts +0 -1
  20. package/dist/private/node/constants.js +0 -1
  21. package/dist/private/node/constants.js.map +1 -1
  22. package/dist/private/node/testing/ui.d.ts +11 -0
  23. package/dist/private/node/testing/ui.js +15 -1
  24. package/dist/private/node/testing/ui.js.map +1 -1
  25. package/dist/private/node/ui/alert.d.ts +5 -1
  26. package/dist/private/node/ui/alert.js +2 -2
  27. package/dist/private/node/ui/alert.js.map +1 -1
  28. package/dist/private/node/ui/components/AutocompletePrompt.js +38 -12
  29. package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -1
  30. package/dist/private/node/ui/components/AutocompletePrompt.test.js +56 -36
  31. package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
  32. package/dist/private/node/ui/components/ConcurrentOutput.d.ts +5 -1
  33. package/dist/private/node/ui/components/ConcurrentOutput.js +15 -13
  34. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  35. package/dist/private/node/ui/components/ConcurrentOutput.test.js +20 -11
  36. package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
  37. package/dist/private/node/ui/components/FullScreen.js +1 -1
  38. package/dist/private/node/ui/components/FullScreen.js.map +1 -1
  39. package/dist/private/node/ui/components/SelectInput.d.ts +7 -2
  40. package/dist/private/node/ui/components/SelectInput.js +73 -60
  41. package/dist/private/node/ui/components/SelectInput.js.map +1 -1
  42. package/dist/private/node/ui/components/SelectInput.test.js +72 -2
  43. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
  44. package/dist/private/node/ui/components/SelectPrompt.js +38 -12
  45. package/dist/private/node/ui/components/SelectPrompt.js.map +1 -1
  46. package/dist/private/node/ui/components/SelectPrompt.test.js +52 -1
  47. package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
  48. package/dist/private/node/ui/components/Tasks.js +9 -1
  49. package/dist/private/node/ui/components/Tasks.js.map +1 -1
  50. package/dist/private/node/ui/components/TextAnimation.js +4 -4
  51. package/dist/private/node/ui/components/TextAnimation.js.map +1 -1
  52. package/dist/private/node/ui/components/TextPrompt.js +4 -4
  53. package/dist/private/node/ui/components/TextPrompt.js.map +1 -1
  54. package/dist/private/node/ui/hooks/use-layout.d.ts +6 -0
  55. package/dist/private/node/ui/hooks/use-layout.js +31 -12
  56. package/dist/private/node/ui/hooks/use-layout.js.map +1 -1
  57. package/dist/private/node/ui.d.ts +11 -3
  58. package/dist/private/node/ui.js +14 -10
  59. package/dist/private/node/ui.js.map +1 -1
  60. package/dist/public/common/object.d.ts +1 -1
  61. package/dist/public/common/object.js +1 -1
  62. package/dist/public/common/object.js.map +1 -1
  63. package/dist/public/common/version.d.ts +1 -1
  64. package/dist/public/common/version.js +1 -1
  65. package/dist/public/common/version.js.map +1 -1
  66. package/dist/public/node/base-command.d.ts +1 -4
  67. package/dist/public/node/base-command.js +17 -19
  68. package/dist/public/node/base-command.js.map +1 -1
  69. package/dist/public/node/context/local.d.ts +0 -7
  70. package/dist/public/node/context/local.js +0 -9
  71. package/dist/public/node/context/local.js.map +1 -1
  72. package/dist/public/node/environments.d.ts +7 -8
  73. package/dist/public/node/environments.js +23 -25
  74. package/dist/public/node/environments.js.map +1 -1
  75. package/dist/public/node/node-package-manager.d.ts +1 -1
  76. package/dist/public/node/node-package-manager.js.map +1 -1
  77. package/dist/public/node/output.d.ts +1 -1
  78. package/dist/public/node/output.js.map +1 -1
  79. package/dist/public/node/path.js +1 -1
  80. package/dist/public/node/path.js.map +1 -1
  81. package/dist/public/node/ruby.d.ts +1 -0
  82. package/dist/public/node/ruby.js +35 -15
  83. package/dist/public/node/ruby.js.map +1 -1
  84. package/dist/public/node/themes/theme-manager.d.ts +1 -1
  85. package/dist/public/node/themes/theme-manager.js.map +1 -1
  86. package/dist/public/node/ui.d.ts +182 -121
  87. package/dist/public/node/ui.js +172 -120
  88. package/dist/public/node/ui.js.map +1 -1
  89. package/dist/tsconfig.tsbuildinfo +1 -1
  90. package/package.json +20 -18
  91. package/dist/private/node/ui/components/TextWithBackground.d.ts +0 -12
  92. package/dist/private/node/ui/components/TextWithBackground.js +0 -39
  93. package/dist/private/node/ui/components/TextWithBackground.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"alert.js","sourceRoot":"","sources":["../../../../src/private/node/ui/alert.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAa,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAA;AACnC,OAAO,EAAC,UAAU,EAAE,WAAW,EAAmB,MAAM,gCAAgC,CAAA;AACxF,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,cAAc,GAA4C;IAC9D,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;CAChB,CAAA;AAED,MAAM,YAAY,GAA0C;IAC1D,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,WAAW;IACpB,OAAO,EAAE,UAAU;CACpB,CAAA;AAED,MAAM,UAAU,KAAK,CAAC,EACpB,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,SAAS,EACT,IAAI,EACJ,cAAc,EACd,gBAAgB,GAAG,KAAK,GACb;IACX,UAAU,CACR,oBAAC,KAAK,IACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,cAAc,GAC9B,EACF,cAAc,CAAC,IAAI,CAAC,EACpB,YAAY,CAAC,IAAI,CAAC,CACnB,CAAA;AACH,CAAC","sourcesContent":["import {Alert, AlertProps} from './components/Alert.js'\nimport {renderOnce} from '../ui.js'\nimport {consoleLog, consoleWarn, Logger, LogLevel} from '../../../public/node/output.js'\nimport React from 'react'\n\nconst typeToLogLevel: {[key in AlertProps['type']]: LogLevel} = {\n info: 'info',\n warning: 'warn',\n success: 'info',\n}\n\nconst typeToLogger: {[key in AlertProps['type']]: Logger} = {\n info: consoleLog,\n warning: consoleWarn,\n success: consoleLog,\n}\n\nexport function alert({\n type,\n headline,\n body,\n nextSteps,\n reference,\n link,\n customSections,\n orderedNextSteps = false,\n}: AlertProps) {\n renderOnce(\n <Alert\n type={type}\n headline={headline}\n body={body}\n nextSteps={nextSteps}\n reference={reference}\n link={link}\n orderedNextSteps={orderedNextSteps}\n customSections={customSections}\n />,\n typeToLogLevel[type],\n typeToLogger[type],\n )\n}\n"]}
1
+ {"version":3,"file":"alert.js","sourceRoot":"","sources":["../../../../src/private/node/ui/alert.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAa,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAA;AACnC,OAAO,EAAC,UAAU,EAAE,WAAW,EAAmB,MAAM,gCAAgC,CAAA;AACxF,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,cAAc,GAA4C;IAC9D,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;CAChB,CAAA;AAED,MAAM,YAAY,GAA0C;IAC1D,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,WAAW;IACpB,OAAO,EAAE,UAAU;CACpB,CAAA;AAMD,MAAM,UAAU,KAAK,CAAC,EACpB,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,SAAS,EACT,IAAI,EACJ,cAAc,EACd,gBAAgB,GAAG,KAAK,EACxB,aAAa,GACA;IACb,OAAO,UAAU,CACf,oBAAC,KAAK,IACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,cAAc,GAC9B,EACF,EAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,aAAa,EAAC,CAC5E,CAAA;AACH,CAAC","sourcesContent":["import {Alert, AlertProps} from './components/Alert.js'\nimport {renderOnce} from '../ui.js'\nimport {consoleLog, consoleWarn, Logger, LogLevel} from '../../../public/node/output.js'\nimport React from 'react'\nimport {RenderOptions} from 'ink'\n\nconst typeToLogLevel: {[key in AlertProps['type']]: LogLevel} = {\n info: 'info',\n warning: 'warn',\n success: 'info',\n}\n\nconst typeToLogger: {[key in AlertProps['type']]: Logger} = {\n info: consoleLog,\n warning: consoleWarn,\n success: consoleLog,\n}\n\nexport interface AlertOptions extends AlertProps {\n renderOptions?: RenderOptions\n}\n\nexport function alert({\n type,\n headline,\n body,\n nextSteps,\n reference,\n link,\n customSections,\n orderedNextSteps = false,\n renderOptions,\n}: AlertOptions) {\n return renderOnce(\n <Alert\n type={type}\n headline={headline}\n body={body}\n nextSteps={nextSteps}\n reference={reference}\n link={link}\n orderedNextSteps={orderedNextSteps}\n customSections={customSections}\n />,\n {logLevel: typeToLogLevel[type], logger: typeToLogger[type], renderOptions},\n )\n}\n"]}
@@ -4,10 +4,10 @@ import { TextInput } from './TextInput.js';
4
4
  import { TokenizedText } from './TokenizedText.js';
5
5
  import { handleCtrlC } from '../../ui.js';
6
6
  import { messageWithPunctuation } from '../utilities.js';
7
- import React, { useCallback, useRef, useState } from 'react';
7
+ import { debounce } from '../../../../public/common/function.js';
8
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
8
9
  import { Box, measureElement, Text, useApp, useInput, useStdout } from 'ink';
9
10
  import figures from 'figures';
10
- import { debounce } from '@shopify/cli-kit/common/function';
11
11
  import ansiEscapes from 'ansi-escapes';
12
12
  var PromptState;
13
13
  (function (PromptState) {
@@ -26,25 +26,49 @@ function AutocompletePrompt({ message, choices: initialChoices, infoTable, onSub
26
26
  const [searchTerm, setSearchTerm] = useState('');
27
27
  const [searchResults, setSearchResults] = useState(paginatedInitialChoices.slice(0, PAGE_SIZE));
28
28
  const { stdout } = useStdout();
29
- const [height, setHeight] = useState(0);
30
29
  const canSearch = initialChoices.length >= PAGE_SIZE;
31
30
  const [hasMorePages, setHasMorePages] = useState(initialHasMorePages);
31
+ const [wrapperHeight, setWrapperHeight] = useState(0);
32
+ const [selectInputHeight, setSelectInputHeight] = useState(0);
33
+ const [limit, setLimit] = useState(searchResults.length);
32
34
  const paginatedSearch = useCallback(async (term) => {
33
35
  const results = await search(term);
34
36
  results.data = results.data.slice(0, PAGE_SIZE);
35
37
  return results;
38
+ }, [search]);
39
+ const wrapperRef = useCallback((node) => {
40
+ if (node !== null) {
41
+ const { height } = measureElement(node);
42
+ setWrapperHeight(height);
43
+ }
36
44
  }, []);
37
- const measuredRef = useCallback((node) => {
45
+ const inputRef = useCallback((node) => {
38
46
  if (node !== null) {
39
47
  const { height } = measureElement(node);
40
- setHeight(height);
48
+ setSelectInputHeight(height);
49
+ }
50
+ }, []);
51
+ useEffect(() => {
52
+ function onResize() {
53
+ const availableSpace = stdout.rows - (wrapperHeight - selectInputHeight);
54
+ // rough estimate of the limit needed based on the space available
55
+ const newLimit = Math.max(2, availableSpace - 6);
56
+ if (newLimit < limit) {
57
+ stdout.write(ansiEscapes.clearTerminal);
58
+ }
59
+ setLimit(Math.min(newLimit, searchResults.length));
41
60
  }
42
- }, [searchResults, promptState]);
43
- useInput(useCallback((input, key) => {
61
+ onResize();
62
+ stdout.on('resize', onResize);
63
+ return () => {
64
+ stdout.off('resize', onResize);
65
+ };
66
+ }, [wrapperHeight, selectInputHeight, searchResults.length, stdout, limit]);
67
+ useInput((input, key) => {
44
68
  handleCtrlC(input, key);
45
69
  if (key.return && promptState === PromptState.Idle && answer) {
46
70
  // -1 is for the last row with the terminal cursor
47
- if (stdout && height >= stdout.rows - 1) {
71
+ if (stdout && wrapperHeight >= stdout.rows - 1) {
48
72
  stdout.write(ansiEscapes.clearTerminal);
49
73
  }
50
74
  setPromptState(PromptState.Submitted);
@@ -52,12 +76,14 @@ function AutocompletePrompt({ message, choices: initialChoices, infoTable, onSub
52
76
  unmountInk();
53
77
  onSubmit(answer.value);
54
78
  }
55
- }, [answer, onSubmit, height, promptState]));
79
+ });
56
80
  const setLoadingWhenSlow = useRef();
57
81
  // we want to set it each time so that searchTermRef always tracks searchTerm,
58
82
  // this is NOT the same as writing useRef(searchTerm)
59
83
  const searchTermRef = useRef('');
60
84
  searchTermRef.current = searchTerm;
85
+ // disable exhaustive-deps because we want to memoize the debounce function itself
86
+ // eslint-disable-next-line react-hooks/exhaustive-deps
61
87
  const debounceSearch = useCallback(debounce((term) => {
62
88
  setLoadingWhenSlow.current = setTimeout(() => {
63
89
  setPromptState(PromptState.Loading);
@@ -83,8 +109,8 @@ function AutocompletePrompt({ message, choices: initialChoices, infoTable, onSub
83
109
  .finally(() => {
84
110
  clearTimeout(setLoadingWhenSlow.current);
85
111
  });
86
- }, 300), []);
87
- return (React.createElement(Box, { flexDirection: "column", marginBottom: 1, ref: measuredRef },
112
+ }, 300), [initialHasMorePages, paginatedInitialChoices, paginatedSearch]);
113
+ return (React.createElement(Box, { flexDirection: "column", marginBottom: 1, ref: wrapperRef },
88
114
  React.createElement(Box, null,
89
115
  React.createElement(Box, { marginRight: 2 },
90
116
  React.createElement(Text, null, "?")),
@@ -111,7 +137,7 @@ function AutocompletePrompt({ message, choices: initialChoices, infoTable, onSub
111
137
  setAnswer(item);
112
138
  }, enableShortcuts: false, emptyMessage: "No results found.", highlightedTerm: searchTerm, loading: promptState === PromptState.Loading, errorMessage: promptState === PromptState.Error
113
139
  ? 'There has been an error while searching. Please try again later.'
114
- : undefined, hasMorePages: hasMorePages, morePagesMessage: "Find what you're looking for by typing its name." })))));
140
+ : undefined, hasMorePages: hasMorePages, morePagesMessage: "Find what you're looking for by typing its name.", ref: inputRef, limit: limit })))));
115
141
  }
116
142
  export { AutocompletePrompt };
117
143
  //# sourceMappingURL=AutocompletePrompt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompletePrompt.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/AutocompletePrompt.tsx"],"names":[],"mappings":"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","sourcesContent":["import {SelectInput, SelectInputProps, Item as SelectItem} from './SelectInput.js'\nimport {InfoTable, InfoTableProps} from './Prompts/InfoTable.js'\nimport {TextInput} from './TextInput.js'\nimport {TokenizedText} from './TokenizedText.js'\nimport {handleCtrlC} from '../../ui.js'\nimport {messageWithPunctuation} from '../utilities.js'\nimport React, {ReactElement, useCallback, useRef, useState} from 'react'\nimport {Box, measureElement, Text, useApp, useInput, useStdout} from 'ink'\nimport figures from 'figures'\nimport {debounce} from '@shopify/cli-kit/common/function'\nimport ansiEscapes from 'ansi-escapes'\n\nexport interface SearchResults<T> {\n data: SelectItem<T>[]\n meta?: {\n hasNextPage: boolean\n }\n}\n\nexport interface AutocompletePromptProps<T> {\n message: string\n choices: SelectInputProps<T>['items']\n onSubmit: (value: T) => void\n infoTable?: InfoTableProps['table']\n hasMorePages?: boolean\n search: (term: string) => Promise<SearchResults<T>>\n}\n\nenum PromptState {\n Idle = 'idle',\n Loading = 'loading',\n Submitted = 'submitted',\n Error = 'error',\n}\n\nconst PAGE_SIZE = 25\n\n// eslint-disable-next-line react/function-component-definition\nfunction AutocompletePrompt<T>({\n message,\n choices: initialChoices,\n infoTable,\n onSubmit,\n search,\n hasMorePages: initialHasMorePages = false,\n}: React.PropsWithChildren<AutocompletePromptProps<T>>): ReactElement | null {\n const paginatedInitialChoices = initialChoices.slice(0, PAGE_SIZE)\n const [answer, setAnswer] = useState<SelectItem<T> | undefined>(paginatedInitialChoices[0])\n const {exit: unmountInk} = useApp()\n const [promptState, setPromptState] = useState<PromptState>(PromptState.Idle)\n const [searchTerm, setSearchTerm] = useState('')\n const [searchResults, setSearchResults] = useState<SelectItem<T>[]>(paginatedInitialChoices.slice(0, PAGE_SIZE))\n const {stdout} = useStdout()\n const [height, setHeight] = useState(0)\n const canSearch = initialChoices.length >= PAGE_SIZE\n const [hasMorePages, setHasMorePages] = useState(initialHasMorePages)\n\n const paginatedSearch = useCallback(async (term: string) => {\n const results = await search(term)\n results.data = results.data.slice(0, PAGE_SIZE)\n return results\n }, [])\n\n const measuredRef = useCallback(\n (node) => {\n if (node !== null) {\n const {height} = measureElement(node)\n setHeight(height)\n }\n },\n [searchResults, promptState],\n )\n\n useInput(\n useCallback(\n (input, key) => {\n handleCtrlC(input, key)\n\n if (key.return && promptState === PromptState.Idle && answer) {\n // -1 is for the last row with the terminal cursor\n if (stdout && height >= stdout.rows - 1) {\n stdout.write(ansiEscapes.clearTerminal)\n }\n setPromptState(PromptState.Submitted)\n setSearchTerm('')\n unmountInk()\n onSubmit(answer.value)\n }\n },\n [answer, onSubmit, height, promptState],\n ),\n )\n\n const setLoadingWhenSlow = useRef<NodeJS.Timeout>()\n\n // we want to set it each time so that searchTermRef always tracks searchTerm,\n // this is NOT the same as writing useRef(searchTerm)\n const searchTermRef = useRef('')\n searchTermRef.current = searchTerm\n\n const debounceSearch = useCallback(\n debounce((term) => {\n setLoadingWhenSlow.current = setTimeout(() => {\n setPromptState(PromptState.Loading)\n }, 100)\n paginatedSearch(term)\n .then((result) => {\n // while we were waiting for the promise to resolve, the user\n // has emptied the search term, so we want to show the default\n // choices instead\n if (searchTermRef.current.length === 0) {\n setSearchResults(paginatedInitialChoices)\n setHasMorePages(initialHasMorePages)\n } else {\n setSearchResults(result.data)\n setHasMorePages(result.meta?.hasNextPage ?? false)\n }\n\n setPromptState(PromptState.Idle)\n })\n .catch(() => {\n setPromptState(PromptState.Error)\n })\n .finally(() => {\n clearTimeout(setLoadingWhenSlow.current)\n })\n }, 300),\n [],\n )\n\n return (\n <Box flexDirection=\"column\" marginBottom={1} ref={measuredRef}>\n <Box>\n <Box marginRight={2}>\n <Text>?</Text>\n </Box>\n <TokenizedText item={messageWithPunctuation(message)} />\n {promptState !== PromptState.Submitted && canSearch ? (\n <Box marginLeft={3}>\n <TextInput\n value={searchTerm}\n onChange={(term) => {\n setSearchTerm(term)\n\n if (term.length > 0) {\n debounceSearch(term)\n } else {\n debounceSearch.cancel()\n setPromptState(PromptState.Idle)\n setSearchResults(paginatedInitialChoices)\n }\n }}\n placeholder=\"Type to search...\"\n />\n </Box>\n ) : null}\n </Box>\n\n {infoTable && promptState !== PromptState.Submitted ? (\n <Box marginLeft={7} marginTop={1}>\n <InfoTable table={infoTable} />\n </Box>\n ) : null}\n\n {promptState === PromptState.Submitted ? (\n <Box>\n <Box marginRight={2}>\n <Text color=\"cyan\">{figures.tick}</Text>\n </Box>\n\n <Text color=\"cyan\">{answer!.label}</Text>\n </Box>\n ) : (\n <Box marginTop={1}>\n <SelectInput\n items={searchResults}\n onChange={({item}) => {\n setAnswer(item)\n }}\n enableShortcuts={false}\n emptyMessage=\"No results found.\"\n highlightedTerm={searchTerm}\n loading={promptState === PromptState.Loading}\n errorMessage={\n promptState === PromptState.Error\n ? 'There has been an error while searching. Please try again later.'\n : undefined\n }\n hasMorePages={hasMorePages}\n morePagesMessage=\"Find what you're looking for by typing its name.\"\n />\n </Box>\n )}\n </Box>\n )\n}\n\nexport {AutocompletePrompt}\n"]}
1
+ {"version":3,"file":"AutocompletePrompt.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/AutocompletePrompt.tsx"],"names":[],"mappings":"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","sourcesContent":["import {SelectInput, SelectInputProps, Item as SelectItem} from './SelectInput.js'\nimport {InfoTable, InfoTableProps} from './Prompts/InfoTable.js'\nimport {TextInput} from './TextInput.js'\nimport {TokenizedText} from './TokenizedText.js'\nimport {handleCtrlC} from '../../ui.js'\nimport {messageWithPunctuation} from '../utilities.js'\nimport {debounce} from '../../../../public/common/function.js'\nimport React, {ReactElement, useCallback, useEffect, useRef, useState} from 'react'\nimport {Box, measureElement, Text, useApp, useInput, useStdout} from 'ink'\nimport figures from 'figures'\nimport ansiEscapes from 'ansi-escapes'\n\nexport interface SearchResults<T> {\n data: SelectItem<T>[]\n meta?: {\n hasNextPage: boolean\n }\n}\n\nexport interface AutocompletePromptProps<T> {\n message: string\n choices: SelectInputProps<T>['items']\n onSubmit: (value: T) => void\n infoTable?: InfoTableProps['table']\n hasMorePages?: boolean\n search: (term: string) => Promise<SearchResults<T>>\n}\n\nenum PromptState {\n Idle = 'idle',\n Loading = 'loading',\n Submitted = 'submitted',\n Error = 'error',\n}\n\nconst PAGE_SIZE = 25\n\n// eslint-disable-next-line react/function-component-definition\nfunction AutocompletePrompt<T>({\n message,\n choices: initialChoices,\n infoTable,\n onSubmit,\n search,\n hasMorePages: initialHasMorePages = false,\n}: React.PropsWithChildren<AutocompletePromptProps<T>>): ReactElement | null {\n const paginatedInitialChoices = initialChoices.slice(0, PAGE_SIZE)\n const [answer, setAnswer] = useState<SelectItem<T> | undefined>(paginatedInitialChoices[0])\n const {exit: unmountInk} = useApp()\n const [promptState, setPromptState] = useState<PromptState>(PromptState.Idle)\n const [searchTerm, setSearchTerm] = useState('')\n const [searchResults, setSearchResults] = useState<SelectItem<T>[]>(paginatedInitialChoices.slice(0, PAGE_SIZE))\n const {stdout} = useStdout()\n const canSearch = initialChoices.length >= PAGE_SIZE\n const [hasMorePages, setHasMorePages] = useState(initialHasMorePages)\n const [wrapperHeight, setWrapperHeight] = useState(0)\n const [selectInputHeight, setSelectInputHeight] = useState(0)\n const [limit, setLimit] = useState(searchResults.length)\n\n const paginatedSearch = useCallback(\n async (term: string) => {\n const results = await search(term)\n results.data = results.data.slice(0, PAGE_SIZE)\n return results\n },\n [search],\n )\n\n const wrapperRef = useCallback((node) => {\n if (node !== null) {\n const {height} = measureElement(node)\n setWrapperHeight(height)\n }\n }, [])\n\n const inputRef = useCallback((node) => {\n if (node !== null) {\n const {height} = measureElement(node)\n setSelectInputHeight(height)\n }\n }, [])\n\n useEffect(() => {\n function onResize() {\n const availableSpace = stdout!.rows - (wrapperHeight - selectInputHeight)\n // rough estimate of the limit needed based on the space available\n const newLimit = Math.max(2, availableSpace - 6)\n\n if (newLimit < limit) {\n stdout!.write(ansiEscapes.clearTerminal)\n }\n\n setLimit(Math.min(newLimit, searchResults.length))\n }\n\n onResize()\n\n stdout!.on('resize', onResize)\n return () => {\n stdout!.off('resize', onResize)\n }\n }, [wrapperHeight, selectInputHeight, searchResults.length, stdout, limit])\n\n useInput((input, key) => {\n handleCtrlC(input, key)\n\n if (key.return && promptState === PromptState.Idle && answer) {\n // -1 is for the last row with the terminal cursor\n if (stdout && wrapperHeight >= stdout.rows - 1) {\n stdout.write(ansiEscapes.clearTerminal)\n }\n setPromptState(PromptState.Submitted)\n setSearchTerm('')\n unmountInk()\n onSubmit(answer.value)\n }\n })\n\n const setLoadingWhenSlow = useRef<NodeJS.Timeout>()\n\n // we want to set it each time so that searchTermRef always tracks searchTerm,\n // this is NOT the same as writing useRef(searchTerm)\n const searchTermRef = useRef('')\n searchTermRef.current = searchTerm\n\n // disable exhaustive-deps because we want to memoize the debounce function itself\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const debounceSearch = useCallback(\n debounce((term: string) => {\n setLoadingWhenSlow.current = setTimeout(() => {\n setPromptState(PromptState.Loading)\n }, 100)\n paginatedSearch(term)\n .then((result) => {\n // while we were waiting for the promise to resolve, the user\n // has emptied the search term, so we want to show the default\n // choices instead\n if (searchTermRef.current.length === 0) {\n setSearchResults(paginatedInitialChoices)\n setHasMorePages(initialHasMorePages)\n } else {\n setSearchResults(result.data)\n setHasMorePages(result.meta?.hasNextPage ?? false)\n }\n\n setPromptState(PromptState.Idle)\n })\n .catch(() => {\n setPromptState(PromptState.Error)\n })\n .finally(() => {\n clearTimeout(setLoadingWhenSlow.current)\n })\n }, 300),\n [initialHasMorePages, paginatedInitialChoices, paginatedSearch],\n )\n\n return (\n <Box flexDirection=\"column\" marginBottom={1} ref={wrapperRef}>\n <Box>\n <Box marginRight={2}>\n <Text>?</Text>\n </Box>\n <TokenizedText item={messageWithPunctuation(message)} />\n {promptState !== PromptState.Submitted && canSearch ? (\n <Box marginLeft={3}>\n <TextInput\n value={searchTerm}\n onChange={(term) => {\n setSearchTerm(term)\n\n if (term.length > 0) {\n debounceSearch(term)\n } else {\n debounceSearch.cancel()\n setPromptState(PromptState.Idle)\n setSearchResults(paginatedInitialChoices)\n }\n }}\n placeholder=\"Type to search...\"\n />\n </Box>\n ) : null}\n </Box>\n\n {infoTable && promptState !== PromptState.Submitted ? (\n <Box marginLeft={7} marginTop={1}>\n <InfoTable table={infoTable} />\n </Box>\n ) : null}\n\n {promptState === PromptState.Submitted ? (\n <Box>\n <Box marginRight={2}>\n <Text color=\"cyan\">{figures.tick}</Text>\n </Box>\n\n <Text color=\"cyan\">{answer!.label}</Text>\n </Box>\n ) : (\n <Box marginTop={1}>\n <SelectInput\n items={searchResults}\n onChange={({item}) => {\n setAnswer(item)\n }}\n enableShortcuts={false}\n emptyMessage=\"No results found.\"\n highlightedTerm={searchTerm}\n loading={promptState === PromptState.Loading}\n errorMessage={\n promptState === PromptState.Error\n ? 'There has been an error while searching. Please try again later.'\n : undefined\n }\n hasMorePages={hasMorePages}\n morePagesMessage=\"Find what you're looking for by typing its name.\"\n ref={inputRef}\n limit={limit}\n />\n </Box>\n )}\n </Box>\n )\n}\n\nexport {AutocompletePrompt}\n"]}
@@ -1,8 +1,18 @@
1
1
  import { AutocompletePrompt } from './AutocompletePrompt.js';
2
- import { getLastFrameAfterUnmount, sendInputAndWait, sendInputAndWaitForChange, sendInputAndWaitForContent, waitForContent, waitForInputsToBeReady, } from '../../testing/ui.js';
3
- import { describe, expect, test, vi } from 'vitest';
2
+ import { getLastFrameAfterUnmount, sendInputAndWait, sendInputAndWaitForChange, sendInputAndWaitForContent, waitForInputsToBeReady, } from '../../testing/ui.js';
3
+ import { OutputStream } from '../../ui.js';
4
+ import { beforeEach, describe, expect, test, vi } from 'vitest';
4
5
  import React from 'react';
5
6
  import { render } from 'ink-testing-library';
7
+ import { useStdout } from 'ink';
8
+ vi.mock('ink', async () => {
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ const original = await vi.importActual('ink');
11
+ return {
12
+ ...original,
13
+ useStdout: vi.fn(),
14
+ };
15
+ });
6
16
  const ARROW_DOWN = '\u001B[B';
7
17
  const ENTER = '\r';
8
18
  const DELETE = '\u007F';
@@ -58,6 +68,16 @@ const DATABASE = [
58
68
  { label: 'forty-ninth', value: 'forty-ninth' },
59
69
  { label: 'fiftieth', value: 'fiftieth' },
60
70
  ];
71
+ beforeEach(() => {
72
+ vi.mocked(useStdout).mockReturnValue({
73
+ stdout: new OutputStream({
74
+ columns: 80,
75
+ rows: 80,
76
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
+ }),
78
+ write: () => { },
79
+ });
80
+ });
61
81
  describe('AutocompletePrompt', async () => {
62
82
  test('choose an answer', async () => {
63
83
  const onEnter = vi.fn();
@@ -160,8 +180,9 @@ describe('AutocompletePrompt', async () => {
160
180
  await waitForInputsToBeReady();
161
181
  await sendInputAndWaitForContent(renderInstance, 'No results found', 'a');
162
182
  // prompt doesn't change when enter is pressed
183
+ await new Promise((resolve) => setTimeout(resolve, 100));
163
184
  await sendInputAndWait(renderInstance, 100, ENTER);
164
- expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`
185
+ expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
165
186
  "? Associate your project with the org Castile Ventures? a 
166
187
 
167
188
  No results found.
@@ -181,8 +202,9 @@ describe('AutocompletePrompt', async () => {
181
202
  await waitForInputsToBeReady();
182
203
  await sendInputAndWaitForContent(renderInstance, 'Loading...', 'a');
183
204
  // prompt doesn't change when enter is pressed
205
+ await new Promise((resolve) => setTimeout(resolve, 100));
184
206
  await sendInputAndWait(renderInstance, 100, ENTER);
185
- expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`
207
+ expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
186
208
  "? Associate your project with the org Castile Ventures? a 
187
209
 
188
210
  Loading...
@@ -340,46 +362,21 @@ describe('AutocompletePrompt', async () => {
340
362
  `);
341
363
  expect(onEnter).toHaveBeenCalledWith('fifth');
342
364
  });
343
- test('allows selecting the first item after searching and triggering the loading state', async () => {
365
+ test('allows selecting the first item after searching', async () => {
344
366
  const onEnter = vi.fn();
345
367
  const search = async (term) => {
346
- await new Promise((resolve) => setTimeout(resolve, 500));
368
+ await new Promise((resolve) => setTimeout(resolve, 300));
347
369
  return {
348
370
  data: DATABASE.filter((item) => item.label.includes(term)),
349
371
  };
350
372
  };
351
373
  const renderInstance = render(React.createElement(AutocompletePrompt, { message: "Associate your project with the org Castile Ventures?", choices: DATABASE, onSubmit: onEnter, search: search }));
352
374
  await waitForInputsToBeReady();
353
- await sendInputAndWaitForContent(renderInstance, 'Loading...', 'e');
354
- await waitForContent(renderInstance, 'Press ↑↓ arrows to select, enter to confirm');
375
+ await sendInputAndWaitForContent(renderInstance, 'fiftieth', 'fiftieth');
355
376
  expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
356
- "? Associate your project with the org Castile Ventures? e 
377
+ "? Associate your project with the org Castile Ventures? fiftieth 
357
378
 
358
- > second
359
- seventh
360
- eighth
361
- tenth
362
- eleventh
363
- twelfth
364
- thirteenth
365
- fourteenth
366
- fifteenth
367
- sixteenth
368
- seventeenth
369
- eighteenth
370
- nineteenth
371
- twentieth
372
- twenty-first
373
- twenty-second
374
- twenty-third
375
- twenty-fourth
376
- twenty-fifth
377
- twenty-sixth
378
- twenty-seventh
379
- twenty-eighth
380
- twenty-ninth
381
- thirtieth
382
- thirty-second
379
+ > fiftieth
383
380
 
384
381
  Press ↑↓ arrows to select, enter to confirm
385
382
  "
@@ -387,10 +384,10 @@ describe('AutocompletePrompt', async () => {
387
384
  await sendInputAndWaitForChange(renderInstance, ENTER);
388
385
  expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`
389
386
  "? Associate your project with the org Castile Ventures?
390
- ✔ second
387
+ ✔ fiftieth
391
388
  "
392
389
  `);
393
- expect(onEnter).toHaveBeenCalledWith('second');
390
+ expect(onEnter).toHaveBeenCalledWith('fiftieth');
394
391
  });
395
392
  test('displays an error message if the search fails', async () => {
396
393
  const search = (_term) => {
@@ -523,5 +520,28 @@ describe('AutocompletePrompt', async () => {
523
520
  "
524
521
  `);
525
522
  });
523
+ test('adapts to the height of the container', async () => {
524
+ vi.mocked(useStdout).mockReturnValue({
525
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
526
+ stdout: new OutputStream({ rows: 10 }),
527
+ write: () => { },
528
+ });
529
+ const renderInstance = render(React.createElement(AutocompletePrompt, { message: "Associate your project with the org Castile Ventures?", choices: DATABASE, onSubmit: () => { }, hasMorePages: true, search: () => Promise.resolve({
530
+ data: DATABASE,
531
+ }) }));
532
+ expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
533
+ "? Associate your project with the org Castile Ventures? Type to search...
534
+
535
+ > first
536
+ second
537
+ third
538
+ fourth
539
+
540
+ 1-25 of many Find what you're looking for by typing its name.
541
+ Showing 4 of 25 items.
542
+ Press ↑↓ arrows to select, enter to confirm
543
+ "
544
+ `);
545
+ });
526
546
  });
527
547
  //# sourceMappingURL=AutocompletePrompt.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompletePrompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/AutocompletePrompt.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {AutocompletePrompt, SearchResults} from './AutocompletePrompt.js'\nimport {\n getLastFrameAfterUnmount,\n sendInputAndWait,\n sendInputAndWaitForChange,\n sendInputAndWaitForContent,\n waitForContent,\n waitForInputsToBeReady,\n} from '../../testing/ui.js'\nimport {describe, expect, test, vi} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\nconst ARROW_DOWN = '\\u001B[B'\nconst ENTER = '\\r'\nconst DELETE = '\\u007F'\n\nconst DATABASE = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\n {label: 'fifth', value: 'fifth'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n {label: 'eleventh', value: 'eleventh'},\n {label: 'twelfth', value: 'twelfth'},\n {label: 'thirteenth', value: 'thirteenth'},\n {label: 'fourteenth', value: 'fourteenth'},\n {label: 'fifteenth', value: 'fifteenth'},\n {label: 'sixteenth', value: 'sixteenth'},\n {label: 'seventeenth', value: 'seventeenth'},\n {label: 'eighteenth', value: 'eighteenth'},\n {label: 'nineteenth', value: 'nineteenth'},\n {label: 'twentieth', value: 'twentieth'},\n {label: 'twenty-first', value: 'twenty-first'},\n {label: 'twenty-second', value: 'twenty-second'},\n {label: 'twenty-third', value: 'twenty-third'},\n {label: 'twenty-fourth', value: 'twenty-fourth'},\n {label: 'twenty-fifth', value: 'twenty-fifth'},\n {label: 'twenty-sixth', value: 'twenty-sixth'},\n {label: 'twenty-seventh', value: 'twenty-seventh'},\n {label: 'twenty-eighth', value: 'twenty-eighth'},\n {label: 'twenty-ninth', value: 'twenty-ninth'},\n {label: 'thirtieth', value: 'thirtieth'},\n {label: 'thirty-first', value: 'thirty-first'},\n {label: 'thirty-second', value: 'thirty-second'},\n {label: 'thirty-third', value: 'thirty-third'},\n {label: 'thirty-fourth', value: 'thirty-fourth'},\n {label: 'thirty-fifth', value: 'thirty-fifth'},\n {label: 'thirty-sixth', value: 'thirty-sixth'},\n {label: 'thirty-seventh', value: 'thirty-seventh'},\n {label: 'thirty-eighth', value: 'thirty-eighth'},\n {label: 'thirty-ninth', value: 'thirty-ninth'},\n {label: 'fortieth', value: 'fortieth'},\n {label: 'forty-first', value: 'forty-first'},\n {label: 'forty-second', value: 'forty-second'},\n {label: 'forty-third', value: 'forty-third'},\n {label: 'forty-fourth', value: 'forty-fourth'},\n {label: 'forty-fifth', value: 'forty-fifth'},\n {label: 'forty-sixth', value: 'forty-sixth'},\n {label: 'forty-seventh', value: 'forty-seventh'},\n {label: 'forty-eighth', value: 'forty-eighth'},\n {label: 'forty-ninth', value: 'forty-ninth'},\n {label: 'fiftieth', value: 'fiftieth'},\n]\n\ndescribe('AutocompletePrompt', async () => {\n test('choose an answer', async () => {\n const onEnter = vi.fn()\n\n const items = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n ]\n\n const infoTable = {Add: ['new-ext'], Remove: ['integrated-demand-ext', 'order-discount']}\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onSubmit={onEnter}\n search={() =>\n Promise.resolve({\n data: [],\n } as SearchResults<string>)\n }\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36msecond\u001b[39m\n \"\n `)\n\n expect(onEnter).toHaveBeenCalledWith(items[1]!.value)\n })\n\n test('renders groups', async () => {\n const items = [\n {label: 'first', value: 'first', group: 'Automations', key: 'f'},\n {label: 'second', value: 'second', group: 'Automations', key: 's'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\n {label: 'fifth', value: 'fifth', key: 'a'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={() => {}}\n search={() =>\n Promise.resolve({\n data: [],\n } as SearchResults<string>)\n }\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n \u001b[1mAutomations\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n\n \u001b[1mMerchant Admin\u001b[22m\n third\n fourth\n\n \u001b[1mOther\u001b[22m\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test('supports an info table', async () => {\n const items = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\n ]\n\n const infoTable = {\n Add: ['new-ext'],\n Remove: ['integrated-demand-ext', 'order-discount'],\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onSubmit={() => {}}\n search={() => Promise.resolve({data: []} as SearchResults<string>)}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n Add: • new-ext\n\n Remove: • integrated-demand-ext\n • order-discount\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test(\"doesn't submit if there are no choices\", async () => {\n const onEnter = vi.fn()\n const searchPromise = Promise.resolve({\n data: [],\n } as SearchResults<string>)\n const search = () => {\n return searchPromise\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'No results found', 'a')\n // prompt doesn't change when enter is pressed\n await sendInputAndWait(renderInstance, 100, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36ma\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[2mNo results found.\u001b[22m\n \"\n `)\n\n expect(onEnter).not.toHaveBeenCalled()\n })\n\n test('has a loading state', async () => {\n const onEnter = vi.fn()\n const searchPromise = new Promise<SearchResults<string>>((resolve) => {\n setTimeout(() => resolve({data: [{label: 'a', value: 'b'}]}), 2000)\n })\n\n const search = () => {\n return searchPromise\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'Loading...', 'a')\n // prompt doesn't change when enter is pressed\n await sendInputAndWait(renderInstance, 100, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36ma\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[2mLoading...\u001b[22m\n \"\n `)\n\n expect(onEnter).not.toHaveBeenCalled()\n })\n\n test('allows searching with pagination', async () => {\n const onEnter = vi.fn()\n\n const search = async (term: string) => {\n return {\n data: DATABASE.filter((item) => item.label.includes(term)),\n }\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'th\u001b[1mi\u001b[22mrty-sixth', 'i')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m\n th\u001b[1mi\u001b[22mrd\n f\u001b[1mi\u001b[22mfth\n s\u001b[1mi\u001b[22mxth\n e\u001b[1mi\u001b[22mghth\n n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrteenth\n f\u001b[1mi\u001b[22mfteenth\n s\u001b[1mi\u001b[22mxteenth\n e\u001b[1mi\u001b[22mghteenth\n n\u001b[1mi\u001b[22mneteenth\n twent\u001b[1mi\u001b[22meth\n twenty-f\u001b[1mi\u001b[22mrst\n twenty-th\u001b[1mi\u001b[22mrd\n twenty-f\u001b[1mi\u001b[22mfth\n twenty-s\u001b[1mi\u001b[22mxth\n twenty-e\u001b[1mi\u001b[22mghth\n twenty-n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrtieth\n th\u001b[1mi\u001b[22mrty-first\n th\u001b[1mi\u001b[22mrty-second\n th\u001b[1mi\u001b[22mrty-third\n th\u001b[1mi\u001b[22mrty-fourth\n th\u001b[1mi\u001b[22mrty-fifth\n th\u001b[1mi\u001b[22mrty-sixth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, DELETE)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForContent(renderInstance, 'th\u001b[1mi\u001b[22mrty-sixth', 'i')\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n f\u001b[1mi\u001b[22mrst\n th\u001b[1mi\u001b[22mrd\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mfth\u001b[39m\n s\u001b[1mi\u001b[22mxth\n e\u001b[1mi\u001b[22mghth\n n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrteenth\n f\u001b[1mi\u001b[22mfteenth\n s\u001b[1mi\u001b[22mxteenth\n e\u001b[1mi\u001b[22mghteenth\n n\u001b[1mi\u001b[22mneteenth\n twent\u001b[1mi\u001b[22meth\n twenty-f\u001b[1mi\u001b[22mrst\n twenty-th\u001b[1mi\u001b[22mrd\n twenty-f\u001b[1mi\u001b[22mfth\n twenty-s\u001b[1mi\u001b[22mxth\n twenty-e\u001b[1mi\u001b[22mghth\n twenty-n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrtieth\n th\u001b[1mi\u001b[22mrty-first\n th\u001b[1mi\u001b[22mrty-second\n th\u001b[1mi\u001b[22mrty-third\n th\u001b[1mi\u001b[22mrty-fourth\n th\u001b[1mi\u001b[22mrty-fifth\n th\u001b[1mi\u001b[22mrty-sixth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36mfifth\u001b[39m\n \"\n `)\n\n expect(onEnter).toHaveBeenCalledWith('fifth')\n })\n\n test('allows selecting the first item after searching and triggering the loading state', async () => {\n const onEnter = vi.fn()\n\n const search = async (term: string) => {\n await new Promise((resolve) => setTimeout(resolve, 500))\n return {\n data: DATABASE.filter((item) => item.label.includes(term)),\n }\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'Loading...', 'e')\n await waitForContent(renderInstance, 'Press ↑↓ arrows to select, enter to confirm')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36me\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36ms\u001b[1me\u001b[22mcond\u001b[39m\n s\u001b[1me\u001b[22mventh\n \u001b[1me\u001b[22mighth\n t\u001b[1me\u001b[22mnth\n \u001b[1me\u001b[22mleventh\n tw\u001b[1me\u001b[22mlfth\n thirt\u001b[1me\u001b[22menth\n fourt\u001b[1me\u001b[22menth\n fift\u001b[1me\u001b[22menth\n sixt\u001b[1me\u001b[22menth\n s\u001b[1me\u001b[22mventeenth\n \u001b[1me\u001b[22mighteenth\n nin\u001b[1me\u001b[22mteenth\n tw\u001b[1me\u001b[22mntieth\n tw\u001b[1me\u001b[22mnty-first\n tw\u001b[1me\u001b[22mnty-second\n tw\u001b[1me\u001b[22mnty-third\n tw\u001b[1me\u001b[22mnty-fourth\n tw\u001b[1me\u001b[22mnty-fifth\n tw\u001b[1me\u001b[22mnty-sixth\n tw\u001b[1me\u001b[22mnty-seventh\n tw\u001b[1me\u001b[22mnty-eighth\n tw\u001b[1me\u001b[22mnty-ninth\n thirti\u001b[1me\u001b[22mth\n thirty-s\u001b[1me\u001b[22mcond\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36msecond\u001b[39m\n \"\n `)\n\n expect(onEnter).toHaveBeenCalledWith('second')\n })\n\n test('displays an error message if the search fails', async () => {\n const search = (_term: string) => {\n return Promise.reject(new Error('Something went wrong'))\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={() => {}}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'There has been an error', 'i')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[31mThere has been an error while searching. Please try again later.\u001b[39m\n \"\n `)\n })\n\n test('immediately shows the initial items if the search is empty', async () => {\n const search = (term: string) => {\n return Promise.resolve({\n data: DATABASE.filter((item) => item.label.includes(term)),\n })\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={() => {}}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'th\u001b[1mi\u001b[22mrty-sixth', 'i')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m\n th\u001b[1mi\u001b[22mrd\n f\u001b[1mi\u001b[22mfth\n s\u001b[1mi\u001b[22mxth\n e\u001b[1mi\u001b[22mghth\n n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrteenth\n f\u001b[1mi\u001b[22mfteenth\n s\u001b[1mi\u001b[22mxteenth\n e\u001b[1mi\u001b[22mghteenth\n n\u001b[1mi\u001b[22mneteenth\n twent\u001b[1mi\u001b[22meth\n twenty-f\u001b[1mi\u001b[22mrst\n twenty-th\u001b[1mi\u001b[22mrd\n twenty-f\u001b[1mi\u001b[22mfth\n twenty-s\u001b[1mi\u001b[22mxth\n twenty-e\u001b[1mi\u001b[22mghth\n twenty-n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrtieth\n th\u001b[1mi\u001b[22mrty-first\n th\u001b[1mi\u001b[22mrty-second\n th\u001b[1mi\u001b[22mrty-third\n th\u001b[1mi\u001b[22mrty-fourth\n th\u001b[1mi\u001b[22mrty-fifth\n th\u001b[1mi\u001b[22mrty-sixth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, DELETE)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test('shows a message that indicates there are more results than shown', async () => {\n const search = (_term: string) => {\n return Promise.resolve({\n data: DATABASE,\n meta: {hasNextPage: true},\n })\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={() => {}}\n hasMorePages\n search={search}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[1m1-25 of many\u001b[22m Find what you're looking for by typing its name.\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n})\n"]}
1
+ {"version":3,"file":"AutocompletePrompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/AutocompletePrompt.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAgB,MAAM,yBAAyB,CAAA;AACzE,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAC,MAAM,QAAQ,CAAA;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAC,SAAS,EAAC,MAAM,KAAK,CAAA;AAE7B,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;IACxB,8DAA8D;IAC9D,MAAM,QAAQ,GAAQ,MAAM,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IAClD,OAAO;QACL,GAAG,QAAQ;QACX,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;KACnB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG,UAAU,CAAA;AAC7B,MAAM,KAAK,GAAG,IAAI,CAAA;AAClB,MAAM,MAAM,GAAG,QAAQ,CAAA;AAEvB,MAAM,QAAQ,GAAG;IACf,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;IAChC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;IAClC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;IAChC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;IAClC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;IAChC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;IAChC,EAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAC;IACpC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;IAClC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;IAChC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;IAChC,EAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAC;IACtC,EAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAC;IACpC,EAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAC;IAC1C,EAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAC;IAC1C,EAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAC;IACxC,EAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAC;IACxC,EAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAC;IAC5C,EAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAC;IAC1C,EAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAC;IAC1C,EAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAC;IACxC,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAC;IAChD,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAC;IAChD,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAC;IAClD,EAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAC;IAChD,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAC;IACxC,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAC;IAChD,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAC;IAChD,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAC;IAClD,EAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAC;IAChD,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAC;IACtC,EAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAC;IAC5C,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAC;IAC5C,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAC;IAC5C,EAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAC;IAC5C,EAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAC;IAChD,EAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAC;IAC9C,EAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAC;IAC5C,EAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAC;CACvC,CAAA;AAED,UAAU,CAAC,GAAG,EAAE;IACd,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC;QACnC,MAAM,EAAE,IAAI,YAAY,CAAC;YACvB,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,EAAE;YACR,8DAA8D;SAC/D,CAAQ;QACT,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;KAChB,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;IACxC,IAAI,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;QAEvB,MAAM,KAAK,GAAG;YACZ,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;YAChC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;YAClC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;SACjC,CAAA;QAED,MAAM,SAAS,GAAG,EAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,EAAC,CAAA;QAEzF,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,KAAK,EACd,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,GAAG,EAAE,CACX,OAAO,CAAC,OAAO,CAAC;gBACd,IAAI,EAAE,EAAE;aACgB,CAAC,GAE7B,CACH,CAAA;QAED,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,yBAAyB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC3D,MAAM,yBAAyB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAEtD,MAAM,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;KAItE,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,KAAK,GAAG;YACZ,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,EAAC;YAChE,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,EAAC;YAClE,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAC;YACzD,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAC;YAC3D,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAC;YAC1C,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;YAChC,EAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAC;YACpC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;YAClC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;YAChC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;SACjC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,KAAK,EACd,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,MAAM,EAAE,GAAG,EAAE,CACX,OAAO,CAAC,OAAO,CAAC;gBACd,IAAI,EAAE,EAAE;aACgB,CAAC,GAE7B,CACH,CAAA;QAED,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;KAqBxD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,KAAK,GAAG;YACZ,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;YAChC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;YAClC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;YAChC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;SACnC,CAAA;QAED,MAAM,SAAS,GAAG;YAChB,GAAG,EAAE,CAAC,SAAS,CAAC;YAChB,MAAM,EAAE,CAAC,uBAAuB,EAAE,gBAAgB,CAAC;SACpD,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,KAAK,EACd,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,EAAE,EAA0B,CAAC,GAClE,CACH,CAAA;QAED,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;KAexD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;QACvB,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;YACpC,IAAI,EAAE,EAAE;SACgB,CAAC,CAAA;QAC3B,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,OAAO,aAAa,CAAA;QACtB,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,GACd,CACH,CAAA;QAED,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,0BAA0B,CAAC,cAAc,EAAE,kBAAkB,EAAE,GAAG,CAAC,CAAA;QACzE,8CAA8C;QAC9C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;QACxD,MAAM,gBAAgB,CAAC,cAAc,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;QAElD,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKxD,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;QACvB,MAAM,aAAa,GAAG,IAAI,OAAO,CAAwB,CAAC,OAAO,EAAE,EAAE;YACnE,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,CAAC,EAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAC,CAAC,EAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QACrE,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,OAAO,aAAa,CAAA;QACtB,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,GACd,CACH,CAAA;QAED,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,0BAA0B,CAAC,cAAc,EAAE,YAAY,EAAE,GAAG,CAAC,CAAA;QACnE,8CAA8C;QAC9C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;QACxD,MAAM,gBAAgB,CAAC,cAAc,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;QAElD,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKxD,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;QAEvB,MAAM,MAAM,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;YACpC,OAAO;gBACL,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC3D,CAAA;QACH,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,GACd,CACH,CAAA;QAED,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BxD,CAAC,CAAA;QAEF,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,0BAA0B,CAAC,cAAc,EAAE,uBAAuB,EAAE,GAAG,CAAC,CAAA;QAE9E,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BxD,CAAC,CAAA;QAEF,MAAM,yBAAyB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;QAEvD,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BxD,CAAC,CAAA;QAEF,MAAM,0BAA0B,CAAC,cAAc,EAAE,uBAAuB,EAAE,GAAG,CAAC,CAAA;QAC9E,MAAM,yBAAyB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC3D,MAAM,yBAAyB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAE3D,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BxD,CAAC,CAAA;QAEF,MAAM,yBAAyB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAEtD,MAAM,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;KAItE,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;QAEvB,MAAM,MAAM,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;YACpC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;YACxD,OAAO;gBACL,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC3D,CAAA;QACH,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,GACd,CACH,CAAA;QAED,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,0BAA0B,CAAC,cAAc,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAA;QAEjF,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;KAOxD,CAAC,CAAA;QAEF,MAAM,yBAAyB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAEtD,MAAM,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;KAItE,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC/B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAA;QAC1D,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,MAAM,EAAE,MAAM,GACd,CACH,CAAA;QAED,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,0BAA0B,CAAC,cAAc,EAAE,yBAAyB,EAAE,GAAG,CAAC,CAAA;QAEhF,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKxD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC3D,CAAC,CAAA;QACJ,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,MAAM,EAAE,MAAM,GACd,CACH,CAAA;QAED,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,0BAA0B,CAAC,cAAc,EAAE,uBAAuB,EAAE,GAAG,CAAC,CAAA;QAE9E,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BxD,CAAC,CAAA;QAEF,MAAM,yBAAyB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;QAEvD,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BxD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC/B,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,EAAC,WAAW,EAAE,IAAI,EAAC;aAC1B,CAAC,CAAA;QACJ,CAAC,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,YAAY,QACZ,MAAM,EAAE,MAAM,GACd,CACH,CAAA;QAED,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgCxD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACvD,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC;YACnC,8DAA8D;YAC9D,MAAM,EAAE,IAAI,YAAY,CAAC,EAAC,IAAI,EAAE,EAAE,EAAC,CAAQ;YAC3C,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;SAChB,CAAC,CAAA;QAEF,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,kBAAkB,IACjB,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,YAAY,QACZ,MAAM,EAAE,GAAG,EAAE,CACX,OAAO,CAAC,OAAO,CAAC;gBACd,IAAI,EAAE,QAAQ;aACU,CAAC,GAE7B,CACH,CAAA;QAED,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;KAYxD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {AutocompletePrompt, SearchResults} from './AutocompletePrompt.js'\nimport {\n getLastFrameAfterUnmount,\n sendInputAndWait,\n sendInputAndWaitForChange,\n sendInputAndWaitForContent,\n waitForInputsToBeReady,\n} from '../../testing/ui.js'\nimport {OutputStream} from '../../ui.js'\nimport {beforeEach, describe, expect, test, vi} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\nimport {useStdout} from 'ink'\n\nvi.mock('ink', async () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const original: any = await vi.importActual('ink')\n return {\n ...original,\n useStdout: vi.fn(),\n }\n})\n\nconst ARROW_DOWN = '\\u001B[B'\nconst ENTER = '\\r'\nconst DELETE = '\\u007F'\n\nconst DATABASE = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\n {label: 'fifth', value: 'fifth'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n {label: 'eleventh', value: 'eleventh'},\n {label: 'twelfth', value: 'twelfth'},\n {label: 'thirteenth', value: 'thirteenth'},\n {label: 'fourteenth', value: 'fourteenth'},\n {label: 'fifteenth', value: 'fifteenth'},\n {label: 'sixteenth', value: 'sixteenth'},\n {label: 'seventeenth', value: 'seventeenth'},\n {label: 'eighteenth', value: 'eighteenth'},\n {label: 'nineteenth', value: 'nineteenth'},\n {label: 'twentieth', value: 'twentieth'},\n {label: 'twenty-first', value: 'twenty-first'},\n {label: 'twenty-second', value: 'twenty-second'},\n {label: 'twenty-third', value: 'twenty-third'},\n {label: 'twenty-fourth', value: 'twenty-fourth'},\n {label: 'twenty-fifth', value: 'twenty-fifth'},\n {label: 'twenty-sixth', value: 'twenty-sixth'},\n {label: 'twenty-seventh', value: 'twenty-seventh'},\n {label: 'twenty-eighth', value: 'twenty-eighth'},\n {label: 'twenty-ninth', value: 'twenty-ninth'},\n {label: 'thirtieth', value: 'thirtieth'},\n {label: 'thirty-first', value: 'thirty-first'},\n {label: 'thirty-second', value: 'thirty-second'},\n {label: 'thirty-third', value: 'thirty-third'},\n {label: 'thirty-fourth', value: 'thirty-fourth'},\n {label: 'thirty-fifth', value: 'thirty-fifth'},\n {label: 'thirty-sixth', value: 'thirty-sixth'},\n {label: 'thirty-seventh', value: 'thirty-seventh'},\n {label: 'thirty-eighth', value: 'thirty-eighth'},\n {label: 'thirty-ninth', value: 'thirty-ninth'},\n {label: 'fortieth', value: 'fortieth'},\n {label: 'forty-first', value: 'forty-first'},\n {label: 'forty-second', value: 'forty-second'},\n {label: 'forty-third', value: 'forty-third'},\n {label: 'forty-fourth', value: 'forty-fourth'},\n {label: 'forty-fifth', value: 'forty-fifth'},\n {label: 'forty-sixth', value: 'forty-sixth'},\n {label: 'forty-seventh', value: 'forty-seventh'},\n {label: 'forty-eighth', value: 'forty-eighth'},\n {label: 'forty-ninth', value: 'forty-ninth'},\n {label: 'fiftieth', value: 'fiftieth'},\n]\n\nbeforeEach(() => {\n vi.mocked(useStdout).mockReturnValue({\n stdout: new OutputStream({\n columns: 80,\n rows: 80,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n }) as any,\n write: () => {},\n })\n})\n\ndescribe('AutocompletePrompt', async () => {\n test('choose an answer', async () => {\n const onEnter = vi.fn()\n\n const items = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n ]\n\n const infoTable = {Add: ['new-ext'], Remove: ['integrated-demand-ext', 'order-discount']}\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onSubmit={onEnter}\n search={() =>\n Promise.resolve({\n data: [],\n } as SearchResults<string>)\n }\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36msecond\u001b[39m\n \"\n `)\n\n expect(onEnter).toHaveBeenCalledWith(items[1]!.value)\n })\n\n test('renders groups', async () => {\n const items = [\n {label: 'first', value: 'first', group: 'Automations', key: 'f'},\n {label: 'second', value: 'second', group: 'Automations', key: 's'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\n {label: 'fifth', value: 'fifth', key: 'a'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={() => {}}\n search={() =>\n Promise.resolve({\n data: [],\n } as SearchResults<string>)\n }\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n \u001b[1mAutomations\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n\n \u001b[1mMerchant Admin\u001b[22m\n third\n fourth\n\n \u001b[1mOther\u001b[22m\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test('supports an info table', async () => {\n const items = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\n ]\n\n const infoTable = {\n Add: ['new-ext'],\n Remove: ['integrated-demand-ext', 'order-discount'],\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onSubmit={() => {}}\n search={() => Promise.resolve({data: []} as SearchResults<string>)}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n Add: • new-ext\n\n Remove: • integrated-demand-ext\n • order-discount\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test(\"doesn't submit if there are no choices\", async () => {\n const onEnter = vi.fn()\n const searchPromise = Promise.resolve({\n data: [],\n } as SearchResults<string>)\n const search = () => {\n return searchPromise\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'No results found', 'a')\n // prompt doesn't change when enter is pressed\n await new Promise((resolve) => setTimeout(resolve, 100))\n await sendInputAndWait(renderInstance, 100, ENTER)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36ma\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[2mNo results found.\u001b[22m\n \"\n `)\n\n expect(onEnter).not.toHaveBeenCalled()\n })\n\n test('has a loading state', async () => {\n const onEnter = vi.fn()\n const searchPromise = new Promise<SearchResults<string>>((resolve) => {\n setTimeout(() => resolve({data: [{label: 'a', value: 'b'}]}), 2000)\n })\n\n const search = () => {\n return searchPromise\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'Loading...', 'a')\n // prompt doesn't change when enter is pressed\n await new Promise((resolve) => setTimeout(resolve, 100))\n await sendInputAndWait(renderInstance, 100, ENTER)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36ma\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[2mLoading...\u001b[22m\n \"\n `)\n\n expect(onEnter).not.toHaveBeenCalled()\n })\n\n test('allows searching with pagination', async () => {\n const onEnter = vi.fn()\n\n const search = async (term: string) => {\n return {\n data: DATABASE.filter((item) => item.label.includes(term)),\n }\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'th\u001b[1mi\u001b[22mrty-sixth', 'i')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m\n th\u001b[1mi\u001b[22mrd\n f\u001b[1mi\u001b[22mfth\n s\u001b[1mi\u001b[22mxth\n e\u001b[1mi\u001b[22mghth\n n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrteenth\n f\u001b[1mi\u001b[22mfteenth\n s\u001b[1mi\u001b[22mxteenth\n e\u001b[1mi\u001b[22mghteenth\n n\u001b[1mi\u001b[22mneteenth\n twent\u001b[1mi\u001b[22meth\n twenty-f\u001b[1mi\u001b[22mrst\n twenty-th\u001b[1mi\u001b[22mrd\n twenty-f\u001b[1mi\u001b[22mfth\n twenty-s\u001b[1mi\u001b[22mxth\n twenty-e\u001b[1mi\u001b[22mghth\n twenty-n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrtieth\n th\u001b[1mi\u001b[22mrty-first\n th\u001b[1mi\u001b[22mrty-second\n th\u001b[1mi\u001b[22mrty-third\n th\u001b[1mi\u001b[22mrty-fourth\n th\u001b[1mi\u001b[22mrty-fifth\n th\u001b[1mi\u001b[22mrty-sixth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, DELETE)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForContent(renderInstance, 'th\u001b[1mi\u001b[22mrty-sixth', 'i')\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n f\u001b[1mi\u001b[22mrst\n th\u001b[1mi\u001b[22mrd\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mfth\u001b[39m\n s\u001b[1mi\u001b[22mxth\n e\u001b[1mi\u001b[22mghth\n n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrteenth\n f\u001b[1mi\u001b[22mfteenth\n s\u001b[1mi\u001b[22mxteenth\n e\u001b[1mi\u001b[22mghteenth\n n\u001b[1mi\u001b[22mneteenth\n twent\u001b[1mi\u001b[22meth\n twenty-f\u001b[1mi\u001b[22mrst\n twenty-th\u001b[1mi\u001b[22mrd\n twenty-f\u001b[1mi\u001b[22mfth\n twenty-s\u001b[1mi\u001b[22mxth\n twenty-e\u001b[1mi\u001b[22mghth\n twenty-n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrtieth\n th\u001b[1mi\u001b[22mrty-first\n th\u001b[1mi\u001b[22mrty-second\n th\u001b[1mi\u001b[22mrty-third\n th\u001b[1mi\u001b[22mrty-fourth\n th\u001b[1mi\u001b[22mrty-fifth\n th\u001b[1mi\u001b[22mrty-sixth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36mfifth\u001b[39m\n \"\n `)\n\n expect(onEnter).toHaveBeenCalledWith('fifth')\n })\n\n test('allows selecting the first item after searching', async () => {\n const onEnter = vi.fn()\n\n const search = async (term: string) => {\n await new Promise((resolve) => setTimeout(resolve, 300))\n return {\n data: DATABASE.filter((item) => item.label.includes(term)),\n }\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={onEnter}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, '\u001b[1mfiftieth\u001b[22m', 'fiftieth')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mfiftieth\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36m\u001b[1mfiftieth\u001b[22m\u001b[39m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36mfiftieth\u001b[39m\n \"\n `)\n\n expect(onEnter).toHaveBeenCalledWith('fiftieth')\n })\n\n test('displays an error message if the search fails', async () => {\n const search = (_term: string) => {\n return Promise.reject(new Error('Something went wrong'))\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={() => {}}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'There has been an error', 'i')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[31mThere has been an error while searching. Please try again later.\u001b[39m\n \"\n `)\n })\n\n test('immediately shows the initial items if the search is empty', async () => {\n const search = (term: string) => {\n return Promise.resolve({\n data: DATABASE.filter((item) => item.label.includes(term)),\n })\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={() => {}}\n search={search}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'th\u001b[1mi\u001b[22mrty-sixth', 'i')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36mi\u001b[7m \u001b[27m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m\n th\u001b[1mi\u001b[22mrd\n f\u001b[1mi\u001b[22mfth\n s\u001b[1mi\u001b[22mxth\n e\u001b[1mi\u001b[22mghth\n n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrteenth\n f\u001b[1mi\u001b[22mfteenth\n s\u001b[1mi\u001b[22mxteenth\n e\u001b[1mi\u001b[22mghteenth\n n\u001b[1mi\u001b[22mneteenth\n twent\u001b[1mi\u001b[22meth\n twenty-f\u001b[1mi\u001b[22mrst\n twenty-th\u001b[1mi\u001b[22mrd\n twenty-f\u001b[1mi\u001b[22mfth\n twenty-s\u001b[1mi\u001b[22mxth\n twenty-e\u001b[1mi\u001b[22mghth\n twenty-n\u001b[1mi\u001b[22mnth\n th\u001b[1mi\u001b[22mrtieth\n th\u001b[1mi\u001b[22mrty-first\n th\u001b[1mi\u001b[22mrty-second\n th\u001b[1mi\u001b[22mrty-third\n th\u001b[1mi\u001b[22mrty-fourth\n th\u001b[1mi\u001b[22mrty-fifth\n th\u001b[1mi\u001b[22mrty-sixth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, DELETE)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test('shows a message that indicates there are more results than shown', async () => {\n const search = (_term: string) => {\n return Promise.resolve({\n data: DATABASE,\n meta: {hasNextPage: true},\n })\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={() => {}}\n hasMorePages\n search={search}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n fifth\n sixth\n seventh\n eighth\n ninth\n tenth\n eleventh\n twelfth\n thirteenth\n fourteenth\n fifteenth\n sixteenth\n seventeenth\n eighteenth\n nineteenth\n twentieth\n twenty-first\n twenty-second\n twenty-third\n twenty-fourth\n twenty-fifth\n\n \u001b[1m1-25 of many\u001b[22m Find what you're looking for by typing its name.\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test('adapts to the height of the container', async () => {\n vi.mocked(useStdout).mockReturnValue({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stdout: new OutputStream({rows: 10}) as any,\n write: () => {},\n })\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={DATABASE}\n onSubmit={() => {}}\n hasMorePages\n search={() =>\n Promise.resolve({\n data: DATABASE,\n } as SearchResults<string>)\n }\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m\n second\n third\n fourth\n\n \u001b[1m1-25 of many\u001b[22m Find what you're looking for by typing its name.\n \u001b[2mShowing 4 of 25 items.\u001b[22m\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n})\n"]}
@@ -5,13 +5,17 @@ import { FunctionComponent } from 'react';
5
5
  import { Key } from 'ink';
6
6
  import { Writable } from 'stream';
7
7
  export type WritableStream = (process: OutputProcess, index: number) => Writable;
8
+ interface Shortcut {
9
+ key: string;
10
+ action: string;
11
+ }
8
12
  export interface ConcurrentOutputProps {
9
13
  processes: OutputProcess[];
10
14
  abortController: AbortController;
11
15
  showTimestamps?: boolean;
12
16
  onInput?: (input: string, key: Key, exit: () => void) => void;
13
17
  footer?: {
14
- title: string;
18
+ shortcuts: Shortcut[];
15
19
  subTitle?: string;
16
20
  };
17
21
  }
@@ -1,10 +1,10 @@
1
- import { TextWithBackground } from './TextWithBackground.js';
2
1
  import useAsyncAndUnmount from '../hooks/use-async-and-unmount.js';
3
2
  import { handleCtrlC } from '../../ui.js';
4
- import React, { useCallback, useState } from 'react';
3
+ import React, { useState } from 'react';
5
4
  import { Box, Static, Text, useInput } from 'ink';
6
5
  import stripAnsi from 'strip-ansi';
7
6
  import treeKill from 'tree-kill';
7
+ import figures from 'figures';
8
8
  import { Writable } from 'stream';
9
9
  /**
10
10
  * Renders output from concurrent processes to the terminal.
@@ -50,7 +50,7 @@ const ConcurrentOutput = ({ processes, abortController, showTimestamps = true, o
50
50
  const writableStream = (process, index) => {
51
51
  return new Writable({
52
52
  write(chunk, _encoding, next) {
53
- const lines = stripAnsi(chunk.toString('ascii').replace(/(\n)$/, '')).split(/\n/);
53
+ const lines = stripAnsi(chunk.toString('utf8').replace(/(\n)$/, '')).split(/\n/);
54
54
  setProcessOutput((previousProcessOutput) => [
55
55
  ...previousProcessOutput,
56
56
  {
@@ -70,12 +70,10 @@ const ConcurrentOutput = ({ processes, abortController, showTimestamps = true, o
70
70
  await process.action(stdout, stderr, abortController.signal);
71
71
  }));
72
72
  };
73
- if (onInput) {
74
- useInput(useCallback((input, key) => {
75
- handleCtrlC(input, key);
76
- onInput(input, key, () => treeKill(process.pid, 'SIGINT'));
77
- }, [onInput]));
78
- }
73
+ useInput((input, key) => {
74
+ handleCtrlC(input, key);
75
+ onInput(input, key, () => treeKill(process.pid, 'SIGINT'));
76
+ }, { isActive: typeof onInput !== 'undefined' });
79
77
  useAsyncAndUnmount(runProcesses, { onRejected: () => abortController.abort() });
80
78
  return (React.createElement(React.Fragment, null,
81
79
  React.createElement(Static, { items: processOutput }, (chunk, index) => {
@@ -90,10 +88,14 @@ const ConcurrentOutput = ({ processes, abortController, showTimestamps = true, o
90
88
  React.createElement(Box, { flexGrow: 1, paddingLeft: 1 },
91
89
  React.createElement(Text, { color: chunk.color }, line)))))));
92
90
  }),
93
- footer ? (React.createElement(Box, { marginY: 1, flexDirection: "column" },
94
- React.createElement(Box, { flexGrow: 1 },
95
- React.createElement(TextWithBackground, { text: footer.title, inverse: true, paddingX: 2, paddingY: 1 })),
96
- footer.subTitle ? (React.createElement(Box, { marginTop: 1, flexGrow: 1 },
91
+ footer ? (React.createElement(Box, { marginY: 1, flexDirection: "column", flexGrow: 1 },
92
+ React.createElement(Box, { flexDirection: "column" }, footer.shortcuts.map((shortcut, index) => (React.createElement(Text, { key: index },
93
+ figures.pointerSmall,
94
+ " Press ",
95
+ React.createElement(Text, { bold: true }, shortcut.key),
96
+ " | ",
97
+ shortcut.action)))),
98
+ footer.subTitle ? (React.createElement(Box, { marginTop: 1 },
97
99
  React.createElement(Text, null, footer.subTitle))) : null)) : null));
98
100
  };
99
101
  export { ConcurrentOutput };