@shopify/cli-kit 3.92.1 → 3.93.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 (160) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/api/graphql/admin/generated/find_development_theme_by_name.d.ts +16 -0
  3. package/dist/cli/api/graphql/admin/generated/find_development_theme_by_name.js +60 -0
  4. package/dist/cli/api/graphql/admin/generated/find_development_theme_by_name.js.map +1 -0
  5. package/dist/private/node/api/graphql.d.ts +10 -0
  6. package/dist/private/node/api/graphql.js +67 -5
  7. package/dist/private/node/api/graphql.js.map +1 -1
  8. package/dist/private/node/conf-store.d.ts +13 -0
  9. package/dist/private/node/conf-store.js +17 -3
  10. package/dist/private/node/conf-store.js.map +1 -1
  11. package/dist/private/node/constants.d.ts +3 -0
  12. package/dist/private/node/constants.js +3 -0
  13. package/dist/private/node/constants.js.map +1 -1
  14. package/dist/private/node/session/exchange.d.ts +22 -8
  15. package/dist/private/node/session/exchange.js +37 -14
  16. package/dist/private/node/session/exchange.js.map +1 -1
  17. package/dist/private/node/session/schema.d.ts +62 -62
  18. package/dist/private/node/session/scopes.js +3 -2
  19. package/dist/private/node/session/scopes.js.map +1 -1
  20. package/dist/private/node/session/store.d.ts +7 -0
  21. package/dist/private/node/session/store.js +17 -0
  22. package/dist/private/node/session/store.js.map +1 -1
  23. package/dist/private/node/session/validate.d.ts +5 -4
  24. package/dist/private/node/session/validate.js +34 -7
  25. package/dist/private/node/session/validate.js.map +1 -1
  26. package/dist/private/node/session.d.ts +1 -1
  27. package/dist/private/node/session.js +77 -32
  28. package/dist/private/node/session.js.map +1 -1
  29. package/dist/private/node/testing/ui.js +6 -4
  30. package/dist/private/node/testing/ui.js.map +1 -1
  31. package/dist/private/node/ui/components/AutocompletePrompt.test.js +5 -5
  32. package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
  33. package/dist/private/node/ui/components/ConcurrentOutput.js +5 -2
  34. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  35. package/dist/private/node/ui/components/ConcurrentOutput.test.js +2 -2
  36. package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
  37. package/dist/private/node/ui/components/SelectInput.test.js +10 -10
  38. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
  39. package/dist/private/node/ui/components/Table/Table.js +2 -2
  40. package/dist/private/node/ui/components/Table/Table.js.map +1 -1
  41. package/dist/private/node/ui/components/Tasks.test.js +6 -6
  42. package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
  43. package/dist/private/node/ui/components/TextAnimation.test.js +1 -1
  44. package/dist/private/node/ui/components/TextAnimation.test.js.map +1 -1
  45. package/dist/private/node/ui/components/TextInput.test.js +4 -4
  46. package/dist/private/node/ui/components/TextInput.test.js.map +1 -1
  47. package/dist/private/node/ui/components/TokenizedText.js +1 -0
  48. package/dist/private/node/ui/components/TokenizedText.js.map +1 -1
  49. package/dist/private/node/ui/hooks/use-select-state.js +1 -3
  50. package/dist/private/node/ui/hooks/use-select-state.js.map +1 -1
  51. package/dist/public/common/version.d.ts +1 -1
  52. package/dist/public/common/version.js +1 -1
  53. package/dist/public/common/version.js.map +1 -1
  54. package/dist/public/node/analytics.js +4 -4
  55. package/dist/public/node/analytics.js.map +1 -1
  56. package/dist/public/node/api/admin.js +1 -3
  57. package/dist/public/node/api/admin.js.map +1 -1
  58. package/dist/public/node/api/rest-api-throttler.d.ts +14 -0
  59. package/dist/public/node/api/rest-api-throttler.js +14 -87
  60. package/dist/public/node/api/rest-api-throttler.js.map +1 -1
  61. package/dist/public/node/archiver.js +6 -7
  62. package/dist/public/node/archiver.js.map +1 -1
  63. package/dist/public/node/cli-launcher.d.ts +1 -1
  64. package/dist/public/node/cli-launcher.js +9 -9
  65. package/dist/public/node/cli-launcher.js.map +1 -1
  66. package/dist/public/node/cli.js +4 -1
  67. package/dist/public/node/cli.js.map +1 -1
  68. package/dist/public/node/context/fqdn.js +1 -0
  69. package/dist/public/node/context/fqdn.js.map +1 -1
  70. package/dist/public/node/context/local.d.ts +7 -0
  71. package/dist/public/node/context/local.js +9 -0
  72. package/dist/public/node/context/local.js.map +1 -1
  73. package/dist/public/node/dot-env.js +1 -1
  74. package/dist/public/node/dot-env.js.map +1 -1
  75. package/dist/public/node/environment.d.ts +4 -9
  76. package/dist/public/node/environment.js +6 -12
  77. package/dist/public/node/environment.js.map +1 -1
  78. package/dist/public/node/environments.js +4 -3
  79. package/dist/public/node/environments.js.map +1 -1
  80. package/dist/public/node/error-handler.js +1 -1
  81. package/dist/public/node/error-handler.js.map +1 -1
  82. package/dist/public/node/error.js +1 -0
  83. package/dist/public/node/error.js.map +1 -1
  84. package/dist/public/node/fs.d.ts +9 -1
  85. package/dist/public/node/fs.js +16 -4
  86. package/dist/public/node/fs.js.map +1 -1
  87. package/dist/public/node/git.d.ts +10 -4
  88. package/dist/public/node/git.js +101 -80
  89. package/dist/public/node/git.js.map +1 -1
  90. package/dist/public/node/global-context.js +1 -3
  91. package/dist/public/node/global-context.js.map +1 -1
  92. package/dist/public/node/hooks/postrun.d.ts +7 -0
  93. package/dist/public/node/hooks/postrun.js +61 -1
  94. package/dist/public/node/hooks/postrun.js.map +1 -1
  95. package/dist/public/node/hooks/prerun.d.ts +3 -2
  96. package/dist/public/node/hooks/prerun.js +9 -22
  97. package/dist/public/node/hooks/prerun.js.map +1 -1
  98. package/dist/public/node/http.js +1 -1
  99. package/dist/public/node/http.js.map +1 -1
  100. package/dist/public/node/import-extractor.d.ts +17 -0
  101. package/dist/public/node/import-extractor.js +84 -23
  102. package/dist/public/node/import-extractor.js.map +1 -1
  103. package/dist/public/node/is-global.d.ts +9 -1
  104. package/dist/public/node/is-global.js +55 -12
  105. package/dist/public/node/is-global.js.map +1 -1
  106. package/dist/public/node/mimes.js +1 -1
  107. package/dist/public/node/mimes.js.map +1 -1
  108. package/dist/public/node/node-package-manager.d.ts +1 -1
  109. package/dist/public/node/node-package-manager.js +4 -1
  110. package/dist/public/node/node-package-manager.js.map +1 -1
  111. package/dist/public/node/os.js +1 -0
  112. package/dist/public/node/os.js.map +1 -1
  113. package/dist/public/node/output.js +3 -2
  114. package/dist/public/node/output.js.map +1 -1
  115. package/dist/public/node/path.d.ts +11 -0
  116. package/dist/public/node/path.js +30 -1
  117. package/dist/public/node/path.js.map +1 -1
  118. package/dist/public/node/result.js +1 -0
  119. package/dist/public/node/result.js.map +1 -1
  120. package/dist/public/node/serial-batch-processor.js +1 -3
  121. package/dist/public/node/serial-batch-processor.js.map +1 -1
  122. package/dist/public/node/session-prompt.js +10 -2
  123. package/dist/public/node/session-prompt.js.map +1 -1
  124. package/dist/public/node/session.js +6 -6
  125. package/dist/public/node/session.js.map +1 -1
  126. package/dist/public/node/themes/api.d.ts +1 -0
  127. package/dist/public/node/themes/api.js +26 -0
  128. package/dist/public/node/themes/api.js.map +1 -1
  129. package/dist/public/node/themes/conf.js +3 -5
  130. package/dist/public/node/themes/conf.js.map +1 -1
  131. package/dist/public/node/themes/factories.js +1 -0
  132. package/dist/public/node/themes/factories.js.map +1 -1
  133. package/dist/public/node/themes/theme-manager.d.ts +2 -2
  134. package/dist/public/node/themes/theme-manager.js +13 -8
  135. package/dist/public/node/themes/theme-manager.js.map +1 -1
  136. package/dist/public/node/{toml.d.ts → toml/codec.d.ts} +1 -1
  137. package/dist/public/node/{toml.js → toml/codec.js} +1 -1
  138. package/dist/public/node/toml/codec.js.map +1 -0
  139. package/dist/public/node/toml/index.d.ts +1 -0
  140. package/dist/public/node/toml/index.js +2 -0
  141. package/dist/public/node/toml/index.js.map +1 -0
  142. package/dist/public/node/toml/toml-file.d.ts +88 -0
  143. package/dist/public/node/toml/toml-file.js +159 -0
  144. package/dist/public/node/toml/toml-file.js.map +1 -0
  145. package/dist/public/node/tree-kill.js +1 -1
  146. package/dist/public/node/tree-kill.js.map +1 -1
  147. package/dist/public/node/ui.js +1 -0
  148. package/dist/public/node/ui.js.map +1 -1
  149. package/dist/public/node/upgrade.d.ts +28 -1
  150. package/dist/public/node/upgrade.js +184 -16
  151. package/dist/public/node/upgrade.js.map +1 -1
  152. package/dist/public/node/version.d.ts +9 -0
  153. package/dist/public/node/version.js +16 -1
  154. package/dist/public/node/version.js.map +1 -1
  155. package/dist/tsconfig.tsbuildinfo +1 -1
  156. package/package.json +12 -12
  157. package/dist/public/node/custom-oclif-loader.d.ts +0 -6
  158. package/dist/public/node/custom-oclif-loader.js +0 -79
  159. package/dist/public/node/custom-oclif-loader.js.map +0 -1
  160. package/dist/public/node/toml.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../../src/private/node/testing/ui.ts"],"names":[],"mappings":"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","sourcesContent":["import {Stdout} from '../ui.js'\nimport {ReactElement} from 'react'\nimport {render as inkRender} from 'ink'\n\nimport {EventEmitter} from 'events'\n\nclass Stderr extends EventEmitter {\n readonly frames: string[] = []\n private _lastFrame?: string\n\n write = (frame: string) => {\n this.frames.push(frame)\n this._lastFrame = frame\n }\n\n lastFrame = () => this._lastFrame\n}\n\nexport class Stdin extends EventEmitter {\n isTTY: boolean\n data: string | null = null\n\n constructor(options: {isTTY?: boolean} = {}) {\n super()\n this.isTTY = options.isTTY ?? true\n }\n\n write = (data: string) => {\n this.data = data\n this.emit('readable')\n }\n\n setEncoding() {}\n setRawMode() {}\n ref() {}\n unref() {}\n read: () => string | null = () => {\n const data = this.data\n\n this.data = null\n\n return data\n }\n}\n\ninterface Instance {\n rerender: (tree: ReactElement) => void\n unmount: () => void\n cleanup: () => void\n stdout: Stdout\n stderr: Stderr\n stdin: Stdin\n frames: string[]\n lastFrame: () => string | undefined\n waitUntilExit: () => TrackedPromise<void>\n}\n\ninterface RenderOptions {\n stdout?: EventEmitter\n stderr?: EventEmitter\n stdin?: EventEmitter\n}\n\nexport const render = (tree: ReactElement, options: RenderOptions = {}): Instance => {\n const stdout = new Stdout({columns: 100})\n const stderr = new Stderr()\n const stdin = new Stdin()\n\n const instance = inkRender(tree, {\n stdout: options.stdout ?? (stdout as any),\n\n stderr: options.stderr ?? (stderr as any),\n\n stdin: options.stdin ?? (stdin as any),\n debug: true,\n exitOnCtrlC: false,\n patchConsole: false,\n })\n\n return {\n rerender: instance.rerender,\n unmount: instance.unmount,\n cleanup: instance.cleanup,\n waitUntilExit: () => trackPromise(instance.waitUntilExit()),\n stdout,\n stderr,\n stdin,\n frames: stdout.frames,\n lastFrame: stdout.lastFrame,\n }\n}\n\n/**\n * Wait for the component to be ready to accept input.\n */\nexport function waitForInputsToBeReady() {\n return new Promise((resolve) => setTimeout(resolve, 100))\n}\n\n/**\n * Wait for the last frame to change to anything.\n */\nexport async function waitForChange(func: () => void, getChangingValue: () => string | number | undefined) {\n const initialValue = getChangingValue()\n\n func()\n\n while (getChangingValue() === initialValue) {\n // Yield via setImmediate so React 19's scheduler (which also uses\n // setImmediate in Node.js) can flush batched renders, then yield\n // via setTimeout(0) to let any follow-up microtasks settle.\n // eslint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setImmediate(() => setTimeout(resolve, 0)))\n }\n}\n\nexport async function waitFor(func: () => void, condition: () => boolean) {\n func()\n\n while (!condition()) {\n // eslint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setImmediate(() => setTimeout(resolve, 0)))\n }\n}\n\n/**\n * Wait for the last frame to contain specific text.\n */\nexport function waitForContent(\n renderInstance: ReturnType<typeof render>,\n content: string,\n func: () => void = () => {},\n) {\n return waitFor(\n () => func(),\n\n () => renderInstance.lastFrame()!.includes(content),\n )\n}\n\n/**\n * Send input and wait for the last frame to change.\n *\n * Useful when you want to send some input and wait for anything to change in the interface.\n * If you need to wait for a specific change instead, you can use sendInputAndWaitForContent.\n */\nexport async function sendInputAndWaitForChange(renderInstance: ReturnType<typeof render>, ...inputs: string[]) {\n await waitForChange(() => inputs.forEach((input) => renderInstance.stdin.write(input)), renderInstance.lastFrame)\n // wait for another tick so we give time to react to update caches\n await new Promise((resolve) => setTimeout(resolve, 0))\n}\n\n/** Send input and wait a number of milliseconds.\n *\n * Useful if you know some what will happen after input will take a certain amount of time\n * and it will not cause any visible change so you can't use sendInputAndWaitForChange.\n * This function can also be used if you want to test that nothing changes after some input has been sent.\n */\nexport async function sendInputAndWait(\n renderInstance: ReturnType<typeof render>,\n waitTime: number,\n ...inputs: string[]\n) {\n inputs.forEach((input) => renderInstance.stdin.write(input))\n await new Promise((resolve) => setTimeout(resolve, waitTime))\n}\n\n/**\n * Send input and wait for the last frame to contain specific text.\n *\n * Useful when you want to send some input and wait for a specific change to happen.\n * If you need to wait for any change instead, you can use sendInputAndWaitForChange.\n */\nexport async function sendInputAndWaitForContent(\n renderInstance: ReturnType<typeof render>,\n content: string,\n ...inputs: string[]\n) {\n await waitForContent(renderInstance, content, () => inputs.forEach((input) => renderInstance.stdin.write(input)))\n // Yield so React 19's scheduler can flush effects (e.g. re-register useInput\n // handlers with up-to-date closures) before subsequent input is sent.\n await new Promise((resolve) => setImmediate(() => setTimeout(resolve, 0)))\n}\n\n/** Function that is useful when you want to check the last frame of a component that unmounted.\n *\n * With Ink 6 / React 19, the output is no longer cleared on unmount,\n * so lastFrame() consistently returns the last rendered content.\n */\nexport function getLastFrameAfterUnmount(renderInstance: ReturnType<typeof render>) {\n return renderInstance.lastFrame()\n}\n\ntype TrackedPromise<T> = Promise<T> & {\n isFulfilled: () => boolean\n isPending: () => boolean\n isRejected: () => boolean\n}\n\nfunction trackPromise<T>(promise: Promise<T>): TrackedPromise<T> {\n let isPending = true\n let isRejected = false\n let isFulfilled = false\n\n const trackedPromise = promise.then(\n function (result) {\n isFulfilled = true\n isPending = false\n return result\n },\n function (error) {\n isRejected = true\n isPending = false\n throw error\n },\n ) as TrackedPromise<T>\n\n trackedPromise.isFulfilled = function () {\n return isFulfilled\n }\n trackedPromise.isPending = function () {\n return isPending\n }\n trackedPromise.isRejected = function () {\n return isRejected\n }\n\n return trackedPromise\n}\n"]}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../../src/private/node/testing/ui.ts"],"names":[],"mappings":"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","sourcesContent":["import {Stdout} from '../ui.js'\nimport {ReactElement} from 'react'\nimport {render as inkRender} from 'ink'\n\nimport {EventEmitter} from 'events'\n\nclass Stderr extends EventEmitter {\n readonly frames: string[] = []\n private _lastFrame?: string\n\n write = (frame: string) => {\n this.frames.push(frame)\n this._lastFrame = frame\n }\n\n lastFrame = () => this._lastFrame\n}\n\nexport class Stdin extends EventEmitter {\n isTTY: boolean\n data: string | null = null\n\n constructor(options: {isTTY?: boolean} = {}) {\n super()\n this.isTTY = options.isTTY ?? true\n }\n\n write = (data: string) => {\n this.data = data\n this.emit('readable')\n }\n\n setEncoding() {}\n setRawMode() {}\n ref() {}\n unref() {}\n read: () => string | null = () => {\n const data = this.data\n\n this.data = null\n\n return data\n }\n}\n\ninterface Instance {\n rerender: (tree: ReactElement) => void\n unmount: () => void\n cleanup: () => void\n stdout: Stdout\n stderr: Stderr\n stdin: Stdin\n frames: string[]\n lastFrame: () => string | undefined\n waitUntilExit: () => TrackedPromise<void>\n}\n\ninterface RenderOptions {\n stdout?: EventEmitter\n stderr?: EventEmitter\n stdin?: EventEmitter\n}\n\nexport const render = (tree: ReactElement, options: RenderOptions = {}): Instance => {\n const stdout = new Stdout({columns: 100})\n const stderr = new Stderr()\n const stdin = new Stdin()\n\n const instance = inkRender(tree, {\n stdout: options.stdout ?? (stdout as any),\n\n stderr: options.stderr ?? (stderr as any),\n\n stdin: options.stdin ?? (stdin as any),\n debug: true,\n exitOnCtrlC: false,\n patchConsole: false,\n })\n\n return {\n rerender: instance.rerender,\n unmount: instance.unmount,\n cleanup: instance.cleanup,\n waitUntilExit: () => trackPromise(instance.waitUntilExit().then(() => {})),\n stdout,\n stderr,\n stdin,\n frames: stdout.frames,\n lastFrame: stdout.lastFrame,\n }\n}\n\n/**\n * Wait for the component to be ready to accept input.\n */\nexport function waitForInputsToBeReady() {\n return new Promise((resolve) => setTimeout(resolve, 10))\n}\n\n/**\n * Wait for the last frame to change to anything.\n */\nexport async function waitForChange(func: () => void, getChangingValue: () => string | number | undefined) {\n const initialValue = getChangingValue()\n\n func()\n\n while (getChangingValue() === initialValue) {\n // Yield via setImmediate so React 19's scheduler (which also uses\n // setImmediate in Node.js) can flush batched renders, then yield\n // via setTimeout(0) to let any follow-up microtasks settle.\n // eslint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setImmediate(() => setTimeout(resolve, 0)))\n }\n}\n\nexport async function waitFor(func: () => void, condition: () => boolean) {\n func()\n\n while (!condition()) {\n // eslint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setImmediate(() => setTimeout(resolve, 0)))\n }\n}\n\n/**\n * Wait for the last frame to contain specific text.\n */\nexport function waitForContent(\n renderInstance: ReturnType<typeof render>,\n content: string,\n func: () => void = () => {},\n) {\n return waitFor(\n () => func(),\n\n () => renderInstance.lastFrame()!.includes(content),\n )\n}\n\n/**\n * Send input and wait for the last frame to change.\n *\n * Useful when you want to send some input and wait for anything to change in the interface.\n * If you need to wait for a specific change instead, you can use sendInputAndWaitForContent.\n */\nexport async function sendInputAndWaitForChange(renderInstance: ReturnType<typeof render>, ...inputs: string[]) {\n await waitForChange(() => inputs.forEach((input) => renderInstance.stdin.write(input)), renderInstance.lastFrame)\n // Yield via setImmediate → setTimeout(0) so React 19's scheduler can flush\n // effects (e.g. re-register useInput handlers with up-to-date closures)\n // before subsequent input is sent.\n await new Promise((resolve) => setImmediate(() => setTimeout(resolve, 0)))\n}\n\n/** Send input and wait a number of milliseconds.\n *\n * Useful if you know some what will happen after input will take a certain amount of time\n * and it will not cause any visible change so you can't use sendInputAndWaitForChange.\n * This function can also be used if you want to test that nothing changes after some input has been sent.\n */\nexport async function sendInputAndWait(\n renderInstance: ReturnType<typeof render>,\n waitTime: number,\n ...inputs: string[]\n) {\n inputs.forEach((input) => renderInstance.stdin.write(input))\n await new Promise((resolve) => setTimeout(resolve, waitTime))\n}\n\n/**\n * Send input and wait for the last frame to contain specific text.\n *\n * Useful when you want to send some input and wait for a specific change to happen.\n * If you need to wait for any change instead, you can use sendInputAndWaitForChange.\n */\nexport async function sendInputAndWaitForContent(\n renderInstance: ReturnType<typeof render>,\n content: string,\n ...inputs: string[]\n) {\n await waitForContent(renderInstance, content, () => inputs.forEach((input) => renderInstance.stdin.write(input)))\n // Yield so React 19's scheduler can flush effects (e.g. re-register useInput\n // handlers with up-to-date closures) before subsequent input is sent.\n await new Promise((resolve) => setImmediate(() => setTimeout(resolve, 0)))\n}\n\n/** Function that is useful when you want to check the last frame of a component that unmounted.\n *\n * With Ink 6 / React 19, the output is no longer cleared on unmount,\n * so lastFrame() consistently returns the last rendered content.\n */\nexport function getLastFrameAfterUnmount(renderInstance: ReturnType<typeof render>) {\n return renderInstance.lastFrame()\n}\n\ntype TrackedPromise<T> = Promise<T> & {\n isFulfilled: () => boolean\n isPending: () => boolean\n isRejected: () => boolean\n}\n\nfunction trackPromise<T>(promise: Promise<T>): TrackedPromise<T> {\n let isPending = true\n let isRejected = false\n let isFulfilled = false\n\n const trackedPromise = promise.then(\n function (result) {\n isFulfilled = true\n isPending = false\n return result\n },\n function (error) {\n isRejected = true\n isPending = false\n throw error\n },\n ) as TrackedPromise<T>\n\n trackedPromise.isFulfilled = function () {\n return isFulfilled\n }\n trackedPromise.isPending = function () {\n return isPending\n }\n trackedPromise.isRejected = function () {\n return isRejected\n }\n\n return trackedPromise\n}\n"]}
@@ -211,7 +211,7 @@ describe('AutocompletePrompt', async () => {
211
211
  await waitForInputsToBeReady();
212
212
  await sendInputAndWaitForContent(renderInstance, 'No results found', 'a');
213
213
  // prompt doesn't change when enter is pressed
214
- await sendInputAndWait(renderInstance, 100, ENTER);
214
+ await sendInputAndWait(renderInstance, 10, ENTER);
215
215
  expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
216
216
  "? Associate your project with the org Castile Ventures? a█
217
217
 
@@ -259,8 +259,8 @@ describe('AutocompletePrompt', async () => {
259
259
  await waitForInputsToBeReady();
260
260
  await sendInputAndWaitForContent(renderInstance, 'Loading...', 'a');
261
261
  // prompt doesn't change when enter is pressed
262
- await new Promise((resolve) => setTimeout(resolve, 100));
263
- await sendInputAndWait(renderInstance, 100, ENTER);
262
+ await new Promise((resolve) => setTimeout(resolve, 10));
263
+ await sendInputAndWait(renderInstance, 10, ENTER);
264
264
  expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
265
265
  "? Associate your project with the org Castile Ventures? a█
266
266
 
@@ -463,9 +463,9 @@ describe('AutocompletePrompt', async () => {
463
463
  await waitForInputsToBeReady();
464
464
  await sendInputAndWaitForContent(renderInstance, 'slash', '\\');
465
465
  expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
466
- "? Associate your project with the org Castile Ventures? \\\\█
466
+ "? Associate your project with the org Castile Ventures? \\█
467
467
 
468
- > with\\\\slash
468
+ > with\\slash
469
469
 
470
470
 
471
471
 
@@ -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 waitForInputsToBeReady,\n render,\n} from '../../testing/ui.js'\nimport {Stdout} from '../../ui.js'\nimport {AbortController} from '../../../../public/node/abort.js'\nimport {beforeEach, describe, expect, test, vi} from 'vitest'\n\nimport React from 'react'\nimport {useStdout} from 'ink'\n\nvi.mock('ink', async () => {\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 Stdout({\n columns: 80,\n rows: 80,\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', {userInput: 'Castile Ventures'}, {char: '?'}]}\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 \u001b[36mCastile Ventures\u001b[39m?\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'},\n {label: 'second', value: 'second', group: 'Automations'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\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 ]\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? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\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 ┃ \\u001b[1mAdd\\u001b[22m\n ┃ • new-ext\n ┃\n ┃ \\u001b[1mRemove\\u001b[22m\n ┃ • 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('supports an info message', 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 infoMessage = {\n title: {\n color: 'red',\n text: 'Info message title',\n },\n body: 'Info message body',\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoMessage={infoMessage}\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 ┃ \u001b[31mInfo message title\u001b[39m\n ┃\n ┃ Info message body\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\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(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36ma\u001b[46m█\u001b[49m\u001b[39m\n\n \u001b[2mNo results found.\u001b[22m\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \u001b[2mTry again with a different keyword.\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\n const search = () => {\n return new Promise<SearchResults<string>>((resolve) => {\n setTimeout(() => {\n resolve({data: [{label: 'a', value: 'b'}]})\n }, 2000)\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...', '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[46m█\u001b[49m\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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\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[46m█\u001b[49m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrteenth \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfteenth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxteenth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghteenth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mneteenth \u001b[46m \u001b[49m\n twent\u001b[1mi\u001b[22meth \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n twenty-th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n twenty-s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n twenty-e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n twenty-n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrtieth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-first \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-second \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-third \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fourth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fifth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-sixth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForContent(renderInstance, 'ype to search', 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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\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[46m█\u001b[49m\u001b[39m\n\n f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mfth\u001b[39m \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrteenth \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfteenth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxteenth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghteenth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mneteenth \u001b[46m \u001b[49m\n twent\u001b[1mi\u001b[22meth \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n twenty-th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n twenty-s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n twenty-e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n twenty-n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrtieth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-first \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-second \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-third \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fourth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fifth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-sixth \u001b[100m \u001b[49m\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 searching with malformed regex', async () => {\n const onEnter = vi.fn()\n const db = [...DATABASE, {label: 'with\\\\slash', value: 'with\\\\slash'}]\n\n const search = async (term: string) => {\n return {\n data: db.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={db}\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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'slash', '\\\\')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\\\\\\\\\u001b[46m█\u001b[49m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mwith\\\\\\\\slash\u001b[39m\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\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[46m█\u001b[49m\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[46m█\u001b[49m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrteenth \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfteenth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxteenth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghteenth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mneteenth \u001b[46m \u001b[49m\n twent\u001b[1mi\u001b[22meth \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n twenty-th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n twenty-s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n twenty-e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n twenty-n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrtieth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-first \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-second \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-third \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fourth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fifth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-sixth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForContent(renderInstance, 'ype to search', 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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \u001b[1m1-50 of many\u001b[22m Find what you're looking for by typing its name.\n \"\n `)\n })\n\n test('adapts to the height of the container', async () => {\n vi.mocked(useStdout).mockReturnValue({\n stdout: new Stdout({rows: 10}) as any,\n write: () => {},\n })\n\n const items = [\n {label: 'first', value: 'first', group: 'Automations'},\n {label: 'second', value: 'second', group: 'Automations'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\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 ]\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={() => {}}\n hasMorePages\n search={() =>\n Promise.resolve({\n data: items,\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[1mAutomations\u001b[22m \\u001b[46m \\u001b[49m\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m \\u001b[100m \\u001b[49m\n second \\u001b[100m \\u001b[49m\n \\u001b[100m \\u001b[49m\n \u001b[1mMerchant Admin\u001b[22m \\u001b[100m \\u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \u001b[1m1-10 of many\u001b[22m Find what you're looking for by typing its name.\n \"\n `)\n })\n\n test('abortController can be used to exit the prompt from outside', async () => {\n const items = [\n {label: 'a', value: 'a'},\n {label: 'b', value: 'b'},\n ]\n\n const abortController = new AbortController()\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 abortSignal={abortController.signal}\n />,\n )\n const promise = renderInstance.waitUntilExit()\n\n abortController.abort()\n\n // wait for the onAbort promise to resolve\n await new Promise((resolve) => setTimeout(resolve, 0))\n\n await expect(promise).resolves.toEqual(undefined)\n })\n})\n"]}
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 waitForInputsToBeReady,\n render,\n} from '../../testing/ui.js'\nimport {Stdout} from '../../ui.js'\nimport {AbortController} from '../../../../public/node/abort.js'\nimport {beforeEach, describe, expect, test, vi} from 'vitest'\n\nimport React from 'react'\nimport {useStdout} from 'ink'\n\nvi.mock('ink', async () => {\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 Stdout({\n columns: 80,\n rows: 80,\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', {userInput: 'Castile Ventures'}, {char: '?'}]}\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 \u001b[36mCastile Ventures\u001b[39m?\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'},\n {label: 'second', value: 'second', group: 'Automations'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\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 ]\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? \u001b[36m\u001b[7mT\u001b[27m\u001b[2mype to search...\u001b[22m\u001b[39m\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 ┃ \\u001b[1mAdd\\u001b[22m\n ┃ • new-ext\n ┃\n ┃ \\u001b[1mRemove\\u001b[22m\n ┃ • 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('supports an info message', 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 infoMessage = {\n title: {\n color: 'red',\n text: 'Info message title',\n },\n body: 'Info message body',\n }\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoMessage={infoMessage}\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 ┃ \u001b[31mInfo message title\u001b[39m\n ┃\n ┃ Info message body\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\n await sendInputAndWaitForContent(renderInstance, 'No results found', 'a')\n // prompt doesn't change when enter is pressed\n await sendInputAndWait(renderInstance, 10, ENTER)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36ma\u001b[46m█\u001b[49m\u001b[39m\n\n \u001b[2mNo results found.\u001b[22m\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \u001b[2mTry again with a different keyword.\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\n const search = () => {\n return new Promise<SearchResults<string>>((resolve) => {\n setTimeout(() => {\n resolve({data: [{label: 'a', value: 'b'}]})\n }, 2000)\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...', 'a')\n // prompt doesn't change when enter is pressed\n await new Promise((resolve) => setTimeout(resolve, 10))\n await sendInputAndWait(renderInstance, 10, ENTER)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36ma\u001b[46m█\u001b[49m\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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\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[46m█\u001b[49m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrteenth \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfteenth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxteenth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghteenth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mneteenth \u001b[46m \u001b[49m\n twent\u001b[1mi\u001b[22meth \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n twenty-th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n twenty-s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n twenty-e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n twenty-n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrtieth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-first \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-second \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-third \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fourth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fifth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-sixth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForContent(renderInstance, 'ype to search', 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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\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[46m█\u001b[49m\u001b[39m\n\n f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mfth\u001b[39m \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrteenth \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfteenth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxteenth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghteenth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mneteenth \u001b[46m \u001b[49m\n twent\u001b[1mi\u001b[22meth \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n twenty-th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n twenty-s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n twenty-e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n twenty-n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrtieth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-first \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-second \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-third \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fourth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fifth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-sixth \u001b[100m \u001b[49m\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 searching with malformed regex', async () => {\n const onEnter = vi.fn()\n const db = [...DATABASE, {label: 'with\\\\slash', value: 'with\\\\slash'}]\n\n const search = async (term: string) => {\n return {\n data: db.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={db}\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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForContent(renderInstance, 'slash', '\\\\')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures? \u001b[36m\\\\\u001b[46m█\u001b[49m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mwith\\\\slash\u001b[39m\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\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[46m█\u001b[49m\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[46m█\u001b[49m\u001b[39m\n\n \u001b[36m>\u001b[39m \u001b[36mf\u001b[1mi\u001b[22mrst\u001b[39m \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrteenth \u001b[46m \u001b[49m\n f\u001b[1mi\u001b[22mfteenth \u001b[46m \u001b[49m\n s\u001b[1mi\u001b[22mxteenth \u001b[46m \u001b[49m\n e\u001b[1mi\u001b[22mghteenth \u001b[46m \u001b[49m\n n\u001b[1mi\u001b[22mneteenth \u001b[46m \u001b[49m\n twent\u001b[1mi\u001b[22meth \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mrst \u001b[46m \u001b[49m\n twenty-th\u001b[1mi\u001b[22mrd \u001b[46m \u001b[49m\n twenty-f\u001b[1mi\u001b[22mfth \u001b[46m \u001b[49m\n twenty-s\u001b[1mi\u001b[22mxth \u001b[46m \u001b[49m\n twenty-e\u001b[1mi\u001b[22mghth \u001b[46m \u001b[49m\n twenty-n\u001b[1mi\u001b[22mnth \u001b[46m \u001b[49m\n th\u001b[1mi\u001b[22mrtieth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-first \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-second \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-third \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fourth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-fifth \u001b[100m \u001b[49m\n th\u001b[1mi\u001b[22mrty-sixth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \"\n `)\n\n await sendInputAndWaitForContent(renderInstance, 'ype to search', 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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\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 \u001b[46m \u001b[49m\n second \u001b[46m \u001b[49m\n third \u001b[46m \u001b[49m\n fourth \u001b[46m \u001b[49m\n fifth \u001b[46m \u001b[49m\n sixth \u001b[46m \u001b[49m\n seventh \u001b[46m \u001b[49m\n eighth \u001b[46m \u001b[49m\n ninth \u001b[46m \u001b[49m\n tenth \u001b[46m \u001b[49m\n eleventh \u001b[46m \u001b[49m\n twelfth \u001b[46m \u001b[49m\n thirteenth \u001b[46m \u001b[49m\n fourteenth \u001b[100m \u001b[49m\n fifteenth \u001b[100m \u001b[49m\n sixteenth \u001b[100m \u001b[49m\n seventeenth \u001b[100m \u001b[49m\n eighteenth \u001b[100m \u001b[49m\n nineteenth \u001b[100m \u001b[49m\n twentieth \u001b[100m \u001b[49m\n twenty-first \u001b[100m \u001b[49m\n twenty-second \u001b[100m \u001b[49m\n twenty-third \u001b[100m \u001b[49m\n twenty-fourth \u001b[100m \u001b[49m\n twenty-fifth \u001b[100m \u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \u001b[1m1-50 of many\u001b[22m Find what you're looking for by typing its name.\n \"\n `)\n })\n\n test('adapts to the height of the container', async () => {\n vi.mocked(useStdout).mockReturnValue({\n stdout: new Stdout({rows: 10}) as any,\n write: () => {},\n })\n\n const items = [\n {label: 'first', value: 'first', group: 'Automations'},\n {label: 'second', value: 'second', group: 'Automations'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\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 ]\n\n const renderInstance = render(\n <AutocompletePrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={() => {}}\n hasMorePages\n search={() =>\n Promise.resolve({\n data: items,\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[1mAutomations\u001b[22m \\u001b[46m \\u001b[49m\n \u001b[36m>\u001b[39m \u001b[36mfirst\u001b[39m \\u001b[100m \\u001b[49m\n second \\u001b[100m \\u001b[49m\n \\u001b[100m \\u001b[49m\n \u001b[1mMerchant Admin\u001b[22m \\u001b[100m \\u001b[49m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm.\u001b[22m\n \u001b[1m1-10 of many\u001b[22m Find what you're looking for by typing its name.\n \"\n `)\n })\n\n test('abortController can be used to exit the prompt from outside', async () => {\n const items = [\n {label: 'a', value: 'a'},\n {label: 'b', value: 'b'},\n ]\n\n const abortController = new AbortController()\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 abortSignal={abortController.signal}\n />,\n )\n const promise = renderInstance.waitUntilExit()\n\n abortController.abort()\n\n // wait for the onAbort promise to resolve\n await new Promise((resolve) => setTimeout(resolve, 0))\n\n await expect(promise).resolves.toEqual(undefined)\n })\n})\n"]}
@@ -122,13 +122,16 @@ const ConcurrentOutput = ({ processes, prefixColumnSize, abortSignal, showTimest
122
122
  if (!keepRunningAfterProcessesResolve) {
123
123
  // Defer unmount so React 19 can flush batched setProcessOutput
124
124
  // state updates before the component tree is torn down.
125
- setImmediate(() => unmountInk());
125
+ // Use setImmediate → setTimeout(0) to span two event-loop phases,
126
+ // giving React's scheduler (which uses setImmediate in Node.js)
127
+ // a full cycle to flush before we tear down the component tree.
128
+ setImmediate(() => setTimeout(() => unmountInk(), 0));
126
129
  }
127
130
  // eslint-disable-next-line no-catch-all/no-catch-all
128
131
  }
129
132
  catch (error) {
130
133
  if (!keepRunningAfterProcessesResolve) {
131
- setImmediate(() => unmountInk(error));
134
+ setImmediate(() => setTimeout(() => unmountInk(error), 0));
132
135
  }
133
136
  }
134
137
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ConcurrentOutput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/ConcurrentOutput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {OutputProcess} from '../../../../public/node/output.js'\nimport {AbortSignal} from '../../../../public/node/abort.js'\nimport React, {FunctionComponent, useCallback, useEffect, useMemo, useState} from 'react'\nimport {Box, Static, Text, TextProps, useApp} from 'ink'\nimport figures from 'figures'\nimport stripAnsi from 'strip-ansi'\n\nimport {Writable} from 'stream'\nimport {AsyncLocalStorage} from 'node:async_hooks'\n\nexport interface ConcurrentOutputProps {\n processes: OutputProcess[]\n prefixColumnSize?: number\n abortSignal: AbortSignal\n showTimestamps?: boolean\n keepRunningAfterProcessesResolve?: boolean\n useAlternativeColorPalette?: boolean\n}\n\ninterface Chunk {\n color: TextProps['color']\n prefix: string\n lines: string[]\n}\n\nfunction addLeadingZero(number: number) {\n if (number < 10) {\n return `0${number}`\n } else {\n return number.toString()\n }\n}\n\nfunction currentTime() {\n const currentDateTime = new Date()\n const hours = addLeadingZero(currentDateTime.getHours())\n const minutes = addLeadingZero(currentDateTime.getMinutes())\n const seconds = addLeadingZero(currentDateTime.getSeconds())\n return `${hours}:${minutes}:${seconds}`\n}\n\ninterface ConcurrentOutputContext {\n outputPrefix?: string\n stripAnsi?: boolean\n}\n\nconst outputContextStore = new AsyncLocalStorage<ConcurrentOutputContext>()\n\nfunction useConcurrentOutputContext<T>(context: ConcurrentOutputContext, callback: () => T): T {\n return outputContextStore.run(context, callback)\n}\n\n/**\n * Renders output from concurrent processes to the terminal.\n * Output will be divided in a three column layout\n * with the left column containing the timestamp,\n * the right column containing the output,\n * and the middle column containing the process prefix.\n * Every process will be rendered with a different color, up to 4 colors.\n *\n * For example running `shopify app dev`:\n *\n * ```shell\n * 2022-10-10 13:11:03 | backend | npm\n * 2022-10-10 13:11:03 | backend | WARN ignoring workspace config at ...\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend | > shopify-app-template-node@0.1.0 dev\n * 2022-10-10 13:11:03 | backend | > cross-env NODE_ENV=development nodemon backend/index.js --watch ./backend\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | frontend | > starter-react-frontend-app@0.1.0 dev\n * 2022-10-10 13:11:03 | frontend | > cross-env NODE_ENV=development node vite-server.js\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend | [nodemon] to restart at any time, enter `rs`\n * 2022-10-10 13:11:03 | backend | [nodemon] watching path(s): backend/\n * 2022-10-10 13:11:03 | backend | [nodemon] watching extensions: js,mjs,json\n * 2022-10-10 13:11:03 | backend | [nodemon] starting `node backend/index.js`\n * 2022-10-10 13:11:03 | backend |\n *\n * ```\n */\nconst ConcurrentOutput: FunctionComponent<ConcurrentOutputProps> = ({\n processes,\n prefixColumnSize,\n abortSignal,\n showTimestamps = true,\n keepRunningAfterProcessesResolve = false,\n useAlternativeColorPalette = false,\n}) => {\n const [processOutput, setProcessOutput] = useState<Chunk[]>([])\n const {exit: unmountInk} = useApp()\n const concurrentColors: TextProps['color'][] = useMemo(\n () =>\n useAlternativeColorPalette\n ? ['#b994c3', '#e69e19', '#d17a73', 'cyan', 'magenta', 'blue']\n : ['yellow', 'cyan', 'magenta', 'green', 'blue'],\n [useAlternativeColorPalette],\n )\n\n const calculatedPrefixColumnSize = useMemo(() => {\n const maxColumnSize = 25\n\n // If the prefixColumnSize is not provided, we calculate it based on the longest process prefix\n const columnSize =\n prefixColumnSize ??\n processes.reduce((maxPrefixLength, process) => Math.max(maxPrefixLength, process.prefix.length), 0)\n\n // Apply overall limit to the prefix column size\n return Math.min(columnSize, maxColumnSize)\n }, [processes, prefixColumnSize])\n\n const addPrefix = (prefix: string, prefixes: string[]) => {\n const index = prefixes.indexOf(prefix)\n if (index !== -1) {\n return index\n }\n prefixes.push(prefix)\n return prefixes.length - 1\n }\n\n const lineColor = useCallback(\n (index: number) => {\n const colorIndex = index % concurrentColors.length\n return concurrentColors[colorIndex]\n },\n [concurrentColors],\n )\n\n const writableStream = useCallback(\n (process: OutputProcess, prefixes: string[]) => {\n return new Writable({\n write(chunk, _encoding, next) {\n const context = outputContextStore.getStore()\n const prefix = context?.outputPrefix ?? process.prefix\n const shouldStripAnsi = context?.stripAnsi ?? true\n const log = chunk.toString('utf8').replace(/(\\n)$/, '')\n\n const index = addPrefix(prefix, prefixes)\n\n const lines = shouldStripAnsi ? stripAnsi(log).split(/\\n/) : log.split(/\\n/)\n setProcessOutput((previousProcessOutput) => [\n ...previousProcessOutput,\n {\n color: lineColor(index),\n prefix,\n lines,\n },\n ])\n next()\n },\n })\n },\n [lineColor],\n )\n\n const formatPrefix = (prefix: string) => {\n // Truncate prefix if needed\n if (prefix.length > calculatedPrefixColumnSize) {\n return prefix.substring(0, calculatedPrefixColumnSize)\n }\n\n return `${' '.repeat(calculatedPrefixColumnSize - prefix.length)}${prefix}`\n }\n\n useEffect(() => {\n const runProcesses = async () => {\n const prefixes: string[] = []\n\n try {\n await Promise.all(\n processes.map(async (process) => {\n const stdout = writableStream(process, prefixes)\n const stderr = writableStream(process, prefixes)\n await process.action(stdout, stderr, abortSignal)\n }),\n )\n if (!keepRunningAfterProcessesResolve) {\n // Defer unmount so React 19 can flush batched setProcessOutput\n // state updates before the component tree is torn down.\n setImmediate(() => unmountInk())\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error: unknown) {\n if (!keepRunningAfterProcessesResolve) {\n setImmediate(() => unmountInk(error as Error | undefined))\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n runProcesses()\n }, [abortSignal, processes, writableStream, unmountInk, keepRunningAfterProcessesResolve])\n\n const {lineVertical} = figures\n\n return (\n <Static items={processOutput}>\n {(chunk, index) => {\n return (\n <Box flexDirection=\"column\" key={index}>\n {chunk.lines.map((line, index) => (\n <Box key={index} flexDirection=\"row\">\n <Text>\n {showTimestamps ? (\n <Text>\n {currentTime()} {lineVertical}{' '}\n </Text>\n ) : null}\n <Text color={chunk.color}>{formatPrefix(chunk.prefix)}</Text>\n <Text>\n {' '}\n {lineVertical} {line}\n </Text>\n </Text>\n </Box>\n ))}\n </Box>\n )\n }}\n </Static>\n )\n}\nexport {ConcurrentOutput, ConcurrentOutputContext, useConcurrentOutputContext}\n"]}
1
+ {"version":3,"file":"ConcurrentOutput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/ConcurrentOutput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {OutputProcess} from '../../../../public/node/output.js'\nimport {AbortSignal} from '../../../../public/node/abort.js'\nimport React, {FunctionComponent, useCallback, useEffect, useMemo, useState} from 'react'\nimport {Box, Static, Text, TextProps, useApp} from 'ink'\nimport figures from 'figures'\nimport stripAnsi from 'strip-ansi'\n\nimport {Writable} from 'stream'\nimport {AsyncLocalStorage} from 'node:async_hooks'\n\nexport interface ConcurrentOutputProps {\n processes: OutputProcess[]\n prefixColumnSize?: number\n abortSignal: AbortSignal\n showTimestamps?: boolean\n keepRunningAfterProcessesResolve?: boolean\n useAlternativeColorPalette?: boolean\n}\n\ninterface Chunk {\n color: TextProps['color']\n prefix: string\n lines: string[]\n}\n\nfunction addLeadingZero(number: number) {\n if (number < 10) {\n return `0${number}`\n } else {\n return number.toString()\n }\n}\n\nfunction currentTime() {\n const currentDateTime = new Date()\n const hours = addLeadingZero(currentDateTime.getHours())\n const minutes = addLeadingZero(currentDateTime.getMinutes())\n const seconds = addLeadingZero(currentDateTime.getSeconds())\n return `${hours}:${minutes}:${seconds}`\n}\n\ninterface ConcurrentOutputContext {\n outputPrefix?: string\n stripAnsi?: boolean\n}\n\nconst outputContextStore = new AsyncLocalStorage<ConcurrentOutputContext>()\n\nfunction useConcurrentOutputContext<T>(context: ConcurrentOutputContext, callback: () => T): T {\n return outputContextStore.run(context, callback)\n}\n\n/**\n * Renders output from concurrent processes to the terminal.\n * Output will be divided in a three column layout\n * with the left column containing the timestamp,\n * the right column containing the output,\n * and the middle column containing the process prefix.\n * Every process will be rendered with a different color, up to 4 colors.\n *\n * For example running `shopify app dev`:\n *\n * ```shell\n * 2022-10-10 13:11:03 | backend | npm\n * 2022-10-10 13:11:03 | backend | WARN ignoring workspace config at ...\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend | > shopify-app-template-node@0.1.0 dev\n * 2022-10-10 13:11:03 | backend | > cross-env NODE_ENV=development nodemon backend/index.js --watch ./backend\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | frontend | > starter-react-frontend-app@0.1.0 dev\n * 2022-10-10 13:11:03 | frontend | > cross-env NODE_ENV=development node vite-server.js\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend | [nodemon] to restart at any time, enter `rs`\n * 2022-10-10 13:11:03 | backend | [nodemon] watching path(s): backend/\n * 2022-10-10 13:11:03 | backend | [nodemon] watching extensions: js,mjs,json\n * 2022-10-10 13:11:03 | backend | [nodemon] starting `node backend/index.js`\n * 2022-10-10 13:11:03 | backend |\n *\n * ```\n */\nconst ConcurrentOutput: FunctionComponent<ConcurrentOutputProps> = ({\n processes,\n prefixColumnSize,\n abortSignal,\n showTimestamps = true,\n keepRunningAfterProcessesResolve = false,\n useAlternativeColorPalette = false,\n}) => {\n const [processOutput, setProcessOutput] = useState<Chunk[]>([])\n const {exit: unmountInk} = useApp()\n const concurrentColors: TextProps['color'][] = useMemo(\n () =>\n useAlternativeColorPalette\n ? ['#b994c3', '#e69e19', '#d17a73', 'cyan', 'magenta', 'blue']\n : ['yellow', 'cyan', 'magenta', 'green', 'blue'],\n [useAlternativeColorPalette],\n )\n\n const calculatedPrefixColumnSize = useMemo(() => {\n const maxColumnSize = 25\n\n // If the prefixColumnSize is not provided, we calculate it based on the longest process prefix\n const columnSize =\n prefixColumnSize ??\n processes.reduce((maxPrefixLength, process) => Math.max(maxPrefixLength, process.prefix.length), 0)\n\n // Apply overall limit to the prefix column size\n return Math.min(columnSize, maxColumnSize)\n }, [processes, prefixColumnSize])\n\n const addPrefix = (prefix: string, prefixes: string[]) => {\n const index = prefixes.indexOf(prefix)\n if (index !== -1) {\n return index\n }\n prefixes.push(prefix)\n return prefixes.length - 1\n }\n\n const lineColor = useCallback(\n (index: number) => {\n const colorIndex = index % concurrentColors.length\n return concurrentColors[colorIndex]\n },\n [concurrentColors],\n )\n\n const writableStream = useCallback(\n (process: OutputProcess, prefixes: string[]) => {\n return new Writable({\n write(chunk, _encoding, next) {\n const context = outputContextStore.getStore()\n const prefix = context?.outputPrefix ?? process.prefix\n const shouldStripAnsi = context?.stripAnsi ?? true\n const log = chunk.toString('utf8').replace(/(\\n)$/, '')\n\n const index = addPrefix(prefix, prefixes)\n\n const lines = shouldStripAnsi ? stripAnsi(log).split(/\\n/) : log.split(/\\n/)\n setProcessOutput((previousProcessOutput) => [\n ...previousProcessOutput,\n {\n color: lineColor(index),\n prefix,\n lines,\n },\n ])\n next()\n },\n })\n },\n [lineColor],\n )\n\n const formatPrefix = (prefix: string) => {\n // Truncate prefix if needed\n if (prefix.length > calculatedPrefixColumnSize) {\n return prefix.substring(0, calculatedPrefixColumnSize)\n }\n\n return `${' '.repeat(calculatedPrefixColumnSize - prefix.length)}${prefix}`\n }\n\n useEffect(() => {\n const runProcesses = async () => {\n const prefixes: string[] = []\n\n try {\n await Promise.all(\n processes.map(async (process) => {\n const stdout = writableStream(process, prefixes)\n const stderr = writableStream(process, prefixes)\n await process.action(stdout, stderr, abortSignal)\n }),\n )\n if (!keepRunningAfterProcessesResolve) {\n // Defer unmount so React 19 can flush batched setProcessOutput\n // state updates before the component tree is torn down.\n // Use setImmediate → setTimeout(0) to span two event-loop phases,\n // giving React's scheduler (which uses setImmediate in Node.js)\n // a full cycle to flush before we tear down the component tree.\n setImmediate(() => setTimeout(() => unmountInk(), 0))\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error: unknown) {\n if (!keepRunningAfterProcessesResolve) {\n setImmediate(() => setTimeout(() => unmountInk(error as Error | undefined), 0))\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n runProcesses()\n }, [abortSignal, processes, writableStream, unmountInk, keepRunningAfterProcessesResolve])\n\n const {lineVertical} = figures\n\n return (\n <Static items={processOutput}>\n {(chunk, index) => {\n return (\n <Box flexDirection=\"column\" key={index}>\n {chunk.lines.map((line, index) => (\n <Box key={index} flexDirection=\"row\">\n <Text>\n {showTimestamps ? (\n <Text>\n {currentTime()} {lineVertical}{' '}\n </Text>\n ) : null}\n <Text color={chunk.color}>{formatPrefix(chunk.prefix)}</Text>\n <Text>\n {' '}\n {lineVertical} {line}\n </Text>\n </Text>\n </Box>\n ))}\n </Box>\n )\n }}\n </Static>\n )\n}\nexport {ConcurrentOutput, ConcurrentOutputContext, useConcurrentOutputContext}\n"]}
@@ -240,7 +240,7 @@ describe('ConcurrentOutput', () => {
240
240
  };
241
241
  // When
242
242
  const renderInstance = render(React.createElement(ConcurrentOutput, { processes: [backendProcess], abortSignal: new AbortController().signal, keepRunningAfterProcessesResolve: true }));
243
- await new Promise((resolve) => setTimeout(resolve, 500));
243
+ await new Promise((resolve) => setTimeout(resolve, 10));
244
244
  expect(renderInstance.waitUntilExit().isRejected()).toBe(false);
245
245
  });
246
246
  test('render promise resolves when all processes resolve by default', async () => {
@@ -269,7 +269,7 @@ describe('ConcurrentOutput', () => {
269
269
  };
270
270
  // When
271
271
  const renderInstance = render(React.createElement(ConcurrentOutput, { keepRunningAfterProcessesResolve: true, processes: [backendProcess], abortSignal: new AbortController().signal }));
272
- await new Promise((resolve) => setTimeout(resolve, 500));
272
+ await new Promise((resolve) => setTimeout(resolve, 10));
273
273
  expect(renderInstance.waitUntilExit().isFulfilled()).toBe(false);
274
274
  });
275
275
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ConcurrentOutput.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/ConcurrentOutput.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {ConcurrentOutput, useConcurrentOutputContext} from './ConcurrentOutput.js'\nimport {render, waitForContent} from '../../testing/ui.js'\nimport {AbortController, AbortSignal} from '../../../../public/node/abort.js'\nimport {unstyled} from '../../../../public/node/output.js'\n\nimport React from 'react'\nimport {describe, expect, test} from 'vitest'\n\nimport {Writable} from 'stream'\n\n/**\n * ConcurrentOutput tests are unreliable unless we await a promise that resolves after the process has written to stdout.\n */\nclass Synchronizer {\n resolve: () => void\n promise: Promise<void>\n\n constructor() {\n this.resolve = () => {}\n this.promise = new Promise<void>((resolve, _reject) => {\n this.resolve = resolve\n })\n }\n}\n\ndescribe('ConcurrentOutput', () => {\n test('renders a stream of concurrent outputs from sub-processes', async () => {\n // Given\n const backendSync = new Synchronizer()\n const frontendSync = new Synchronizer()\n\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n\n backendSync.resolve()\n },\n }\n\n const frontendProcess = {\n prefix: 'frontend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n await backendSync.promise\n\n stdout.write('first frontend message')\n stdout.write('second frontend message')\n stdout.write('third frontend message')\n\n frontendSync.resolve()\n },\n }\n // When\n\n const renderInstance = render(\n <ConcurrentOutput processes={[backendProcess, frontendProcess]} abortSignal={new AbortController().signal} />,\n )\n\n await frontendSync.promise\n // Wait for React 19 to render the process output\n await waitForContent(renderInstance, 'third frontend message')\n\n // Then\n expect(unstyled(renderInstance.lastFrame()!.replace(/\\d/g, '0'))).toMatchInlineSnapshot(`\n \"00:00:00 │ backend │ first backend message\n 00:00:00 │ backend │ second backend message\n 00:00:00 │ backend │ third backend message\n 00:00:00 │ frontend │ first frontend message\n 00:00:00 │ frontend │ second frontend message\n 00:00:00 │ frontend │ third frontend message\n \"\n `)\n })\n\n test('strips ansi codes from the output by default', async () => {\n const output = 'foo'\n\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write(`\\u001b[32m${output}\\u001b[39m`)\n processSync.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, output)\n\n // Then\n const logColumns = renderInstance.lastFrame()!.split('│')\n expect(logColumns.length).toBe(3)\n expect(logColumns[2]?.trim()).toEqual(output)\n })\n\n test('does not strip ansi codes from the output when stripAnsi is false', async () => {\n const output = '\\u001b[32mfoo\\u001b[39m'\n\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n useConcurrentOutputContext({stripAnsi: false}, () => {\n stdout.write(output)\n })\n processSync.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, 'foo')\n\n // Then\n const logColumns = renderInstance.lastFrame()!.split('│')\n expect(logColumns.length).toBe(3)\n expect(logColumns[2]?.trim()).toEqual(output)\n })\n\n test('renders custom prefixes on log lines', async () => {\n // Given\n const processSync = new Synchronizer()\n const extensionName = 'my-extension'\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n useConcurrentOutputContext({outputPrefix: extensionName}, () => {\n stdout.write('foo bar')\n })\n processSync.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(\n <ConcurrentOutput\n processes={processes}\n // Ensure it's not truncated\n prefixColumnSize={extensionName.length}\n abortSignal={new AbortController().signal}\n />,\n )\n\n await processSync.promise\n await waitForContent(renderInstance, 'foo bar')\n\n // Then\n const logColumns = unstyled(renderInstance.lastFrame()!).split('│')\n expect(logColumns.length).toBe(3)\n expect(logColumns[1]?.trim()).toEqual(extensionName)\n })\n\n test('renders prefix column width based on prefixColumnSize', async () => {\n // Given\n const processSync1 = new Synchronizer()\n const processSync2 = new Synchronizer()\n\n const columnSize = 5\n const processes = [\n {\n prefix: '1234567890',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('foo')\n processSync1.resolve()\n },\n },\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('bar')\n processSync2.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(\n <ConcurrentOutput\n processes={processes}\n prefixColumnSize={columnSize}\n abortSignal={new AbortController().signal}\n />,\n )\n await Promise.all([processSync1.promise, processSync2.promise])\n await waitForContent(renderInstance, 'bar')\n\n // Then\n const logLines = unstyled(renderInstance.lastFrame()!).split('\\n').filter(Boolean)\n expect(logLines.length).toBe(2)\n logLines.forEach((line) => {\n const logColumns = line.split('│')\n expect(logColumns.length).toBe(3)\n // Including spacing\n expect(logColumns[1]?.length).toBe(columnSize + 2)\n })\n })\n\n test('renders prefix column width based on processes by default', async () => {\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('foo')\n processSync.resolve()\n },\n },\n {prefix: '12', action: async () => {}},\n {prefix: '123', action: async () => {}},\n {prefix: '1234', action: async () => {}},\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, 'foo')\n\n // Then\n const logColumns = unstyled(renderInstance.lastFrame()!).split('│')\n expect(logColumns.length).toBe(3)\n // 4 is largest prefix, plus spacing\n expect(logColumns[1]?.length).toBe(4 + 2)\n })\n\n test('does not render prefix column larger than max', async () => {\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('foo')\n processSync.resolve()\n },\n },\n {prefix: new Array(26).join('0'), action: async () => {}},\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, 'foo')\n\n // Then\n const logColumns = unstyled(renderInstance.lastFrame()!).split('│')\n expect(logColumns.length).toBe(3)\n // 25 is largest column allowed, plus spacing\n expect(logColumns[1]?.length).toBe(25 + 2)\n })\n\n test('rejects with the error thrown inside one of the processes', async () => {\n // Given\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n\n throw new Error('something went wrong')\n },\n }\n\n // When\n\n const renderInstance = render(\n <ConcurrentOutput processes={[backendProcess]} abortSignal={new AbortController().signal} />,\n )\n\n const renderPromise = renderInstance.waitUntilExit()\n\n await expect(renderPromise).rejects.toThrowError('something went wrong')\n expect(renderPromise.isRejected()).toBe(true)\n })\n\n test(\"doesn't reject when an error is thrown inside one of the processes and keepRunningAfterProcessesResolve is true\", async () => {\n // Given\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n\n throw new Error('something went wrong')\n },\n }\n\n // When\n\n const renderInstance = render(\n <ConcurrentOutput\n processes={[backendProcess]}\n abortSignal={new AbortController().signal}\n keepRunningAfterProcessesResolve\n />,\n )\n\n await new Promise((resolve) => setTimeout(resolve, 500))\n expect(renderInstance.waitUntilExit().isRejected()).toBe(false)\n })\n\n test('render promise resolves when all processes resolve by default', async () => {\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n },\n }\n\n // When\n const renderInstance = render(\n <ConcurrentOutput processes={[backendProcess]} abortSignal={new AbortController().signal} />,\n )\n\n const renderPromise = renderInstance.waitUntilExit()\n\n await renderPromise\n expect(renderPromise.isFulfilled()).toBe(true)\n })\n\n test(\"render promise doesn't resolve when all processes resolve and keepRunningAfterProcessesResolve is true\", async () => {\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n },\n }\n\n // When\n const renderInstance = render(\n <ConcurrentOutput\n keepRunningAfterProcessesResolve\n processes={[backendProcess]}\n abortSignal={new AbortController().signal}\n />,\n )\n\n await new Promise((resolve) => setTimeout(resolve, 500))\n\n expect(renderInstance.waitUntilExit().isFulfilled()).toBe(false)\n })\n})\n"]}
1
+ {"version":3,"file":"ConcurrentOutput.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/ConcurrentOutput.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAE,0BAA0B,EAAC,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAC,MAAM,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAC,eAAe,EAAc,MAAM,kCAAkC,CAAA;AAC7E,OAAO,EAAC,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAE1D,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAI7C;;GAEG;AACH,MAAM,YAAY;IAIhB;QACE,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;YACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACxB,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,QAAQ;QACR,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAA;QACtC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA;QAEvC,MAAM,cAAc,GAAG;YACrB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;gBAC1E,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBACrC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;gBACtC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBAErC,WAAW,CAAC,OAAO,EAAE,CAAA;YACvB,CAAC;SACF,CAAA;QAED,MAAM,eAAe,GAAG;YACtB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;gBAC1E,MAAM,WAAW,CAAC,OAAO,CAAA;gBAEzB,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;gBACtC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;gBACvC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;gBAEtC,YAAY,CAAC,OAAO,EAAE,CAAA;YACxB,CAAC;SACF,CAAA;QACD,OAAO;QAEP,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,gBAAgB,IAAC,SAAS,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GAAI,CAC9G,CAAA;QAED,MAAM,YAAY,CAAC,OAAO,CAAA;QAC1B,iDAAiD;QACjD,MAAM,cAAc,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAA;QAE9D,OAAO;QACP,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,SAAS,EAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;KAQvF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,MAAM,GAAG,KAAK,CAAA;QAEpB,QAAQ;QACR,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAA;QACtC,MAAM,SAAS,GAAG;YAChB;gBACE,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;oBAC1E,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,YAAY,CAAC,CAAA;oBAC7C,WAAW,CAAC,OAAO,EAAE,CAAA;gBACvB,CAAC;aACF;SACF,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAC,gBAAgB,IAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GAAI,CAAC,CAAA;QACpH,MAAM,WAAW,CAAC,OAAO,CAAA;QACzB,MAAM,cAAc,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;QAE5C,OAAO;QACP,MAAM,UAAU,GAAG,cAAc,CAAC,SAAS,EAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACzD,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,MAAM,GAAG,yBAAyB,CAAA;QAExC,QAAQ;QACR,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAA;QACtC,MAAM,SAAS,GAAG;YAChB;gBACE,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;oBAC1E,0BAA0B,CAAC,EAAC,SAAS,EAAE,KAAK,EAAC,EAAE,GAAG,EAAE;wBAClD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;oBACtB,CAAC,CAAC,CAAA;oBACF,WAAW,CAAC,OAAO,EAAE,CAAA;gBACvB,CAAC;aACF;SACF,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAC,gBAAgB,IAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GAAI,CAAC,CAAA;QACpH,MAAM,WAAW,CAAC,OAAO,CAAA;QACzB,MAAM,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAE3C,OAAO;QACP,MAAM,UAAU,GAAG,cAAc,CAAC,SAAS,EAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACzD,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACtD,QAAQ;QACR,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAA;QACtC,MAAM,aAAa,GAAG,cAAc,CAAA;QACpC,MAAM,SAAS,GAAG;YAChB;gBACE,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;oBAC1E,0BAA0B,CAAC,EAAC,YAAY,EAAE,aAAa,EAAC,EAAE,GAAG,EAAE;wBAC7D,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;oBACzB,CAAC,CAAC,CAAA;oBACF,WAAW,CAAC,OAAO,EAAE,CAAA;gBACvB,CAAC;aACF;SACF,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,gBAAgB,IACf,SAAS,EAAE,SAAS;YACpB,4BAA4B;YAC5B,gBAAgB,EAAE,aAAa,CAAC,MAAM,EACtC,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GACzC,CACH,CAAA;QAED,MAAM,WAAW,CAAC,OAAO,CAAA;QACzB,MAAM,cAAc,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;QAE/C,OAAO;QACP,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,EAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACnE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACvE,QAAQ;QACR,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA;QACvC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA;QAEvC,MAAM,UAAU,GAAG,CAAC,CAAA;QACpB,MAAM,SAAS,GAAG;YAChB;gBACE,MAAM,EAAE,YAAY;gBACpB,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;oBAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACnB,YAAY,CAAC,OAAO,EAAE,CAAA;gBACxB,CAAC;aACF;YACD;gBACE,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;oBAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACnB,YAAY,CAAC,OAAO,EAAE,CAAA;gBACxB,CAAC;aACF;SACF,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,gBAAgB,IACf,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,UAAU,EAC5B,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GACzC,CACH,CAAA;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAA;QAC/D,MAAM,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAE3C,OAAO;QACP,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,EAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAClF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC/B,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACxB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjC,oBAAoB;YACpB,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;QACpD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,QAAQ;QACR,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAA;QACtC,MAAM,SAAS,GAAG;YAChB;gBACE,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;oBAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACnB,WAAW,CAAC,OAAO,EAAE,CAAA;gBACvB,CAAC;aACF;YACD,EAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAC;YACtC,EAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAC;YACvC,EAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAC;SACzC,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAC,gBAAgB,IAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GAAI,CAAC,CAAA;QACpH,MAAM,WAAW,CAAC,OAAO,CAAA;QACzB,MAAM,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAE3C,OAAO;QACP,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,EAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACnE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjC,oCAAoC;QACpC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC/D,QAAQ;QACR,MAAM,WAAW,GAAG,IAAI,YAAY,EAAE,CAAA;QACtC,MAAM,SAAS,GAAG;YAChB;gBACE,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;oBAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACnB,WAAW,CAAC,OAAO,EAAE,CAAA;gBACvB,CAAC;aACF;YACD,EAAC,MAAM,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAC;SAC1D,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAC,gBAAgB,IAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GAAI,CAAC,CAAA;QACpH,MAAM,WAAW,CAAC,OAAO,CAAA;QACzB,MAAM,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAE3C,OAAO;QACP,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,EAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACnE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjC,6CAA6C;QAC7C,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,QAAQ;QACR,MAAM,cAAc,GAAG;YACrB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;gBAC1E,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBACrC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;gBACtC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBAErC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;YACzC,CAAC;SACF,CAAA;QAED,OAAO;QAEP,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,gBAAgB,IAAC,SAAS,EAAE,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GAAI,CAC7F,CAAA;QAED,MAAM,aAAa,GAAG,cAAc,CAAC,aAAa,EAAE,CAAA;QAEpD,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAA;QACxE,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,iHAAiH,EAAE,KAAK,IAAI,EAAE;QACjI,QAAQ;QACR,MAAM,cAAc,GAAG;YACrB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;gBAC1E,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBACrC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;gBACtC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBAErC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;YACzC,CAAC;SACF,CAAA;QAED,OAAO;QAEP,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,gBAAgB,IACf,SAAS,EAAE,CAAC,cAAc,CAAC,EAC3B,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EACzC,gCAAgC,SAChC,CACH,CAAA;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QACvD,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,cAAc,GAAG;YACrB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;gBAC1E,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBACrC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;gBACtC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;YACvC,CAAC;SACF,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,gBAAgB,IAAC,SAAS,EAAE,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GAAI,CAC7F,CAAA;QAED,MAAM,aAAa,GAAG,cAAc,CAAC,aAAa,EAAE,CAAA;QAEpD,MAAM,aAAa,CAAA;QACnB,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,wGAAwG,EAAE,KAAK,IAAI,EAAE;QACxH,MAAM,cAAc,GAAG;YACrB,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK,EAAE,MAAgB,EAAE,OAAiB,EAAE,OAAoB,EAAE,EAAE;gBAC1E,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;gBACrC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;gBACtC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;YACvC,CAAC;SACF,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,gBAAgB,IACf,gCAAgC,QAChC,SAAS,EAAE,CAAC,cAAc,CAAC,EAC3B,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,GACzC,CACH,CAAA;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QAEvD,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {ConcurrentOutput, useConcurrentOutputContext} from './ConcurrentOutput.js'\nimport {render, waitForContent} from '../../testing/ui.js'\nimport {AbortController, AbortSignal} from '../../../../public/node/abort.js'\nimport {unstyled} from '../../../../public/node/output.js'\n\nimport React from 'react'\nimport {describe, expect, test} from 'vitest'\n\nimport {Writable} from 'stream'\n\n/**\n * ConcurrentOutput tests are unreliable unless we await a promise that resolves after the process has written to stdout.\n */\nclass Synchronizer {\n resolve: () => void\n promise: Promise<void>\n\n constructor() {\n this.resolve = () => {}\n this.promise = new Promise<void>((resolve, _reject) => {\n this.resolve = resolve\n })\n }\n}\n\ndescribe('ConcurrentOutput', () => {\n test('renders a stream of concurrent outputs from sub-processes', async () => {\n // Given\n const backendSync = new Synchronizer()\n const frontendSync = new Synchronizer()\n\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n\n backendSync.resolve()\n },\n }\n\n const frontendProcess = {\n prefix: 'frontend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n await backendSync.promise\n\n stdout.write('first frontend message')\n stdout.write('second frontend message')\n stdout.write('third frontend message')\n\n frontendSync.resolve()\n },\n }\n // When\n\n const renderInstance = render(\n <ConcurrentOutput processes={[backendProcess, frontendProcess]} abortSignal={new AbortController().signal} />,\n )\n\n await frontendSync.promise\n // Wait for React 19 to render the process output\n await waitForContent(renderInstance, 'third frontend message')\n\n // Then\n expect(unstyled(renderInstance.lastFrame()!.replace(/\\d/g, '0'))).toMatchInlineSnapshot(`\n \"00:00:00 │ backend │ first backend message\n 00:00:00 │ backend │ second backend message\n 00:00:00 │ backend │ third backend message\n 00:00:00 │ frontend │ first frontend message\n 00:00:00 │ frontend │ second frontend message\n 00:00:00 │ frontend │ third frontend message\n \"\n `)\n })\n\n test('strips ansi codes from the output by default', async () => {\n const output = 'foo'\n\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write(`\\u001b[32m${output}\\u001b[39m`)\n processSync.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, output)\n\n // Then\n const logColumns = renderInstance.lastFrame()!.split('│')\n expect(logColumns.length).toBe(3)\n expect(logColumns[2]?.trim()).toEqual(output)\n })\n\n test('does not strip ansi codes from the output when stripAnsi is false', async () => {\n const output = '\\u001b[32mfoo\\u001b[39m'\n\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n useConcurrentOutputContext({stripAnsi: false}, () => {\n stdout.write(output)\n })\n processSync.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, 'foo')\n\n // Then\n const logColumns = renderInstance.lastFrame()!.split('│')\n expect(logColumns.length).toBe(3)\n expect(logColumns[2]?.trim()).toEqual(output)\n })\n\n test('renders custom prefixes on log lines', async () => {\n // Given\n const processSync = new Synchronizer()\n const extensionName = 'my-extension'\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n useConcurrentOutputContext({outputPrefix: extensionName}, () => {\n stdout.write('foo bar')\n })\n processSync.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(\n <ConcurrentOutput\n processes={processes}\n // Ensure it's not truncated\n prefixColumnSize={extensionName.length}\n abortSignal={new AbortController().signal}\n />,\n )\n\n await processSync.promise\n await waitForContent(renderInstance, 'foo bar')\n\n // Then\n const logColumns = unstyled(renderInstance.lastFrame()!).split('│')\n expect(logColumns.length).toBe(3)\n expect(logColumns[1]?.trim()).toEqual(extensionName)\n })\n\n test('renders prefix column width based on prefixColumnSize', async () => {\n // Given\n const processSync1 = new Synchronizer()\n const processSync2 = new Synchronizer()\n\n const columnSize = 5\n const processes = [\n {\n prefix: '1234567890',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('foo')\n processSync1.resolve()\n },\n },\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('bar')\n processSync2.resolve()\n },\n },\n ]\n\n // When\n const renderInstance = render(\n <ConcurrentOutput\n processes={processes}\n prefixColumnSize={columnSize}\n abortSignal={new AbortController().signal}\n />,\n )\n await Promise.all([processSync1.promise, processSync2.promise])\n await waitForContent(renderInstance, 'bar')\n\n // Then\n const logLines = unstyled(renderInstance.lastFrame()!).split('\\n').filter(Boolean)\n expect(logLines.length).toBe(2)\n logLines.forEach((line) => {\n const logColumns = line.split('│')\n expect(logColumns.length).toBe(3)\n // Including spacing\n expect(logColumns[1]?.length).toBe(columnSize + 2)\n })\n })\n\n test('renders prefix column width based on processes by default', async () => {\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('foo')\n processSync.resolve()\n },\n },\n {prefix: '12', action: async () => {}},\n {prefix: '123', action: async () => {}},\n {prefix: '1234', action: async () => {}},\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, 'foo')\n\n // Then\n const logColumns = unstyled(renderInstance.lastFrame()!).split('│')\n expect(logColumns.length).toBe(3)\n // 4 is largest prefix, plus spacing\n expect(logColumns[1]?.length).toBe(4 + 2)\n })\n\n test('does not render prefix column larger than max', async () => {\n // Given\n const processSync = new Synchronizer()\n const processes = [\n {\n prefix: '1',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('foo')\n processSync.resolve()\n },\n },\n {prefix: new Array(26).join('0'), action: async () => {}},\n ]\n\n // When\n const renderInstance = render(<ConcurrentOutput processes={processes} abortSignal={new AbortController().signal} />)\n await processSync.promise\n await waitForContent(renderInstance, 'foo')\n\n // Then\n const logColumns = unstyled(renderInstance.lastFrame()!).split('│')\n expect(logColumns.length).toBe(3)\n // 25 is largest column allowed, plus spacing\n expect(logColumns[1]?.length).toBe(25 + 2)\n })\n\n test('rejects with the error thrown inside one of the processes', async () => {\n // Given\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n\n throw new Error('something went wrong')\n },\n }\n\n // When\n\n const renderInstance = render(\n <ConcurrentOutput processes={[backendProcess]} abortSignal={new AbortController().signal} />,\n )\n\n const renderPromise = renderInstance.waitUntilExit()\n\n await expect(renderPromise).rejects.toThrowError('something went wrong')\n expect(renderPromise.isRejected()).toBe(true)\n })\n\n test(\"doesn't reject when an error is thrown inside one of the processes and keepRunningAfterProcessesResolve is true\", async () => {\n // Given\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n\n throw new Error('something went wrong')\n },\n }\n\n // When\n\n const renderInstance = render(\n <ConcurrentOutput\n processes={[backendProcess]}\n abortSignal={new AbortController().signal}\n keepRunningAfterProcessesResolve\n />,\n )\n\n await new Promise((resolve) => setTimeout(resolve, 10))\n expect(renderInstance.waitUntilExit().isRejected()).toBe(false)\n })\n\n test('render promise resolves when all processes resolve by default', async () => {\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n },\n }\n\n // When\n const renderInstance = render(\n <ConcurrentOutput processes={[backendProcess]} abortSignal={new AbortController().signal} />,\n )\n\n const renderPromise = renderInstance.waitUntilExit()\n\n await renderPromise\n expect(renderPromise.isFulfilled()).toBe(true)\n })\n\n test(\"render promise doesn't resolve when all processes resolve and keepRunningAfterProcessesResolve is true\", async () => {\n const backendProcess = {\n prefix: 'backend',\n action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => {\n stdout.write('first backend message')\n stdout.write('second backend message')\n stdout.write('third backend message')\n },\n }\n\n // When\n const renderInstance = render(\n <ConcurrentOutput\n keepRunningAfterProcessesResolve\n processes={[backendProcess]}\n abortSignal={new AbortController().signal}\n />,\n )\n\n await new Promise((resolve) => setTimeout(resolve, 10))\n\n expect(renderInstance.waitUntilExit().isFulfilled()).toBe(false)\n })\n})\n"]}