@shopify/cli-kit 3.35.0 → 3.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/dist/content-tokens.js +1 -1
  2. package/dist/content-tokens.js.map +1 -1
  3. package/dist/error.js +2 -2
  4. package/dist/error.js.map +1 -1
  5. package/dist/index.d.ts +0 -3
  6. package/dist/index.js +0 -3
  7. package/dist/index.js.map +1 -1
  8. package/dist/metadata.d.ts +1 -1
  9. package/dist/metadata.js.map +1 -1
  10. package/dist/monorail.d.ts +1 -1
  11. package/dist/monorail.js +1 -1
  12. package/dist/monorail.js.map +1 -1
  13. package/dist/output.js +0 -4
  14. package/dist/output.js.map +1 -1
  15. package/dist/plugins.d.ts +1 -1
  16. package/dist/plugins.js.map +1 -1
  17. package/dist/{typing → private/common/ts}/deep-required.d.ts +3 -3
  18. package/dist/{typing → private/common/ts}/deep-required.js +0 -0
  19. package/dist/private/common/ts/deep-required.js.map +1 -0
  20. package/dist/{typing → private/common/ts}/overloaded-parameters.d.ts +0 -0
  21. package/dist/{typing → private/common/ts}/overloaded-parameters.js +0 -0
  22. package/dist/private/common/ts/overloaded-parameters.js.map +1 -0
  23. package/dist/private/node/api/graphql.js +1 -2
  24. package/dist/private/node/api/graphql.js.map +1 -1
  25. package/dist/private/node/api/headers.d.ts +9 -0
  26. package/dist/private/node/api/headers.js +26 -0
  27. package/dist/private/node/api/headers.js.map +1 -1
  28. package/dist/private/node/constants.js +3 -3
  29. package/dist/private/node/constants.js.map +1 -1
  30. package/dist/private/node/session/device-authorization.js +1 -1
  31. package/dist/private/node/session/device-authorization.js.map +1 -1
  32. package/dist/private/node/session/exchange.js +1 -1
  33. package/dist/private/node/session/exchange.js.map +1 -1
  34. package/dist/private/node/session/identity-token-validation.js +1 -1
  35. package/dist/private/node/session/identity-token-validation.js.map +1 -1
  36. package/dist/private/node/session/post-auth.js +3 -3
  37. package/dist/private/node/session/post-auth.js.map +1 -1
  38. package/dist/{typing → private/node}/simple-definitions.d.ts +0 -0
  39. package/dist/{typing → private/node}/simple-definitions.js +0 -0
  40. package/dist/private/node/simple-definitions.js.map +1 -0
  41. package/dist/private/node/ui/alert.d.ts +1 -1
  42. package/dist/private/node/ui/alert.js +2 -2
  43. package/dist/private/node/ui/alert.js.map +1 -1
  44. package/dist/private/node/ui/components/Alert.d.ts +5 -0
  45. package/dist/private/node/ui/components/Alert.js +9 -6
  46. package/dist/private/node/ui/components/Alert.js.map +1 -1
  47. package/dist/private/node/ui/components/Alert.test.js +30 -4
  48. package/dist/private/node/ui/components/Alert.test.js.map +1 -1
  49. package/dist/private/node/ui/components/AutocompletePrompt.d.ts +12 -0
  50. package/dist/private/node/ui/components/AutocompletePrompt.js +111 -0
  51. package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -0
  52. package/dist/private/node/ui/components/AutocompletePrompt.test.d.ts +1 -0
  53. package/dist/private/node/ui/components/AutocompletePrompt.test.js +473 -0
  54. package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -0
  55. package/dist/private/node/ui/components/Banner.d.ts +0 -1
  56. package/dist/private/node/ui/components/Banner.js +4 -4
  57. package/dist/private/node/ui/components/Banner.js.map +1 -1
  58. package/dist/private/node/ui/components/Banner.test.js +10 -5
  59. package/dist/private/node/ui/components/Banner.test.js.map +1 -1
  60. package/dist/private/node/ui/components/FatalError.js +1 -1
  61. package/dist/private/node/ui/components/FatalError.js.map +1 -1
  62. package/dist/private/node/ui/components/FatalError.test.js +4 -8
  63. package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
  64. package/dist/private/node/ui/components/{Table.d.ts → Prompts/InfoTable.d.ts} +2 -2
  65. package/dist/private/node/ui/components/{Table.js → Prompts/InfoTable.js} +6 -6
  66. package/dist/private/node/ui/components/Prompts/InfoTable.js.map +1 -0
  67. package/dist/private/node/ui/components/SelectInput.d.ts +9 -2
  68. package/dist/private/node/ui/components/SelectInput.js +96 -52
  69. package/dist/private/node/ui/components/SelectInput.js.map +1 -1
  70. package/dist/private/node/ui/components/SelectInput.test.js +140 -54
  71. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
  72. package/dist/private/node/ui/components/SelectPrompt.d.ts +4 -3
  73. package/dist/private/node/ui/components/SelectPrompt.js +17 -11
  74. package/dist/private/node/ui/components/SelectPrompt.js.map +1 -1
  75. package/dist/private/node/ui/components/SelectPrompt.test.js +113 -23
  76. package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
  77. package/dist/private/node/ui/components/Tasks.d.ts +6 -5
  78. package/dist/private/node/ui/components/Tasks.js +32 -11
  79. package/dist/private/node/ui/components/Tasks.js.map +1 -1
  80. package/dist/private/node/ui/components/Tasks.test.js +55 -9
  81. package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
  82. package/dist/private/node/ui/components/TextInput.d.ts +4 -1
  83. package/dist/private/node/ui/components/TextInput.js +22 -13
  84. package/dist/private/node/ui/components/TextInput.js.map +1 -1
  85. package/dist/private/node/ui/components/TextInput.test.js +47 -40
  86. package/dist/private/node/ui/components/TextInput.test.js.map +1 -1
  87. package/dist/private/node/ui/components/TextPrompt.d.ts +3 -1
  88. package/dist/private/node/ui/components/TextPrompt.js +28 -15
  89. package/dist/private/node/ui/components/TextPrompt.js.map +1 -1
  90. package/dist/private/node/ui/components/TextPrompt.test.js +71 -15
  91. package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
  92. package/dist/private/node/ui/components/TokenizedText.d.ts +3 -0
  93. package/dist/private/node/ui/components/TokenizedText.js +33 -1
  94. package/dist/private/node/ui/components/TokenizedText.js.map +1 -1
  95. package/dist/private/node/ui/utilities.d.ts +2 -0
  96. package/dist/private/node/ui/utilities.js +6 -0
  97. package/dist/private/node/ui/utilities.js.map +1 -0
  98. package/dist/{typing → public/common/ts}/pick-by-prefix.d.ts +4 -3
  99. package/dist/{typing → public/common/ts}/pick-by-prefix.js +0 -0
  100. package/dist/public/common/ts/pick-by-prefix.js.map +1 -0
  101. package/dist/public/common/version.d.ts +1 -1
  102. package/dist/public/common/version.js +1 -1
  103. package/dist/public/common/version.js.map +1 -1
  104. package/dist/public/node/api/admin.js +1 -1
  105. package/dist/public/node/api/admin.js.map +1 -1
  106. package/dist/public/node/api/http.d.ts +0 -0
  107. package/dist/public/node/api/http.js +2 -0
  108. package/dist/public/node/api/http.js.map +1 -0
  109. package/dist/public/node/api/oxygen.js +1 -1
  110. package/dist/public/node/api/oxygen.js.map +1 -1
  111. package/dist/public/node/archiver.js +2 -1
  112. package/dist/public/node/archiver.js.map +1 -1
  113. package/dist/public/node/cli.js +2 -2
  114. package/dist/public/node/cli.js.map +1 -1
  115. package/dist/public/node/environment/spin.js +2 -2
  116. package/dist/public/node/environment/spin.js.map +1 -1
  117. package/dist/public/node/error-handler.js +7 -5
  118. package/dist/public/node/error-handler.js.map +1 -1
  119. package/dist/public/node/framework.js +2 -2
  120. package/dist/public/node/framework.js.map +1 -1
  121. package/dist/public/node/fs.d.ts +22 -4
  122. package/dist/public/node/fs.js +34 -6
  123. package/dist/public/node/fs.js.map +1 -1
  124. package/dist/public/node/github.js +1 -1
  125. package/dist/public/node/github.js.map +1 -1
  126. package/dist/{http/fetch.d.ts → public/node/http.d.ts} +18 -7
  127. package/dist/{http/fetch.js → public/node/http.js} +22 -9
  128. package/dist/public/node/http.js.map +1 -0
  129. package/dist/public/node/liquid.js +4 -4
  130. package/dist/public/node/liquid.js.map +1 -1
  131. package/dist/public/node/node-package-manager.d.ts +22 -1
  132. package/dist/public/node/node-package-manager.js +22 -11
  133. package/dist/public/node/node-package-manager.js.map +1 -1
  134. package/dist/public/node/path.d.ts +22 -0
  135. package/dist/{path.js → public/node/path.js} +8 -20
  136. package/dist/public/node/path.js.map +1 -0
  137. package/dist/public/node/presets.js +4 -4
  138. package/dist/public/node/presets.js.map +1 -1
  139. package/dist/public/node/ruby.js +23 -27
  140. package/dist/public/node/ruby.js.map +1 -1
  141. package/dist/public/node/ui.d.ts +50 -9
  142. package/dist/public/node/ui.js +69 -8
  143. package/dist/public/node/ui.js.map +1 -1
  144. package/dist/public/node/vscode.js +4 -4
  145. package/dist/public/node/vscode.js.map +1 -1
  146. package/dist/testing/ui.d.ts +4 -1
  147. package/dist/testing/ui.js +24 -1
  148. package/dist/testing/ui.js.map +1 -1
  149. package/dist/tsconfig.tsbuildinfo +1 -1
  150. package/dist/ui/executor.d.ts +2 -14
  151. package/dist/ui/executor.js +38 -72
  152. package/dist/ui/executor.js.map +1 -1
  153. package/dist/ui.js +6 -23
  154. package/dist/ui.js.map +1 -1
  155. package/package.json +3 -5
  156. package/dist/http/fetch.js.map +0 -1
  157. package/dist/http/formdata.d.ts +0 -3
  158. package/dist/http/formdata.js +0 -6
  159. package/dist/http/formdata.js.map +0 -1
  160. package/dist/http.d.ts +0 -26
  161. package/dist/http.js +0 -31
  162. package/dist/http.js.map +0 -1
  163. package/dist/npm.d.ts +0 -27
  164. package/dist/npm.js +0 -20
  165. package/dist/npm.js.map +0 -1
  166. package/dist/path.d.ts +0 -25
  167. package/dist/path.js.map +0 -1
  168. package/dist/private/node/ui/components/Table.js.map +0 -1
  169. package/dist/typing/deep-required.js.map +0 -1
  170. package/dist/typing/overloaded-parameters.js.map +0 -1
  171. package/dist/typing/pick-by-prefix.js.map +0 -1
  172. package/dist/typing/simple-definitions.js.map +0 -1
  173. package/dist/ui/inquirer/autocomplete.d.ts +0 -11
  174. package/dist/ui/inquirer/autocomplete.js +0 -110
  175. package/dist/ui/inquirer/autocomplete.js.map +0 -1
  176. package/dist/ui/inquirer/input.d.ts +0 -16
  177. package/dist/ui/inquirer/input.js +0 -45
  178. package/dist/ui/inquirer/input.js.map +0 -1
  179. package/dist/ui/inquirer/password.d.ts +0 -7
  180. package/dist/ui/inquirer/password.js +0 -8
  181. package/dist/ui/inquirer/password.js.map +0 -1
  182. package/dist/ui/inquirer/select.d.ts +0 -14
  183. package/dist/ui/inquirer/select.js +0 -26
  184. package/dist/ui/inquirer/select.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Banner.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Banner.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC5B,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,SAAS,GAAG,CAAC,CAAA;QAErD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,MAAM,GAAG,CAAC,CAAA;QAClD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,SAAS,GAAG,CAAC,CAAA;QACrD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,OAAO,GAAG,CAAC,CAAA;QACnD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,gBAAgB,GAAG,CAAC,CAAA;QAE5D,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {Banner} from './Banner.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('Banner', async () => {\n test('renders with a border for success', async () => {\n const {lastFrame} = render(<Banner type=\"success\" />)\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[32m╭─\u001b[39m success \u001b[32m────────────────────────────────────────────────────────────────────╮\u001b[39m\n \u001b[32m│\u001b[39m \u001b[32m│\u001b[39m\n \u001b[32m│\u001b[39m \u001b[32m│\u001b[39m\n \u001b[32m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[39m\"\n `)\n })\n\n test('renders with a border for info', async () => {\n const {lastFrame} = render(<Banner type=\"info\" />)\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[2m╭─\u001b[22m info \u001b[2m───────────────────────────────────────────────────────────────────────╮\u001b[22m\n \u001b[2m│\u001b[22m \u001b[2m│\u001b[22m\n \u001b[2m│\u001b[22m \u001b[2m│\u001b[22m\n \u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[22m\"\n `)\n })\n\n test('renders with a border for warning', async () => {\n const {lastFrame} = render(<Banner type=\"warning\" />)\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[33m╭─\u001b[39m warning \u001b[33m────────────────────────────────────────────────────────────────────╮\u001b[39m\n \u001b[33m│\u001b[39m \u001b[33m│\u001b[39m\n \u001b[33m│\u001b[39m \u001b[33m│\u001b[39m\n \u001b[33m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[39m\"\n `)\n })\n\n test('renders with a border for error', async () => {\n const {lastFrame} = render(<Banner type=\"error\" />)\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[31m╭─\u001b[39m error \u001b[31m──────────────────────────────────────────────────────────────────────╮\u001b[39m\n \u001b[31m│\u001b[39m \u001b[31m│\u001b[39m\n \u001b[31m│\u001b[39m \u001b[31m│\u001b[39m\n \u001b[31m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[39m\"\n `)\n })\n\n test('renders with a top and bottom lines only for external errors', async () => {\n const {lastFrame} = render(<Banner type=\"external_error\" />)\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[31m──\u001b[39m external error \u001b[31m──────────────────────────────────────────────────────────────\u001b[39m\n\n\n \u001b[31m────────────────────────────────────────────────────────────────────────────────\u001b[39m\"\n `)\n })\n})\n"]}
1
+ {"version":3,"file":"Banner.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Banner.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC5B,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,SAAS,GAAG,CAAC,CAAA;QAErD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAMzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,MAAM,GAAG,CAAC,CAAA;QAClD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAMzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,SAAS,GAAG,CAAC,CAAA;QACrD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAMzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,OAAO,GAAG,CAAC,CAAA;QACnD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAMzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,MAAM,IAAC,IAAI,EAAC,gBAAgB,GAAG,CAAC,CAAA;QAE5D,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAMzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {Banner} from './Banner.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('Banner', async () => {\n test('renders with a border for success', async () => {\n const {lastFrame} = render(<Banner type=\"success\" />)\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[32m╭─\u001b[39m success \u001b[32m────────────────────────────────────────────────────────────────────╮\u001b[39m\n \u001b[32m│\u001b[39m \u001b[32m│\u001b[39m\n \u001b[32m│\u001b[39m \u001b[32m│\u001b[39m\n \u001b[32m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[39m\n \"\n `)\n })\n\n test('renders with a border for info', async () => {\n const {lastFrame} = render(<Banner type=\"info\" />)\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[2m╭─\u001b[22m info \u001b[2m───────────────────────────────────────────────────────────────────────╮\u001b[22m\n \u001b[2m│\u001b[22m \u001b[2m│\u001b[22m\n \u001b[2m│\u001b[22m \u001b[2m│\u001b[22m\n \u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[22m\n \"\n `)\n })\n\n test('renders with a border for warning', async () => {\n const {lastFrame} = render(<Banner type=\"warning\" />)\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[33m╭─\u001b[39m warning \u001b[33m────────────────────────────────────────────────────────────────────╮\u001b[39m\n \u001b[33m│\u001b[39m \u001b[33m│\u001b[39m\n \u001b[33m│\u001b[39m \u001b[33m│\u001b[39m\n \u001b[33m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[39m\n \"\n `)\n })\n\n test('renders with a border for error', async () => {\n const {lastFrame} = render(<Banner type=\"error\" />)\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[31m╭─\u001b[39m error \u001b[31m──────────────────────────────────────────────────────────────────────╮\u001b[39m\n \u001b[31m│\u001b[39m \u001b[31m│\u001b[39m\n \u001b[31m│\u001b[39m \u001b[31m│\u001b[39m\n \u001b[31m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[39m\n \"\n `)\n })\n\n test('renders with a top and bottom lines only for external errors', async () => {\n const {lastFrame} = render(<Banner type=\"external_error\" />)\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[31m──\u001b[39m external error \u001b[31m──────────────────────────────────────────────────────────────\u001b[39m\n\n\n \u001b[31m────────────────────────────────────────────────────────────────────────────────\u001b[39m\n \"\n `)\n })\n})\n"]}
@@ -29,7 +29,7 @@ const FatalError = ({ error }) => {
29
29
  if (error instanceof ExternalError) {
30
30
  tool = `${error.command} ${error.args.join(' ')}`;
31
31
  }
32
- return (React.createElement(Banner, { type: tool ? 'external_error' : 'error', marginY: 1 },
32
+ return (React.createElement(Banner, { type: tool ? 'external_error' : 'error' },
33
33
  tool && (React.createElement(Box, { marginBottom: 1 },
34
34
  React.createElement(Text, null,
35
35
  "Error coming from ",
@@ -1 +1 @@
1
- {"version":3,"file":"FatalError.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FatalError.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Banner} from './Banner.js'\nimport {TokenizedText} from './TokenizedText.js'\nimport {Command} from './Command.js'\nimport {List} from './List.js'\nimport {Bug, cleanSingleStackTracePath, ExternalError, Fatal} from '../../../../error.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\nimport StackTracey from 'stacktracey'\n\nexport interface FatalErrorProps {\n error: Fatal\n}\n\nconst FatalError: React.FC<FatalErrorProps> = ({error}) => {\n let stack\n let tool\n\n if (error instanceof Bug) {\n stack = new StackTracey(error)\n stack.items.forEach((item) => {\n item.file = cleanSingleStackTracePath(item.file)\n })\n\n stack = stack.withSources()\n stack = stack\n .filter((entry) => {\n return !entry.file.includes('@oclif/core')\n })\n .map((item) => {\n /** We make the paths relative to the packages/ directory */\n const fileShortComponents = item.fileShort.split('packages/')\n item.fileShort = fileShortComponents.length === 2 ? fileShortComponents[1]! : fileShortComponents[0]!\n return item\n })\n }\n\n if (error instanceof ExternalError) {\n tool = `${error.command} ${error.args.join(' ')}`\n }\n\n return (\n <Banner type={tool ? 'external_error' : 'error'} marginY={1}>\n {tool && (\n <Box marginBottom={1}>\n <Text>\n Error coming from <Command command={tool} />\n </Text>\n </Box>\n )}\n\n <Box>\n <Text>{error.message}</Text>\n </Box>\n\n {error.tryMessage && (\n <Box marginTop={1}>\n <TokenizedText item={error.tryMessage} />\n </Box>\n )}\n\n {error.nextSteps && (\n <Box marginTop={1}>\n <List title=\"Next steps\" items={error.nextSteps} />\n </Box>\n )}\n\n {stack && stack.items.length !== 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text>To investigate the issue, examine this stack trace:</Text>\n {stack.items.map((item, index) => (\n <Box flexDirection=\"column\" key={index} paddingLeft={2}>\n <Text>\n at{item.calleeShort && <Text color=\"yellow\">{` ${item.calleeShort}`}</Text>}\n {item.fileShort && ` (${item.fileShort}:${item.line})`}\n </Text>\n <Box paddingLeft={2}>\n <Text dimColor>{item.sourceLine?.trim()}</Text>\n </Box>\n </Box>\n ))}\n </Box>\n )}\n </Banner>\n )\n}\n\nexport {FatalError}\n"]}
1
+ {"version":3,"file":"FatalError.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FatalError.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Banner} from './Banner.js'\nimport {TokenizedText} from './TokenizedText.js'\nimport {Command} from './Command.js'\nimport {List} from './List.js'\nimport {Bug, cleanSingleStackTracePath, ExternalError, Fatal} from '../../../../error.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\nimport StackTracey from 'stacktracey'\n\nexport interface FatalErrorProps {\n error: Fatal\n}\n\nconst FatalError: React.FC<FatalErrorProps> = ({error}) => {\n let stack\n let tool\n\n if (error instanceof Bug) {\n stack = new StackTracey(error)\n stack.items.forEach((item) => {\n item.file = cleanSingleStackTracePath(item.file)\n })\n\n stack = stack.withSources()\n stack = stack\n .filter((entry) => {\n return !entry.file.includes('@oclif/core')\n })\n .map((item) => {\n /** We make the paths relative to the packages/ directory */\n const fileShortComponents = item.fileShort.split('packages/')\n item.fileShort = fileShortComponents.length === 2 ? fileShortComponents[1]! : fileShortComponents[0]!\n return item\n })\n }\n\n if (error instanceof ExternalError) {\n tool = `${error.command} ${error.args.join(' ')}`\n }\n\n return (\n <Banner type={tool ? 'external_error' : 'error'}>\n {tool && (\n <Box marginBottom={1}>\n <Text>\n Error coming from <Command command={tool} />\n </Text>\n </Box>\n )}\n\n <Box>\n <Text>{error.message}</Text>\n </Box>\n\n {error.tryMessage && (\n <Box marginTop={1}>\n <TokenizedText item={error.tryMessage} />\n </Box>\n )}\n\n {error.nextSteps && (\n <Box marginTop={1}>\n <List title=\"Next steps\" items={error.nextSteps} />\n </Box>\n )}\n\n {stack && stack.items.length !== 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text>To investigate the issue, examine this stack trace:</Text>\n {stack.items.map((item, index) => (\n <Box flexDirection=\"column\" key={index} paddingLeft={2}>\n <Text>\n at{item.calleeShort && <Text color=\"yellow\">{` ${item.calleeShort}`}</Text>}\n {item.fileShort && ` (${item.fileShort}:${item.line})`}\n </Text>\n <Box paddingLeft={2}>\n <Text dimColor>{item.sourceLine?.trim()}</Text>\n </Box>\n </Box>\n ))}\n </Box>\n )}\n </Banner>\n )\n}\n\nexport {FatalError}\n"]}
@@ -9,8 +9,7 @@ describe('FatalError', async () => {
9
9
  const error = new Abort('test', 'try this');
10
10
  const { lastFrame } = render(React.createElement(FatalError, { error: error }));
11
11
  expect(unstyled(lastFrame())).toMatchInlineSnapshot(`
12
- "
13
- ╭─ error ──────────────────────────────────────────────────────────────────────╮
12
+ "╭─ error ──────────────────────────────────────────────────────────────────────╮
14
13
  │ │
15
14
  │ test │
16
15
  │ │
@@ -31,8 +30,7 @@ describe('FatalError', async () => {
31
30
  `;
32
31
  const { lastFrame } = render(React.createElement(FatalError, { error: error }));
33
32
  expect(unstyled(lastFrame())).toMatchInlineSnapshot(`
34
- "
35
- ╭─ error ──────────────────────────────────────────────────────────────────────╮
33
+ "╭─ error ──────────────────────────────────────────────────────────────────────╮
36
34
  │ │
37
35
  │ Unexpected error │
38
36
  │ │
@@ -78,8 +76,7 @@ describe('FatalError', async () => {
78
76
  ];
79
77
  const { lastFrame } = render(React.createElement(FatalError, { error: error }));
80
78
  expect(unstyled(lastFrame())).toMatchInlineSnapshot(`
81
- "
82
- ╭─ error ──────────────────────────────────────────────────────────────────────╮
79
+ "╭─ error ──────────────────────────────────────────────────────────────────────╮
83
80
  │ │
84
81
  │ Unexpected error │
85
82
  │ │
@@ -104,8 +101,7 @@ describe('FatalError', async () => {
104
101
  const error = new ExternalError('Unexpected error', 'yarn', ['install']);
105
102
  const { lastFrame } = render(React.createElement(FatalError, { error: error }));
106
103
  expect(unstyled(lastFrame())).toMatchInlineSnapshot(`
107
- "
108
- ── external error ──────────────────────────────────────────────────────────────
104
+ "── external error ──────────────────────────────────────────────────────────────
109
105
 
110
106
  Error coming from \`yarn install\`
111
107
 
@@ -1 +1 @@
1
- {"version":3,"file":"FatalError.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FatalError.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAC,KAAK,EAAE,GAAG,EAAE,aAAa,EAAC,MAAM,sBAAsB,CAAA;AAC9D,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAChC,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAC3C,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAUpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;KAcpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,KAAK,CAAC,SAAS,GAAG;YAChB;gBACE,UAAU;gBACV;oBACE,IAAI,EAAE;wBACJ,KAAK,EAAE,yCAAyC;wBAChD,GAAG,EAAE,qCAAqC;qBAC3C;iBACF;gBACD;oBACE,IAAI,EAAE,GAAG;iBACV;aACF;YACD,gEAAgE;YAChE;gBACE,gFAAgF;gBAChF;oBACE,OAAO,EAAE,SAAS;iBACnB;aACF;SACF,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;KAqBpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;QAExE,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAUpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {FatalError} from './FatalError.js'\nimport {unstyled} from '../../../../output.js'\nimport {Abort, Bug, ExternalError} from '../../../../error.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('FatalError', async () => {\n test('renders correctly with a just a message and tryMessage', async () => {\n const error = new Abort('test', 'try this')\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ test │\n │ │\n │ try this │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly with a message and a stack', async () => {\n const error = new Bug('Unexpected error')\n error.stack = `\n Error: Unexpected error\n at Module._compile (internal/modules/cjs/loader.js:1137:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)\n at Module.load (internal/modules/cjs/loader.js:985:32)\n at Function.Module._load (internal/modules/cjs/loader.js:878:14)\n `\n\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Unexpected error │\n │ │\n │ To investigate the issue, examine this stack trace: │\n │ at _compile (internal/modules/cjs/loader.js:1137) │\n │ at js (internal/modules/cjs/loader.js:1157) │\n │ at load (internal/modules/cjs/loader.js:985) │\n │ at _load (internal/modules/cjs/loader.js:878) │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly with a message, a stack, and next steps', async () => {\n const error = new Bug('Unexpected error')\n error.stack = `\n Error: Unexpected error\n at Module._compile (internal/modules/cjs/loader.js:1137:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)\n at Module.load (internal/modules/cjs/loader.js:985:32)\n at Function.Module._load (internal/modules/cjs/loader.js:878:14)\n `\n\n error.nextSteps = [\n [\n 'Have you',\n {\n link: {\n label: 'created a Shopify Partners organization',\n url: 'https://partners.shopify.com/signup',\n },\n },\n {\n char: '?',\n },\n ],\n 'Have you confirmed your accounts from the emails you received?',\n [\n 'Need to connect to a different App or organization? Run the command again with',\n {\n command: '--reset',\n },\n ],\n ]\n\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Unexpected error │\n │ │\n │ Next steps │\n │ • Have you created a Shopify Partners organization ( │\n │ https://partners.shopify.com/signup )? │\n │ • Have you confirmed your accounts from the emails you received? │\n │ • Need to connect to a different App or organization? Run the command │\n │ again with \\`--reset\\` │\n │ │\n │ To investigate the issue, examine this stack trace: │\n │ at _compile (internal/modules/cjs/loader.js:1137) │\n │ at js (internal/modules/cjs/loader.js:1157) │\n │ at load (internal/modules/cjs/loader.js:985) │\n │ at _load (internal/modules/cjs/loader.js:878) │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly an external error', async () => {\n const error = new ExternalError('Unexpected error', 'yarn', ['install'])\n\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"\n ── external error ──────────────────────────────────────────────────────────────\n\n Error coming from \\`yarn install\\`\n\n Unexpected error\n\n ────────────────────────────────────────────────────────────────────────────────\n \"\n `)\n })\n})\n"]}
1
+ {"version":3,"file":"FatalError.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FatalError.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAC,KAAK,EAAE,GAAG,EAAE,aAAa,EAAC,MAAM,sBAAsB,CAAA;AAC9D,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAChC,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAC3C,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;KASpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;KAapD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,KAAK,CAAC,SAAS,GAAG;YAChB;gBACE,UAAU;gBACV;oBACE,IAAI,EAAE;wBACJ,KAAK,EAAE,yCAAyC;wBAChD,GAAG,EAAE,qCAAqC;qBAC3C;iBACF;gBACD;oBACE,IAAI,EAAE,GAAG;iBACV;aACF;YACD,gEAAgE;YAChE;gBACE,gFAAgF;gBAChF;oBACE,OAAO,EAAE,SAAS;iBACnB;aACF;SACF,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;KAoBpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;QAExE,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;KASpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {FatalError} from './FatalError.js'\nimport {unstyled} from '../../../../output.js'\nimport {Abort, Bug, ExternalError} from '../../../../error.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('FatalError', async () => {\n test('renders correctly with a just a message and tryMessage', async () => {\n const error = new Abort('test', 'try this')\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ test │\n │ │\n │ try this │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly with a message and a stack', async () => {\n const error = new Bug('Unexpected error')\n error.stack = `\n Error: Unexpected error\n at Module._compile (internal/modules/cjs/loader.js:1137:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)\n at Module.load (internal/modules/cjs/loader.js:985:32)\n at Function.Module._load (internal/modules/cjs/loader.js:878:14)\n `\n\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Unexpected error │\n │ │\n │ To investigate the issue, examine this stack trace: │\n │ at _compile (internal/modules/cjs/loader.js:1137) │\n │ at js (internal/modules/cjs/loader.js:1157) │\n │ at load (internal/modules/cjs/loader.js:985) │\n │ at _load (internal/modules/cjs/loader.js:878) │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly with a message, a stack, and next steps', async () => {\n const error = new Bug('Unexpected error')\n error.stack = `\n Error: Unexpected error\n at Module._compile (internal/modules/cjs/loader.js:1137:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)\n at Module.load (internal/modules/cjs/loader.js:985:32)\n at Function.Module._load (internal/modules/cjs/loader.js:878:14)\n `\n\n error.nextSteps = [\n [\n 'Have you',\n {\n link: {\n label: 'created a Shopify Partners organization',\n url: 'https://partners.shopify.com/signup',\n },\n },\n {\n char: '?',\n },\n ],\n 'Have you confirmed your accounts from the emails you received?',\n [\n 'Need to connect to a different App or organization? Run the command again with',\n {\n command: '--reset',\n },\n ],\n ]\n\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Unexpected error │\n │ │\n │ Next steps │\n │ • Have you created a Shopify Partners organization ( │\n │ https://partners.shopify.com/signup )? │\n │ • Have you confirmed your accounts from the emails you received? │\n │ • Need to connect to a different App or organization? Run the command │\n │ again with \\`--reset\\` │\n │ │\n │ To investigate the issue, examine this stack trace: │\n │ at _compile (internal/modules/cjs/loader.js:1137) │\n │ at js (internal/modules/cjs/loader.js:1157) │\n │ at load (internal/modules/cjs/loader.js:985) │\n │ at _load (internal/modules/cjs/loader.js:878) │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly an external error', async () => {\n const error = new ExternalError('Unexpected error', 'yarn', ['install'])\n\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"── external error ──────────────────────────────────────────────────────────────\n\n Error coming from \\`yarn install\\`\n\n Unexpected error\n\n ────────────────────────────────────────────────────────────────────────────────\n \"\n `)\n })\n})\n"]}
@@ -4,5 +4,5 @@ export interface Props {
4
4
  [header: string]: string[];
5
5
  };
6
6
  }
7
- declare const Table: React.FC<Props>;
8
- export default Table;
7
+ declare const InfoTable: React.FC<Props>;
8
+ export default InfoTable;
@@ -1,11 +1,11 @@
1
- import { List } from './List.js';
2
- import { capitalize } from '../../../../public/common/string.js';
1
+ import { List } from '../List.js';
2
+ import { capitalize } from '../../../../../public/common/string.js';
3
3
  import { Box, Text } from 'ink';
4
4
  import React from 'react';
5
- const Table = ({ table }) => {
5
+ const InfoTable = ({ table }) => {
6
6
  const headers = Object.keys(table);
7
7
  const headerColumnWidth = Math.max(...headers.map((header) => header.length));
8
- return (React.createElement(Box, { flexDirection: "column", paddingY: 1 }, headers.map((header, index) => (React.createElement(Box, { key: index, marginBottom: index === headers.length - 1 ? 0 : 1 },
8
+ return (React.createElement(Box, { flexDirection: "column" }, headers.map((header, index) => (React.createElement(Box, { key: index, marginBottom: index === headers.length - 1 ? 0 : 1 },
9
9
  React.createElement(Box, { width: headerColumnWidth + 1 },
10
10
  React.createElement(Text, null,
11
11
  capitalize(header),
@@ -13,5 +13,5 @@ const Table = ({ table }) => {
13
13
  React.createElement(Box, { flexGrow: 1 },
14
14
  React.createElement(List, { items: table[header] })))))));
15
15
  };
16
- export default Table;
17
- //# sourceMappingURL=Table.js.map
16
+ export default InfoTable;
17
+ //# sourceMappingURL=InfoTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InfoTable.js","sourceRoot":"","sources":["../../../../../../src/private/node/ui/components/Prompts/InfoTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAA;AAC/B,OAAO,EAAC,UAAU,EAAC,MAAM,wCAAwC,CAAA;AACjE,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,MAAM,SAAS,GAAoB,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAClC,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAE7E,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,IACxB,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9B,oBAAC,GAAG,IAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,oBAAC,GAAG,IAAC,KAAK,EAAE,iBAAiB,GAAG,CAAC;YAC/B,oBAAC,IAAI;gBAAE,UAAU,CAAC,MAAM,CAAC;oBAAS,CAC9B;QACN,oBAAC,GAAG,IAAC,QAAQ,EAAE,CAAC;YACd,oBAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAE,GAAI,CAC3B,CACF,CACP,CAAC,CACE,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,SAAS,CAAA","sourcesContent":["import {List} from '../List.js'\nimport {capitalize} from '../../../../../public/common/string.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\n\nexport interface Props {\n table: {\n [header: string]: string[]\n }\n}\n\nconst InfoTable: React.FC<Props> = ({table}) => {\n const headers = Object.keys(table)\n const headerColumnWidth = Math.max(...headers.map((header) => header.length))\n\n return (\n <Box flexDirection=\"column\">\n {headers.map((header, index) => (\n <Box key={index} marginBottom={index === headers.length - 1 ? 0 : 1}>\n <Box width={headerColumnWidth + 1}>\n <Text>{capitalize(header)}:</Text>\n </Box>\n <Box flexGrow={1}>\n <List items={table[header]!} />\n </Box>\n </Box>\n ))}\n </Box>\n )\n}\n\nexport default InfoTable\n"]}
@@ -1,7 +1,14 @@
1
1
  import React from 'react';
2
2
  export interface Props<T> {
3
3
  items: Item<T>[];
4
- onChange: (item: Item<T>) => void;
4
+ onChange: (item: Item<T> | undefined) => void;
5
+ enableShortcuts?: boolean;
6
+ focus?: boolean;
7
+ emptyMessage?: string;
8
+ defaultValue?: Item<T>;
9
+ highlightedTerm?: string;
10
+ loading?: boolean;
11
+ errorMessage?: string;
5
12
  }
6
13
  export interface Item<T> {
7
14
  label: string;
@@ -9,4 +16,4 @@ export interface Item<T> {
9
16
  key?: string;
10
17
  group?: string;
11
18
  }
12
- export default function SelectInput<T>({ items, onChange }: React.PropsWithChildren<Props<T>>): JSX.Element | null;
19
+ export default function SelectInput<T>({ items, onChange, enableShortcuts, focus, emptyMessage, defaultValue, highlightedTerm, loading, errorMessage, }: React.PropsWithChildren<Props<T>>): JSX.Element | null;
@@ -1,23 +1,55 @@
1
1
  import { isEqual } from '../../../../public/common/lang.js';
2
- import { groupBy } from '../../../../public/common/collection.js';
2
+ import { groupBy, partition } from '../../../../public/common/collection.js';
3
3
  import { mapValues } from '../../../../public/common/object.js';
4
4
  import React, { useState, useEffect, useRef, useCallback } from 'react';
5
5
  import { Box, useInput, Text } from 'ink';
6
+ import { debounce } from '@shopify/cli-kit/common/function';
7
+ import chalk from 'chalk';
8
+ import figures from 'figures';
9
+ function highlightedLabel(label, term) {
10
+ if (!term) {
11
+ return label;
12
+ }
13
+ const regex = new RegExp(term, 'i');
14
+ return label.replace(regex, (match) => {
15
+ return chalk.bold(match);
16
+ });
17
+ }
6
18
  function groupItems(items) {
7
19
  let index = 0;
8
- return mapValues(groupBy(items, 'group'), (groupItems) => groupItems.map((groupItem) => {
20
+ const [withGroup, withoutGroup] = partition(items, 'group');
21
+ const withGroupMapped = mapValues(groupBy(withGroup, 'group'), (groupItems) => groupItems.map((groupItem) => {
9
22
  const item = { ...groupItem, key: groupItem.key ?? (index + 1).toString(), index };
10
23
  index += 1;
11
24
  return item;
12
25
  }));
26
+ const withoutGroupMapped = withoutGroup.map((item) => {
27
+ const newItem = { ...item, key: item.key ?? (index + 1).toString(), index };
28
+ index += 1;
29
+ return newItem;
30
+ });
31
+ return [withGroupMapped, withoutGroupMapped];
32
+ }
33
+ function SelectItemsGroup({ title, items, selectedIndex, hasMarginTop, enableShortcuts, highlightedTerm, }) {
34
+ return (React.createElement(Box, { key: title, flexDirection: "column", marginTop: hasMarginTop ? 1 : 0 },
35
+ title && (React.createElement(Box, { marginLeft: 3 },
36
+ React.createElement(Text, { bold: true }, title))),
37
+ items.map((item) => {
38
+ const isSelected = item.index === selectedIndex;
39
+ const label = highlightedLabel(item.label, highlightedTerm);
40
+ return (React.createElement(Box, { key: item.key },
41
+ React.createElement(Box, { marginRight: 2 }, isSelected ? React.createElement(Text, { color: "cyan" }, `>`) : React.createElement(Text, null, " ")),
42
+ React.createElement(Text, { color: isSelected ? 'cyan' : undefined }, enableShortcuts ? `(${item.key}) ${label}` : label)));
43
+ })));
13
44
  }
14
- export default function SelectInput({ items, onChange }) {
15
- const [inputStack, setInputStack] = useState(null);
16
- const [inputTimeout, setInputTimeout] = useState(null);
17
- const [selectedIndex, setSelectedIndex] = useState(0);
18
- const keys = useRef(new Set(items.map((item) => item.key)));
19
- const groupedItems = groupItems(items);
20
- const groupedItemsValues = Object.values(groupedItems).flat();
45
+ export default function SelectInput({ items, onChange, enableShortcuts = true, focus = true, emptyMessage = 'No items to select.', defaultValue, highlightedTerm, loading = false, errorMessage, }) {
46
+ const defaultValueIndex = defaultValue ? items.findIndex((item) => item.value === defaultValue.value) : -1;
47
+ const initialIndex = defaultValueIndex === -1 ? 0 : defaultValueIndex;
48
+ const inputStack = useRef(null);
49
+ const [selectedIndex, setSelectedIndex] = useState(initialIndex);
50
+ const [groupedItems, ungroupedItems] = groupItems(items);
51
+ const groupedItemsValues = [...Object.values(groupedItems).flat(), ...ungroupedItems];
52
+ const keys = groupedItemsValues.map((item) => item.key);
21
53
  const groupTitles = Object.keys(groupedItems);
22
54
  const previousItems = useRef(items);
23
55
  const changeSelection = useCallback((index) => {
@@ -25,63 +57,75 @@ export default function SelectInput({ items, onChange }) {
25
57
  setSelectedIndex(index);
26
58
  onChange(items.find((item) => item.value === groupedItem.value));
27
59
  }, [items]);
28
- // reset index when items change
29
60
  useEffect(() => {
30
- if (!isEqual(previousItems.current.map((item) => item.value), items.map((item) => item.value))) {
61
+ if (items.length === 0) {
62
+ // reset selection when items are empty
63
+ onChange(undefined);
64
+ }
65
+ else if (
66
+ // reset index when items change
67
+ !isEqual(previousItems.current.map((item) => item.value), items.map((item) => item.value))) {
31
68
  changeSelection(0);
32
69
  }
33
70
  previousItems.current = items;
34
71
  }, [items]);
35
- const handleInput = useCallback((input, key) => {
36
- const parsedInput = parseInt(input, 10);
37
- if (parsedInput !== 0 && parsedInput <= items.length + 1) {
38
- changeSelection(parsedInput - 1);
39
- }
40
- else if (keys.current.has(input)) {
41
- const groupedItem = groupedItemsValues.find((item) => item.key === input);
42
- if (groupedItem !== undefined) {
43
- changeSelection(groupedItem.index);
44
- }
45
- }
72
+ const handleArrows = useCallback((key) => {
73
+ const lastIndex = items.length - 1;
46
74
  if (key.upArrow) {
47
- const lastIndex = items.length - 1;
48
75
  changeSelection(selectedIndex === 0 ? lastIndex : selectedIndex - 1);
49
76
  }
50
77
  else if (key.downArrow) {
51
- changeSelection(selectedIndex === items.length - 1 ? 0 : selectedIndex + 1);
78
+ changeSelection(selectedIndex === lastIndex ? 0 : selectedIndex + 1);
52
79
  }
53
80
  }, [selectedIndex, items]);
54
- useInput((input, key) => {
55
- if (input.length > 0 && Object.values(key).every((value) => value === false)) {
56
- const newInputStack = inputStack === null ? input : inputStack + input;
57
- setInputStack(newInputStack);
58
- if (inputTimeout !== null) {
59
- clearTimeout(inputTimeout);
81
+ const handleShortcuts = useCallback((input) => {
82
+ if (keys.includes(input)) {
83
+ const groupedItem = groupedItemsValues.find((item) => item.key === input);
84
+ if (groupedItem !== undefined) {
85
+ changeSelection(groupedItem.index);
60
86
  }
61
- setInputTimeout(setTimeout(() => {
62
- handleInput(newInputStack, key);
63
- setInputStack(null);
64
- setInputTimeout(null);
65
- }, 300));
87
+ }
88
+ }, [items]);
89
+ const debounceHandleShortcuts = useCallback(debounce((newInputStack) => {
90
+ handleShortcuts(newInputStack);
91
+ inputStack.current = null;
92
+ }, 300), []);
93
+ useInput((input, key) => {
94
+ // check that no special modifier (shift, control, etc.) is being pressed
95
+ if (enableShortcuts && input.length > 0 && Object.values(key).every((value) => value === false)) {
96
+ const newInputStack = inputStack.current === null ? input : inputStack.current + input;
97
+ inputStack.current = newInputStack;
98
+ debounceHandleShortcuts(newInputStack);
66
99
  }
67
100
  else {
68
- handleInput(input, key);
101
+ debounceHandleShortcuts.cancel();
102
+ inputStack.current = null;
103
+ handleArrows(key);
69
104
  }
70
- });
71
- return (React.createElement(Box, { flexDirection: "column" },
72
- groupTitles.map((title) => {
73
- const hasTitle = title !== 'undefined';
74
- return (React.createElement(Box, { key: title, flexDirection: "column", marginTop: hasTitle ? 1 : 0 },
75
- hasTitle && (React.createElement(Box, { marginLeft: 3 },
76
- React.createElement(Text, { bold: true }, title))),
77
- groupedItems[title].map((item) => {
78
- const isSelected = item.index === selectedIndex;
79
- return (React.createElement(Box, { key: item.key },
80
- React.createElement(Box, { marginRight: 2 }, isSelected ? React.createElement(Text, { color: "cyan" }, `>`) : React.createElement(Text, null, " ")),
81
- React.createElement(Text, { color: isSelected ? 'cyan' : undefined }, `(${item.key}) ${item.label}`)));
82
- })));
83
- }),
84
- React.createElement(Box, { marginTop: 1, marginLeft: 3 },
85
- React.createElement(Text, { dimColor: true }, "navigate with arrows, enter to select"))));
105
+ }, { isActive: focus });
106
+ const ungroupedItemsTitle = groupTitles.length > 0 ? 'Other' : undefined;
107
+ if (loading) {
108
+ return (React.createElement(Box, { marginLeft: 3 },
109
+ React.createElement(Text, { dimColor: true }, "Loading...")));
110
+ }
111
+ else if (errorMessage && errorMessage.length > 0) {
112
+ return (React.createElement(Box, { marginLeft: 3 },
113
+ React.createElement(Text, { color: "red" }, errorMessage)));
114
+ }
115
+ else if (items.length === 0) {
116
+ return (React.createElement(Box, { marginLeft: 3 },
117
+ React.createElement(Text, { dimColor: true }, emptyMessage)));
118
+ }
119
+ else {
120
+ return (React.createElement(Box, { flexDirection: "column" },
121
+ groupTitles.map((title, index) => (React.createElement(SelectItemsGroup, { title: title, selectedIndex: selectedIndex, items: groupedItems[title], key: title, hasMarginTop: index !== 0, enableShortcuts: enableShortcuts, highlightedTerm: highlightedTerm }))),
122
+ ungroupedItems.length > 0 && (React.createElement(SelectItemsGroup, { title: ungroupedItemsTitle, selectedIndex: selectedIndex, items: ungroupedItems, hasMarginTop: groupTitles.length > 0, enableShortcuts: enableShortcuts, highlightedTerm: highlightedTerm })),
123
+ React.createElement(Box, { marginTop: 1, marginLeft: 3 },
124
+ React.createElement(Text, { dimColor: true },
125
+ "Press ",
126
+ figures.arrowUp,
127
+ figures.arrowDown,
128
+ " arrows to select, enter to confirm"))));
129
+ }
86
130
  }
87
131
  //# sourceMappingURL=SelectInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SelectInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {isEqual} from '../../../../public/common/lang.js'\nimport {groupBy} from '../../../../public/common/collection.js'\nimport {mapValues} from '../../../../public/common/object.js'\nimport React, {useState, useEffect, useRef, useCallback} from 'react'\nimport {Box, Key, useInput, Text} from 'ink'\n\nexport interface Props<T> {\n items: Item<T>[]\n onChange: (item: Item<T>) => void\n}\n\nexport interface Item<T> {\n label: string\n value: T\n key?: string\n group?: string\n}\n\nfunction groupItems<T>(items: Item<T>[]) {\n let index = 0\n\n return mapValues(groupBy(items, 'group'), (groupItems) =>\n groupItems.map((groupItem) => {\n const item = {...groupItem, key: groupItem.key ?? (index + 1).toString(), index}\n index += 1\n return item\n }),\n )\n}\n\nexport default function SelectInput<T>({items, onChange}: React.PropsWithChildren<Props<T>>): JSX.Element | null {\n const [inputStack, setInputStack] = useState<string | null>(null)\n const [inputTimeout, setInputTimeout] = useState<NodeJS.Timeout | null>(null)\n const [selectedIndex, setSelectedIndex] = useState(0)\n const keys = useRef(new Set(items.map((item) => item.key)))\n const groupedItems = groupItems(items)\n const groupedItemsValues = Object.values(groupedItems).flat()\n const groupTitles = Object.keys(groupedItems)\n const previousItems = useRef<Item<T>[]>(items)\n\n const changeSelection = useCallback(\n (index: number) => {\n const groupedItem = groupedItemsValues.find((item) => item.index === index)!\n setSelectedIndex(index)\n onChange(items.find((item) => item.value === groupedItem.value)!)\n },\n [items],\n )\n\n // reset index when items change\n useEffect(() => {\n if (\n !isEqual(\n previousItems.current.map((item) => item.value),\n items.map((item) => item.value),\n )\n ) {\n changeSelection(0)\n }\n\n previousItems.current = items\n }, [items])\n\n const handleInput = useCallback(\n (input: string, key: Key) => {\n const parsedInput = parseInt(input, 10)\n\n if (parsedInput !== 0 && parsedInput <= items.length + 1) {\n changeSelection(parsedInput - 1)\n } else if (keys.current.has(input)) {\n const groupedItem = groupedItemsValues.find((item) => item.key === input)\n if (groupedItem !== undefined) {\n changeSelection(groupedItem.index)\n }\n }\n\n if (key.upArrow) {\n const lastIndex = items.length - 1\n\n changeSelection(selectedIndex === 0 ? lastIndex : selectedIndex - 1)\n } else if (key.downArrow) {\n changeSelection(selectedIndex === items.length - 1 ? 0 : selectedIndex + 1)\n }\n },\n [selectedIndex, items],\n )\n\n useInput((input, key) => {\n if (input.length > 0 && Object.values(key).every((value) => value === false)) {\n const newInputStack = inputStack === null ? input : inputStack + input\n\n setInputStack(newInputStack)\n\n if (inputTimeout !== null) {\n clearTimeout(inputTimeout)\n }\n\n setInputTimeout(\n setTimeout(() => {\n handleInput(newInputStack, key)\n setInputStack(null)\n setInputTimeout(null)\n }, 300),\n )\n } else {\n handleInput(input, key)\n }\n })\n\n return (\n <Box flexDirection=\"column\">\n {groupTitles.map((title) => {\n const hasTitle = title !== 'undefined'\n\n return (\n <Box key={title} flexDirection=\"column\" marginTop={hasTitle ? 1 : 0}>\n {hasTitle && (\n <Box marginLeft={3}>\n <Text bold>{title}</Text>\n </Box>\n )}\n {groupedItems[title]!.map((item) => {\n const isSelected = item.index === selectedIndex\n\n return (\n <Box key={item.key}>\n <Box marginRight={2}>{isSelected ? <Text color=\"cyan\">{`>`}</Text> : <Text> </Text>}</Box>\n\n <Text color={isSelected ? 'cyan' : undefined}>{`(${item.key}) ${item.label}`}</Text>\n </Box>\n )\n })}\n </Box>\n )\n })}\n\n <Box marginTop={1} marginLeft={3}>\n <Text dimColor>navigate with arrows, enter to select</Text>\n </Box>\n </Box>\n )\n}\n"]}
1
+ {"version":3,"file":"SelectInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {isEqual} from '../../../../public/common/lang.js'\nimport {groupBy, partition} from '../../../../public/common/collection.js'\nimport {mapValues} from '../../../../public/common/object.js'\nimport React, {useState, useEffect, useRef, useCallback} from 'react'\nimport {Box, Key, useInput, Text} from 'ink'\nimport {debounce} from '@shopify/cli-kit/common/function'\nimport chalk from 'chalk'\nimport figures from 'figures'\n\nexport interface Props<T> {\n items: Item<T>[]\n onChange: (item: Item<T> | undefined) => void\n enableShortcuts?: boolean\n focus?: boolean\n emptyMessage?: string\n defaultValue?: Item<T>\n highlightedTerm?: string\n loading?: boolean\n errorMessage?: string\n}\n\nexport interface Item<T> {\n label: string\n value: T\n key?: string\n group?: string\n}\n\ninterface ItemWithIndex<T> extends Item<T> {\n key: string\n index: number\n}\n\nfunction highlightedLabel(label: string, term: string | undefined) {\n if (!term) {\n return label\n }\n\n const regex = new RegExp(term, 'i')\n return label.replace(regex, (match) => {\n return chalk.bold(match)\n })\n}\n\nfunction groupItems<T>(items: Item<T>[]): [{[key: string]: ItemWithIndex<T>[]}, ItemWithIndex<T>[]] {\n let index = 0\n\n const [withGroup, withoutGroup] = partition(items, 'group')\n\n const withGroupMapped = mapValues(groupBy(withGroup, 'group'), (groupItems) =>\n groupItems.map((groupItem) => {\n const item = {...groupItem, key: groupItem.key ?? (index + 1).toString(), index}\n index += 1\n return item\n }),\n )\n const withoutGroupMapped = withoutGroup.map((item) => {\n const newItem = {...item, key: item.key ?? (index + 1).toString(), index}\n index += 1\n return newItem\n })\n\n return [withGroupMapped, withoutGroupMapped]\n}\n\ninterface SelectItemsGroupProps<T> {\n title: string | undefined\n items: ItemWithIndex<T>[]\n selectedIndex: number\n hasMarginTop: boolean\n enableShortcuts: boolean\n highlightedTerm?: string\n}\n\nfunction SelectItemsGroup<T>({\n title,\n items,\n selectedIndex,\n hasMarginTop,\n enableShortcuts,\n highlightedTerm,\n}: SelectItemsGroupProps<T>): JSX.Element {\n return (\n <Box key={title} flexDirection=\"column\" marginTop={hasMarginTop ? 1 : 0}>\n {title && (\n <Box marginLeft={3}>\n <Text bold>{title}</Text>\n </Box>\n )}\n\n {items.map((item) => {\n const isSelected = item.index === selectedIndex\n const label = highlightedLabel(item.label, highlightedTerm)\n\n return (\n <Box key={item.key}>\n <Box marginRight={2}>{isSelected ? <Text color=\"cyan\">{`>`}</Text> : <Text> </Text>}</Box>\n\n <Text color={isSelected ? 'cyan' : undefined}>{enableShortcuts ? `(${item.key}) ${label}` : label}</Text>\n </Box>\n )\n })}\n </Box>\n )\n}\n\nexport default function SelectInput<T>({\n items,\n onChange,\n enableShortcuts = true,\n focus = true,\n emptyMessage = 'No items to select.',\n defaultValue,\n highlightedTerm,\n loading = false,\n errorMessage,\n}: React.PropsWithChildren<Props<T>>): JSX.Element | null {\n const defaultValueIndex = defaultValue ? items.findIndex((item) => item.value === defaultValue.value) : -1\n const initialIndex = defaultValueIndex === -1 ? 0 : defaultValueIndex\n const inputStack = useRef<string | null>(null)\n const [selectedIndex, setSelectedIndex] = useState(initialIndex)\n const [groupedItems, ungroupedItems] = groupItems(items)\n const groupedItemsValues = [...Object.values(groupedItems).flat(), ...ungroupedItems]\n const keys = groupedItemsValues.map((item) => item.key)\n const groupTitles = Object.keys(groupedItems)\n const previousItems = useRef<Item<T>[]>(items)\n\n const changeSelection = useCallback(\n (index: number) => {\n const groupedItem = groupedItemsValues.find((item) => item.index === index)!\n setSelectedIndex(index)\n onChange(items.find((item) => item.value === groupedItem.value))\n },\n [items],\n )\n\n useEffect(() => {\n if (items.length === 0) {\n // reset selection when items are empty\n onChange(undefined)\n } else if (\n // reset index when items change\n !isEqual(\n previousItems.current.map((item) => item.value),\n items.map((item) => item.value),\n )\n ) {\n changeSelection(0)\n }\n\n previousItems.current = items\n }, [items])\n\n const handleArrows = useCallback(\n (key: Key) => {\n const lastIndex = items.length - 1\n\n if (key.upArrow) {\n changeSelection(selectedIndex === 0 ? lastIndex : selectedIndex - 1)\n } else if (key.downArrow) {\n changeSelection(selectedIndex === lastIndex ? 0 : selectedIndex + 1)\n }\n },\n [selectedIndex, items],\n )\n\n const handleShortcuts = useCallback(\n (input: string) => {\n if (keys.includes(input)) {\n const groupedItem = groupedItemsValues.find((item) => item.key === input)\n if (groupedItem !== undefined) {\n changeSelection(groupedItem.index)\n }\n }\n },\n [items],\n )\n\n const debounceHandleShortcuts = useCallback(\n debounce((newInputStack) => {\n handleShortcuts(newInputStack)\n inputStack.current = null\n }, 300),\n [],\n )\n\n useInput(\n (input, key) => {\n // check that no special modifier (shift, control, etc.) is being pressed\n if (enableShortcuts && input.length > 0 && Object.values(key).every((value) => value === false)) {\n const newInputStack = inputStack.current === null ? input : inputStack.current + input\n\n inputStack.current = newInputStack\n debounceHandleShortcuts(newInputStack)\n } else {\n debounceHandleShortcuts.cancel()\n inputStack.current = null\n handleArrows(key)\n }\n },\n {isActive: focus},\n )\n\n const ungroupedItemsTitle = groupTitles.length > 0 ? 'Other' : undefined\n\n if (loading) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>Loading...</Text>\n </Box>\n )\n } else if (errorMessage && errorMessage.length > 0) {\n return (\n <Box marginLeft={3}>\n <Text color=\"red\">{errorMessage}</Text>\n </Box>\n )\n } else if (items.length === 0) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>{emptyMessage}</Text>\n </Box>\n )\n } else {\n return (\n <Box flexDirection=\"column\">\n {groupTitles.map((title, index) => (\n <SelectItemsGroup\n title={title}\n selectedIndex={selectedIndex}\n items={groupedItems[title]!}\n key={title}\n hasMarginTop={index !== 0}\n enableShortcuts={enableShortcuts}\n highlightedTerm={highlightedTerm}\n ></SelectItemsGroup>\n ))}\n\n {ungroupedItems.length > 0 && (\n <SelectItemsGroup\n title={ungroupedItemsTitle}\n selectedIndex={selectedIndex}\n items={ungroupedItems}\n hasMarginTop={groupTitles.length > 0}\n enableShortcuts={enableShortcuts}\n highlightedTerm={highlightedTerm}\n ></SelectItemsGroup>\n )}\n\n <Box marginTop={1} marginLeft={3}>\n <Text dimColor>\n Press {figures.arrowUp}\n {figures.arrowDown} arrows to select, enter to confirm\n </Text>\n </Box>\n </Box>\n )\n }\n}\n"]}