@navios/commander-tui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +275 -0
  3. package/coverage/__tests__/utils/factories.ts.html +1147 -0
  4. package/coverage/__tests__/utils/index.html +131 -0
  5. package/coverage/__tests__/utils/render-utils.tsx.html +202 -0
  6. package/coverage/base.css +224 -0
  7. package/coverage/block-navigation.js +87 -0
  8. package/coverage/clover.xml +959 -0
  9. package/coverage/components/filter/filter_bar.tsx.html +322 -0
  10. package/coverage/components/filter/index.html +116 -0
  11. package/coverage/components/log/index.html +131 -0
  12. package/coverage/components/log/index.ts.html +88 -0
  13. package/coverage/components/log/log_message.tsx.html +391 -0
  14. package/coverage/components/prompt/index.html +116 -0
  15. package/coverage/components/prompt/prompt_renderer.tsx.html +1123 -0
  16. package/coverage/components/screen/index.html +131 -0
  17. package/coverage/components/screen/loading_message.tsx.html +217 -0
  18. package/coverage/components/screen/progress_message.tsx.html +265 -0
  19. package/coverage/components/sidebar/index.html +146 -0
  20. package/coverage/components/sidebar/sidebar.tsx.html +391 -0
  21. package/coverage/components/sidebar/sidebar_item.tsx.html +235 -0
  22. package/coverage/components/sidebar/sidebar_separator.tsx.html +124 -0
  23. package/coverage/context/index.html +131 -0
  24. package/coverage/context/index.ts.html +88 -0
  25. package/coverage/context/logger_context.tsx.html +412 -0
  26. package/coverage/coverage-final.json +55 -0
  27. package/coverage/favicon.png +0 -0
  28. package/coverage/filter/filter_engine.ts.html +424 -0
  29. package/coverage/filter/index.html +116 -0
  30. package/coverage/hooks/index.html +131 -0
  31. package/coverage/hooks/index.ts.html +88 -0
  32. package/coverage/hooks/use_theme.ts.html +121 -0
  33. package/coverage/index.html +356 -0
  34. package/coverage/keyboard/index.html +116 -0
  35. package/coverage/keyboard/keyboard_manager.ts.html +784 -0
  36. package/coverage/prettify.css +1 -0
  37. package/coverage/prettify.js +2 -0
  38. package/coverage/schemas/index.html +161 -0
  39. package/coverage/schemas/index.ts.html +94 -0
  40. package/coverage/schemas/logger-options.ts.html +124 -0
  41. package/coverage/schemas/prompt-options.ts.html +112 -0
  42. package/coverage/schemas/screen-options.ts.html +127 -0
  43. package/coverage/services/index.html +146 -0
  44. package/coverage/services/logger.ts.html +1192 -0
  45. package/coverage/services/prompt.ts.html +568 -0
  46. package/coverage/services/screen.ts.html +1804 -0
  47. package/coverage/sort-arrow-sprite.png +0 -0
  48. package/coverage/sorter.js +210 -0
  49. package/coverage/themes/dark.ts.html +604 -0
  50. package/coverage/themes/high-contrast.ts.html +619 -0
  51. package/coverage/themes/index.html +176 -0
  52. package/coverage/themes/index.ts.html +97 -0
  53. package/coverage/themes/light.ts.html +601 -0
  54. package/coverage/themes/utils.ts.html +334 -0
  55. package/coverage/tokens/index.html +161 -0
  56. package/coverage/tokens/index.ts.html +94 -0
  57. package/coverage/tokens/logger.ts.html +115 -0
  58. package/coverage/tokens/prompt.ts.html +115 -0
  59. package/coverage/tokens/screen.ts.html +115 -0
  60. package/coverage/types/file.types.ts.html +265 -0
  61. package/coverage/types/filter.types.ts.html +238 -0
  62. package/coverage/types/index.html +236 -0
  63. package/coverage/types/index.ts.html +151 -0
  64. package/coverage/types/keyboard.types.ts.html +364 -0
  65. package/coverage/types/log.types.ts.html +268 -0
  66. package/coverage/types/message.types.ts.html +445 -0
  67. package/coverage/types/prompt.types.ts.html +403 -0
  68. package/coverage/types/screen.types.ts.html +451 -0
  69. package/coverage/types/theme.types.ts.html +841 -0
  70. package/coverage/utils/colors/file-colors.ts.html +112 -0
  71. package/coverage/utils/colors/helpers.ts.html +235 -0
  72. package/coverage/utils/colors/index.html +221 -0
  73. package/coverage/utils/colors/index.ts.html +145 -0
  74. package/coverage/utils/colors/log-colors.ts.html +253 -0
  75. package/coverage/utils/colors/progress-colors.ts.html +160 -0
  76. package/coverage/utils/colors/prompt-colors.ts.html +175 -0
  77. package/coverage/utils/colors/sidebar-colors.ts.html +241 -0
  78. package/coverage/utils/colors/table-colors.ts.html +118 -0
  79. package/coverage/utils/filetype.ts.html +277 -0
  80. package/coverage/utils/format.ts.html +241 -0
  81. package/coverage/utils/index.html +161 -0
  82. package/coverage/utils/index.ts.html +118 -0
  83. package/coverage/utils/stdout-printer.ts.html +523 -0
  84. package/dist/src/components/file/file_log.d.ts +35 -0
  85. package/dist/src/components/file/file_log.d.ts.map +1 -0
  86. package/dist/src/components/file/index.d.ts +2 -0
  87. package/dist/src/components/file/index.d.ts.map +1 -0
  88. package/dist/src/components/filter/filter_bar.d.ts +10 -0
  89. package/dist/src/components/filter/filter_bar.d.ts.map +1 -0
  90. package/dist/src/components/filter/index.d.ts +2 -0
  91. package/dist/src/components/filter/index.d.ts.map +1 -0
  92. package/dist/src/components/help/help_overlay.d.ts +10 -0
  93. package/dist/src/components/help/help_overlay.d.ts.map +1 -0
  94. package/dist/src/components/help/index.d.ts +2 -0
  95. package/dist/src/components/help/index.d.ts.map +1 -0
  96. package/dist/src/components/index.d.ts +27 -0
  97. package/dist/src/components/index.d.ts.map +1 -0
  98. package/dist/src/components/log/debug_log.d.ts +3 -0
  99. package/dist/src/components/log/debug_log.d.ts.map +1 -0
  100. package/dist/src/components/log/error_log.d.ts +3 -0
  101. package/dist/src/components/log/error_log.d.ts.map +1 -0
  102. package/dist/src/components/log/fatal_log.d.ts +3 -0
  103. package/dist/src/components/log/fatal_log.d.ts.map +1 -0
  104. package/dist/src/components/log/index.d.ts +9 -0
  105. package/dist/src/components/log/index.d.ts.map +1 -0
  106. package/dist/src/components/log/info_log.d.ts +3 -0
  107. package/dist/src/components/log/info_log.d.ts.map +1 -0
  108. package/dist/src/components/log/log_message.d.ts +33 -0
  109. package/dist/src/components/log/log_message.d.ts.map +1 -0
  110. package/dist/src/components/log/success_log.d.ts +3 -0
  111. package/dist/src/components/log/success_log.d.ts.map +1 -0
  112. package/dist/src/components/log/trace_log.d.ts +3 -0
  113. package/dist/src/components/log/trace_log.d.ts.map +1 -0
  114. package/dist/src/components/log/warning_log.d.ts +3 -0
  115. package/dist/src/components/log/warning_log.d.ts.map +1 -0
  116. package/dist/src/components/prompt/index.d.ts +3 -0
  117. package/dist/src/components/prompt/index.d.ts.map +1 -0
  118. package/dist/src/components/prompt/prompt_renderer.d.ts +6 -0
  119. package/dist/src/components/prompt/prompt_renderer.d.ts.map +1 -0
  120. package/dist/src/components/screen/group_renderer.d.ts +19 -0
  121. package/dist/src/components/screen/group_renderer.d.ts.map +1 -0
  122. package/dist/src/components/screen/index.d.ts +13 -0
  123. package/dist/src/components/screen/index.d.ts.map +1 -0
  124. package/dist/src/components/screen/loading_message.d.ts +6 -0
  125. package/dist/src/components/screen/loading_message.d.ts.map +1 -0
  126. package/dist/src/components/screen/message_renderer.d.ts +8 -0
  127. package/dist/src/components/screen/message_renderer.d.ts.map +1 -0
  128. package/dist/src/components/screen/progress_message.d.ts +8 -0
  129. package/dist/src/components/screen/progress_message.d.ts.map +1 -0
  130. package/dist/src/components/screen/screen_bridge.d.ts +20 -0
  131. package/dist/src/components/screen/screen_bridge.d.ts.map +1 -0
  132. package/dist/src/components/screen/table_message.d.ts +6 -0
  133. package/dist/src/components/screen/table_message.d.ts.map +1 -0
  134. package/dist/src/components/screen_manager_bridge.d.ts +11 -0
  135. package/dist/src/components/screen_manager_bridge.d.ts.map +1 -0
  136. package/dist/src/components/sidebar/index.d.ts +6 -0
  137. package/dist/src/components/sidebar/index.d.ts.map +1 -0
  138. package/dist/src/components/sidebar/sidebar.d.ts +18 -0
  139. package/dist/src/components/sidebar/sidebar.d.ts.map +1 -0
  140. package/dist/src/components/sidebar/sidebar_item.d.ts +14 -0
  141. package/dist/src/components/sidebar/sidebar_item.d.ts.map +1 -0
  142. package/dist/src/components/sidebar/sidebar_separator.d.ts +2 -0
  143. package/dist/src/components/sidebar/sidebar_separator.d.ts.map +1 -0
  144. package/dist/src/context/logger_context.d.ts +60 -0
  145. package/dist/src/context/logger_context.d.ts.map +1 -0
  146. package/dist/src/filter/filter_engine.d.ts +20 -0
  147. package/dist/src/filter/filter_engine.d.ts.map +1 -0
  148. package/dist/src/filter/index.d.ts +4 -0
  149. package/dist/src/filter/index.d.ts.map +1 -0
  150. package/dist/src/hooks/index.d.ts +2 -0
  151. package/dist/src/hooks/index.d.ts.map +1 -0
  152. package/dist/src/hooks/use_theme.d.ts +7 -0
  153. package/dist/src/hooks/use_theme.d.ts.map +1 -0
  154. package/dist/src/index.d.ts +88 -0
  155. package/dist/src/index.d.ts.map +1 -0
  156. package/dist/src/keyboard/create_bindings.d.ts +31 -0
  157. package/dist/src/keyboard/create_bindings.d.ts.map +1 -0
  158. package/dist/src/keyboard/index.d.ts +12 -0
  159. package/dist/src/keyboard/index.d.ts.map +1 -0
  160. package/dist/src/keyboard/keyboard_manager.d.ts +69 -0
  161. package/dist/src/keyboard/keyboard_manager.d.ts.map +1 -0
  162. package/dist/src/services/index.d.ts +5 -0
  163. package/dist/src/services/index.d.ts.map +1 -0
  164. package/dist/src/services/logger.d.ts +61 -0
  165. package/dist/src/services/logger.d.ts.map +1 -0
  166. package/dist/src/services/prompt.d.ts +37 -0
  167. package/dist/src/services/prompt.d.ts.map +1 -0
  168. package/dist/src/services/screen.d.ts +165 -0
  169. package/dist/src/services/screen.d.ts.map +1 -0
  170. package/dist/src/services/screen_manager.d.ts +124 -0
  171. package/dist/src/services/screen_manager.d.ts.map +1 -0
  172. package/dist/src/themes/dark.d.ts +7 -0
  173. package/dist/src/themes/dark.d.ts.map +1 -0
  174. package/dist/src/themes/high-contrast.d.ts +7 -0
  175. package/dist/src/themes/high-contrast.d.ts.map +1 -0
  176. package/dist/src/themes/index.d.ts +18 -0
  177. package/dist/src/themes/index.d.ts.map +1 -0
  178. package/dist/src/themes/light.d.ts +6 -0
  179. package/dist/src/themes/light.d.ts.map +1 -0
  180. package/dist/src/themes/utils.d.ts +22 -0
  181. package/dist/src/themes/utils.d.ts.map +1 -0
  182. package/dist/src/types/file.types.d.ts +40 -0
  183. package/dist/src/types/file.types.d.ts.map +1 -0
  184. package/dist/src/types/filter.types.d.ts +31 -0
  185. package/dist/src/types/filter.types.d.ts.map +1 -0
  186. package/dist/src/types/index.d.ts +81 -0
  187. package/dist/src/types/index.d.ts.map +1 -0
  188. package/dist/src/types/keyboard.types.d.ts +83 -0
  189. package/dist/src/types/keyboard.types.d.ts.map +1 -0
  190. package/dist/src/types/log.types.d.ts +32 -0
  191. package/dist/src/types/log.types.d.ts.map +1 -0
  192. package/dist/src/types/message.types.d.ts +91 -0
  193. package/dist/src/types/message.types.d.ts.map +1 -0
  194. package/dist/src/types/prompt.types.d.ts +89 -0
  195. package/dist/src/types/prompt.types.d.ts.map +1 -0
  196. package/dist/src/types/screen.types.d.ts +85 -0
  197. package/dist/src/types/screen.types.d.ts.map +1 -0
  198. package/dist/src/types/theme.types.d.ts +216 -0
  199. package/dist/src/types/theme.types.d.ts.map +1 -0
  200. package/dist/src/utils/colors/file-colors.d.ts +10 -0
  201. package/dist/src/utils/colors/file-colors.d.ts.map +1 -0
  202. package/dist/src/utils/colors/helpers.d.ts +29 -0
  203. package/dist/src/utils/colors/helpers.d.ts.map +1 -0
  204. package/dist/src/utils/colors/index.d.ts +13 -0
  205. package/dist/src/utils/colors/index.d.ts.map +1 -0
  206. package/dist/src/utils/colors/log-colors.d.ts +15 -0
  207. package/dist/src/utils/colors/log-colors.d.ts.map +1 -0
  208. package/dist/src/utils/colors/progress-colors.d.ts +25 -0
  209. package/dist/src/utils/colors/progress-colors.d.ts.map +1 -0
  210. package/dist/src/utils/colors/prompt-colors.d.ts +22 -0
  211. package/dist/src/utils/colors/prompt-colors.d.ts.map +1 -0
  212. package/dist/src/utils/colors/sidebar-colors.d.ts +50 -0
  213. package/dist/src/utils/colors/sidebar-colors.d.ts.map +1 -0
  214. package/dist/src/utils/colors/table-colors.d.ts +12 -0
  215. package/dist/src/utils/colors/table-colors.d.ts.map +1 -0
  216. package/dist/src/utils/filetype.d.ts +19 -0
  217. package/dist/src/utils/filetype.d.ts.map +1 -0
  218. package/dist/src/utils/format.d.ts +9 -0
  219. package/dist/src/utils/format.d.ts.map +1 -0
  220. package/dist/src/utils/index.d.ts +20 -0
  221. package/dist/src/utils/index.d.ts.map +1 -0
  222. package/dist/src/utils/stdout-printer.d.ts +10 -0
  223. package/dist/src/utils/stdout-printer.d.ts.map +1 -0
  224. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  225. package/dist/tsconfig.tsbuildinfo +1 -0
  226. package/dist/tsdown.config.d.mts +5 -0
  227. package/dist/tsdown.config.d.mts.map +1 -0
  228. package/dist/vitest.config.d.mts +3 -0
  229. package/dist/vitest.config.d.mts.map +1 -0
  230. package/lib/index.cjs +6349 -0
  231. package/lib/index.cjs.map +1 -0
  232. package/lib/index.d.cts +1720 -0
  233. package/lib/index.d.cts.map +1 -0
  234. package/lib/index.d.mts +1720 -0
  235. package/lib/index.d.mts.map +1 -0
  236. package/lib/index.mjs +6264 -0
  237. package/lib/index.mjs.map +1 -0
  238. package/lib/screen_manager_bridge-BpDgVu3e.cjs +3357 -0
  239. package/lib/screen_manager_bridge-BpDgVu3e.cjs.map +1 -0
  240. package/lib/screen_manager_bridge-CkV7637i.cjs +3 -0
  241. package/lib/screen_manager_bridge-DN2J6_k1.mjs +3 -0
  242. package/lib/screen_manager_bridge-Dfg4QUrl.mjs +3034 -0
  243. package/lib/screen_manager_bridge-Dfg4QUrl.mjs.map +1 -0
  244. package/package.json +43 -0
  245. package/project.json +60 -0
  246. package/src/__tests__/components/__snapshots__/filter_bar.spec.tsx.snap +2245 -0
  247. package/src/__tests__/components/__snapshots__/loading_message.spec.tsx.snap +1382 -0
  248. package/src/__tests__/components/__snapshots__/log_message.spec.tsx.snap +3169 -0
  249. package/src/__tests__/components/__snapshots__/progress_message.spec.tsx.snap +1743 -0
  250. package/src/__tests__/components/__snapshots__/prompt_renderer.spec.tsx.snap +3135 -0
  251. package/src/__tests__/components/__snapshots__/sidebar.spec.tsx.snap +2617 -0
  252. package/src/__tests__/components/filter_bar.spec.tsx +190 -0
  253. package/src/__tests__/components/loading_message.spec.tsx +110 -0
  254. package/src/__tests__/components/log_message.spec.tsx +166 -0
  255. package/src/__tests__/components/progress_message.spec.tsx +147 -0
  256. package/src/__tests__/components/prompt_renderer.spec.tsx +274 -0
  257. package/src/__tests__/components/sidebar.spec.tsx +305 -0
  258. package/src/__tests__/filter/filter_engine.spec.ts +325 -0
  259. package/src/__tests__/keyboard/keyboard_manager.spec.ts +557 -0
  260. package/src/__tests__/mocks/scm-mock.ts +5 -0
  261. package/src/__tests__/services/logger.spec.ts +630 -0
  262. package/src/__tests__/services/prompt.spec.ts +411 -0
  263. package/src/__tests__/services/screen.spec.ts +721 -0
  264. package/src/__tests__/setup.ts +43 -0
  265. package/src/__tests__/utils/factories.ts +354 -0
  266. package/src/__tests__/utils/filetype.spec.ts +195 -0
  267. package/src/__tests__/utils/format.spec.ts +178 -0
  268. package/src/__tests__/utils/render-utils.tsx +39 -0
  269. package/src/__tests__/utils/test-container.ts +48 -0
  270. package/src/components/file/file_log.tsx +241 -0
  271. package/src/components/file/index.ts +1 -0
  272. package/src/components/filter/filter_bar.tsx +79 -0
  273. package/src/components/filter/index.ts +1 -0
  274. package/src/components/help/help_overlay.tsx +100 -0
  275. package/src/components/help/index.ts +1 -0
  276. package/src/components/index.ts +15 -0
  277. package/src/components/log/index.ts +1 -0
  278. package/src/components/log/log_message.tsx +102 -0
  279. package/src/components/prompt/index.ts +2 -0
  280. package/src/components/prompt/prompt_renderer.tsx +346 -0
  281. package/src/components/screen/group_renderer.tsx +64 -0
  282. package/src/components/screen/index.ts +6 -0
  283. package/src/components/screen/loading_message.tsx +44 -0
  284. package/src/components/screen/message_renderer.tsx +108 -0
  285. package/src/components/screen/progress_message.tsx +60 -0
  286. package/src/components/screen/screen_bridge.tsx +149 -0
  287. package/src/components/screen/table_message.tsx +57 -0
  288. package/src/components/screen_manager_bridge.tsx +245 -0
  289. package/src/components/sidebar/index.ts +3 -0
  290. package/src/components/sidebar/sidebar.tsx +102 -0
  291. package/src/components/sidebar/sidebar_item.tsx +50 -0
  292. package/src/components/sidebar/sidebar_separator.tsx +13 -0
  293. package/src/context/index.ts +1 -0
  294. package/src/context/logger_context.tsx +109 -0
  295. package/src/factories/index.ts +1 -0
  296. package/src/factories/screen.factory.ts +22 -0
  297. package/src/filter/filter_engine.ts +113 -0
  298. package/src/filter/index.ts +1 -0
  299. package/src/hooks/index.ts +1 -0
  300. package/src/hooks/use_theme.ts +12 -0
  301. package/src/index.ts +64 -0
  302. package/src/keyboard/create_bindings.ts +457 -0
  303. package/src/keyboard/index.ts +2 -0
  304. package/src/keyboard/keyboard_manager.ts +233 -0
  305. package/src/overrides/console.logger.override.ts +61 -0
  306. package/src/overrides/index.ts +1 -0
  307. package/src/schemas/index.ts +3 -0
  308. package/src/schemas/logger-options.ts +13 -0
  309. package/src/schemas/prompt-options.ts +9 -0
  310. package/src/schemas/screen-options.ts +14 -0
  311. package/src/services/index.ts +4 -0
  312. package/src/services/logger.ts +369 -0
  313. package/src/services/prompt.ts +169 -0
  314. package/src/services/screen.ts +590 -0
  315. package/src/services/screen_manager.tsx +390 -0
  316. package/src/themes/dark.ts +173 -0
  317. package/src/themes/high-contrast.ts +178 -0
  318. package/src/themes/index.ts +4 -0
  319. package/src/themes/light.ts +172 -0
  320. package/src/themes/utils.ts +83 -0
  321. package/src/tokens/index.ts +3 -0
  322. package/src/tokens/logger.ts +10 -0
  323. package/src/tokens/prompt.ts +10 -0
  324. package/src/tokens/screen.ts +10 -0
  325. package/src/types/file.types.ts +60 -0
  326. package/src/types/filter.types.ts +51 -0
  327. package/src/types/index.ts +22 -0
  328. package/src/types/keyboard.types.ts +93 -0
  329. package/src/types/log.types.ts +61 -0
  330. package/src/types/message.types.ts +120 -0
  331. package/src/types/prompt.types.ts +106 -0
  332. package/src/types/screen.types.ts +124 -0
  333. package/src/types/theme.types.ts +252 -0
  334. package/src/utils/colors/file-colors.ts +9 -0
  335. package/src/utils/colors/helpers.ts +50 -0
  336. package/src/utils/colors/index.ts +20 -0
  337. package/src/utils/colors/log-colors.ts +56 -0
  338. package/src/utils/colors/progress-colors.ts +25 -0
  339. package/src/utils/colors/prompt-colors.ts +30 -0
  340. package/src/utils/colors/sidebar-colors.ts +52 -0
  341. package/src/utils/colors/table-colors.ts +11 -0
  342. package/src/utils/filetype.ts +64 -0
  343. package/src/utils/format.ts +52 -0
  344. package/src/utils/index.ts +11 -0
  345. package/src/utils/stdout-printer.ts +255 -0
  346. package/tsconfig.json +14 -0
  347. package/tsdown.config.mts +34 -0
  348. package/vitest.config.mts +10 -0
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Vitest setup file for commander-tui tests.
3
+ *
4
+ * Mocks @opentui/core and @opentui/react to avoid:
5
+ * - .scm file loading (tree-sitter query files)
6
+ * - WebAssembly loading (tree-sitter parsers)
7
+ */
8
+ import { vi } from 'vitest'
9
+
10
+ // Mock @opentui/core - provides TextAttributes enum and other core types
11
+ vi.mock('@opentui/core', () => ({
12
+ TextAttributes: {
13
+ BOLD: 1,
14
+ DIM: 2,
15
+ ITALIC: 4,
16
+ UNDERLINE: 8,
17
+ BLINK: 16,
18
+ REVERSE: 32,
19
+ HIDDEN: 64,
20
+ STRIKETHROUGH: 128,
21
+ },
22
+ RGBA: class RGBA {
23
+ r: number
24
+ g: number
25
+ b: number
26
+ a: number
27
+ constructor(r = 0, g = 0, b = 0, a = 1) {
28
+ this.r = r
29
+ this.g = g
30
+ this.b = b
31
+ this.a = a
32
+ }
33
+ static fromHex(_hex: string) {
34
+ return new RGBA()
35
+ }
36
+ },
37
+ }))
38
+
39
+ // Mock @opentui/react - provides React component rendering
40
+ vi.mock('@opentui/react', () => ({
41
+ render: vi.fn(),
42
+ unmount: vi.fn(),
43
+ }))
@@ -0,0 +1,354 @@
1
+ import { vi } from 'vitest'
2
+
3
+ import { darkTheme } from '../../themes/index.ts'
4
+
5
+ import type { LogLevel } from '@navios/core'
6
+ import type {
7
+ ChoicePromptData,
8
+ ConfirmPromptData,
9
+ DiffMessageData,
10
+ FileErrorMessageData,
11
+ FileMessageData,
12
+ FilterState,
13
+ GroupMessageData,
14
+ InputPromptData,
15
+ KeyboardContext,
16
+ LoadingMessageData,
17
+ LogMessageData,
18
+ MultiChoicePromptData,
19
+ ProgressMessageData,
20
+ TableMessageData,
21
+ Theme,
22
+ } from '../../types/index.ts'
23
+
24
+ let idCounter = 0
25
+
26
+ function generateId(prefix = 'test'): string {
27
+ return `${prefix}-${++idCounter}`
28
+ }
29
+
30
+ /**
31
+ * Fixed timestamp for snapshot tests.
32
+ * Using a stable date ensures snapshots don't change between runs.
33
+ */
34
+ export const STABLE_TIMESTAMP = new Date('2025-01-01T00:00:00.000Z')
35
+
36
+ // ============================================
37
+ // Message Factories
38
+ // ============================================
39
+
40
+ export function createLogMessage(overrides: Partial<LogMessageData> = {}): LogMessageData {
41
+ return {
42
+ id: generateId('log'),
43
+ type: 'log',
44
+ timestamp: STABLE_TIMESTAMP,
45
+ level: 'log',
46
+ content: 'Test log message',
47
+ ...overrides,
48
+ }
49
+ }
50
+
51
+ export function createFileMessage(overrides: Partial<FileMessageData> = {}): FileMessageData {
52
+ return {
53
+ id: generateId('file'),
54
+ type: 'file',
55
+ timestamp: STABLE_TIMESTAMP,
56
+ filePath: '/test/file.ts',
57
+ content: 'const x = 1;',
58
+ ...overrides,
59
+ }
60
+ }
61
+
62
+ export function createDiffMessage(overrides: Partial<DiffMessageData> = {}): DiffMessageData {
63
+ return {
64
+ id: generateId('diff'),
65
+ type: 'diff',
66
+ timestamp: STABLE_TIMESTAMP,
67
+ filePath: '/test/file.ts',
68
+ diff: '- old\n+ new',
69
+ ...overrides,
70
+ }
71
+ }
72
+
73
+ export function createFileErrorMessage(
74
+ overrides: Partial<FileErrorMessageData> = {},
75
+ ): FileErrorMessageData {
76
+ return {
77
+ id: generateId('fileError'),
78
+ type: 'fileError',
79
+ timestamp: STABLE_TIMESTAMP,
80
+ filePath: '/test/file.ts',
81
+ content: 'const x = 1;',
82
+ errorLines: [1],
83
+ startLine: 1,
84
+ ...overrides,
85
+ }
86
+ }
87
+
88
+ export function createLoadingMessage(
89
+ overrides: Partial<LoadingMessageData> = {},
90
+ ): LoadingMessageData {
91
+ return {
92
+ id: generateId('loading'),
93
+ type: 'loading',
94
+ timestamp: STABLE_TIMESTAMP,
95
+ content: 'Loading...',
96
+ status: 'loading',
97
+ ...overrides,
98
+ }
99
+ }
100
+
101
+ export function createProgressMessage(
102
+ overrides: Partial<ProgressMessageData> = {},
103
+ ): ProgressMessageData {
104
+ return {
105
+ id: generateId('progress'),
106
+ type: 'progress',
107
+ timestamp: STABLE_TIMESTAMP,
108
+ label: 'Processing',
109
+ current: 0,
110
+ total: 100,
111
+ status: 'active',
112
+ ...overrides,
113
+ }
114
+ }
115
+
116
+ export function createGroupMessage(overrides: Partial<GroupMessageData> = {}): GroupMessageData {
117
+ return {
118
+ id: generateId('group'),
119
+ type: 'group',
120
+ timestamp: STABLE_TIMESTAMP,
121
+ label: 'Test Group',
122
+ collapsed: false,
123
+ isEnd: false,
124
+ ...overrides,
125
+ }
126
+ }
127
+
128
+ export function createTableMessage(overrides: Partial<TableMessageData> = {}): TableMessageData {
129
+ return {
130
+ id: generateId('table'),
131
+ type: 'table',
132
+ timestamp: STABLE_TIMESTAMP,
133
+ headers: ['Name', 'Value'],
134
+ rows: [
135
+ ['foo', '1'],
136
+ ['bar', '2'],
137
+ ],
138
+ ...overrides,
139
+ }
140
+ }
141
+
142
+ // ============================================
143
+ // Prompt Factories
144
+ // ============================================
145
+
146
+ export function createChoicePrompt(overrides: Partial<ChoicePromptData> = {}): ChoicePromptData {
147
+ return {
148
+ id: generateId('prompt'),
149
+ type: 'choice',
150
+ timestamp: STABLE_TIMESTAMP,
151
+ question: 'Select an option',
152
+ choices: [
153
+ { label: 'Option A', value: 'a' },
154
+ { label: 'Option B', value: 'b' },
155
+ { label: 'Option C', value: 'c' },
156
+ ],
157
+ defaultChoice: 'a',
158
+ selectedIndex: 0,
159
+ inputMode: false,
160
+ inputValue: '',
161
+ resolved: false,
162
+ ...overrides,
163
+ }
164
+ }
165
+
166
+ export function createConfirmPrompt(overrides: Partial<ConfirmPromptData> = {}): ConfirmPromptData {
167
+ return {
168
+ id: generateId('prompt'),
169
+ type: 'confirm',
170
+ timestamp: STABLE_TIMESTAMP,
171
+ question: 'Are you sure?',
172
+ confirmText: 'Yes',
173
+ cancelText: 'No',
174
+ defaultValue: true,
175
+ selectedValue: true,
176
+ resolved: false,
177
+ ...overrides,
178
+ }
179
+ }
180
+
181
+ export function createInputPrompt(overrides: Partial<InputPromptData> = {}): InputPromptData {
182
+ return {
183
+ id: generateId('prompt'),
184
+ type: 'input',
185
+ timestamp: STABLE_TIMESTAMP,
186
+ question: 'Enter a value',
187
+ placeholder: 'Type here...',
188
+ defaultValue: '',
189
+ value: '',
190
+ resolved: false,
191
+ ...overrides,
192
+ }
193
+ }
194
+
195
+ export function createMultiChoicePrompt(
196
+ overrides: Partial<MultiChoicePromptData> = {},
197
+ ): MultiChoicePromptData {
198
+ return {
199
+ id: generateId('prompt'),
200
+ type: 'multiChoice',
201
+ timestamp: STABLE_TIMESTAMP,
202
+ question: 'Select options',
203
+ choices: [
204
+ { label: 'Option A', value: 'a' },
205
+ { label: 'Option B', value: 'b' },
206
+ { label: 'Option C', value: 'c' },
207
+ ],
208
+ selectedIndices: new Set(),
209
+ focusedIndex: 0,
210
+ minSelect: 0,
211
+ maxSelect: 3,
212
+ resolved: false,
213
+ ...overrides,
214
+ }
215
+ }
216
+
217
+ // ============================================
218
+ // Filter & Keyboard Factories
219
+ // ============================================
220
+
221
+ const ALL_LOG_LEVELS: LogLevel[] = ['verbose', 'debug', 'log', 'warn', 'error', 'fatal']
222
+
223
+ export function createFilterState(overrides: Partial<FilterState> = {}): FilterState {
224
+ return {
225
+ enabledLevels: new Set(ALL_LOG_LEVELS),
226
+ searchQuery: '',
227
+ isVisible: false,
228
+ focusedField: 'search',
229
+ ...overrides,
230
+ }
231
+ }
232
+
233
+ export function createKeyboardContext(overrides: Partial<KeyboardContext> = {}): KeyboardContext {
234
+ return {
235
+ hasPrompt: false,
236
+ inInputMode: false,
237
+ focusArea: 'content',
238
+ isFilterActive: false,
239
+ isHelpVisible: false,
240
+ hasSidebar: true,
241
+ ...overrides,
242
+ }
243
+ }
244
+
245
+ // ============================================
246
+ // Theme Factory
247
+ // ============================================
248
+
249
+ export function createTheme(): Theme {
250
+ return { ...darkTheme }
251
+ }
252
+
253
+ // ============================================
254
+ // Mock Screen Instance
255
+ // ============================================
256
+
257
+ export interface MockScreenInstance {
258
+ getId: ReturnType<typeof vi.fn>
259
+ getName: ReturnType<typeof vi.fn>
260
+ getIcon: ReturnType<typeof vi.fn>
261
+ getBadgeCount: ReturnType<typeof vi.fn>
262
+ setBadgeCount: ReturnType<typeof vi.fn>
263
+ isHidden: ReturnType<typeof vi.fn>
264
+ setHidden: ReturnType<typeof vi.fn>
265
+ show: ReturnType<typeof vi.fn>
266
+ hide: ReturnType<typeof vi.fn>
267
+ getStatus: ReturnType<typeof vi.fn>
268
+ setStatus: ReturnType<typeof vi.fn>
269
+ isComplete: ReturnType<typeof vi.fn>
270
+ hasPrintedToConsole: ReturnType<typeof vi.fn>
271
+ getMessages: ReturnType<typeof vi.fn>
272
+ addMessage: ReturnType<typeof vi.fn>
273
+ updateMessage: ReturnType<typeof vi.fn>
274
+ updateProgressMessage: ReturnType<typeof vi.fn>
275
+ clear: ReturnType<typeof vi.fn>
276
+ _addPrompt: ReturnType<typeof vi.fn>
277
+ getActivePrompt: ReturnType<typeof vi.fn>
278
+ hasActivePrompt: ReturnType<typeof vi.fn>
279
+ updatePromptSelection: ReturnType<typeof vi.fn>
280
+ promptNavigateUp: ReturnType<typeof vi.fn>
281
+ promptNavigateDown: ReturnType<typeof vi.fn>
282
+ promptNavigateLeft: ReturnType<typeof vi.fn>
283
+ promptNavigateRight: ReturnType<typeof vi.fn>
284
+ promptToggleSelection: ReturnType<typeof vi.fn>
285
+ promptEnterInputMode: ReturnType<typeof vi.fn>
286
+ promptExitInputMode: ReturnType<typeof vi.fn>
287
+ isPromptInInputMode: ReturnType<typeof vi.fn>
288
+ promptUpdateInput: ReturnType<typeof vi.fn>
289
+ promptAppendInput: ReturnType<typeof vi.fn>
290
+ promptDeleteLastChar: ReturnType<typeof vi.fn>
291
+ canSubmitPrompt: ReturnType<typeof vi.fn>
292
+ promptSubmit: ReturnType<typeof vi.fn>
293
+ onChange: ReturnType<typeof vi.fn>
294
+ _setManager: ReturnType<typeof vi.fn>
295
+ _setPrintFn: ReturnType<typeof vi.fn>
296
+ _flushToConsole: ReturnType<typeof vi.fn>
297
+ }
298
+
299
+ export function createMockScreenInstance(
300
+ overrides: Partial<MockScreenInstance> = {},
301
+ ): MockScreenInstance {
302
+ const mockScreen: MockScreenInstance = {
303
+ getId: vi.fn(() => 'test-screen-id'),
304
+ getName: vi.fn(() => 'Test Screen'),
305
+ getIcon: vi.fn(() => undefined),
306
+ getBadgeCount: vi.fn(() => 0),
307
+ setBadgeCount: vi.fn().mockReturnThis(),
308
+ isHidden: vi.fn(() => false),
309
+ setHidden: vi.fn().mockReturnThis(),
310
+ show: vi.fn().mockReturnThis(),
311
+ hide: vi.fn().mockReturnThis(),
312
+ getStatus: vi.fn(() => 'pending'),
313
+ setStatus: vi.fn().mockReturnThis(),
314
+ isComplete: vi.fn(() => false),
315
+ hasPrintedToConsole: vi.fn(() => false),
316
+ getMessages: vi.fn(() => []),
317
+ addMessage: vi.fn(),
318
+ updateMessage: vi.fn(),
319
+ updateProgressMessage: vi.fn(),
320
+ clear: vi.fn().mockReturnThis(),
321
+ _addPrompt: vi.fn(() => Promise.resolve('')),
322
+ getActivePrompt: vi.fn(() => null),
323
+ hasActivePrompt: vi.fn(() => false),
324
+ updatePromptSelection: vi.fn(),
325
+ promptNavigateUp: vi.fn(),
326
+ promptNavigateDown: vi.fn(),
327
+ promptNavigateLeft: vi.fn(),
328
+ promptNavigateRight: vi.fn(),
329
+ promptToggleSelection: vi.fn(),
330
+ promptEnterInputMode: vi.fn(() => false),
331
+ promptExitInputMode: vi.fn(),
332
+ isPromptInInputMode: vi.fn(() => false),
333
+ promptUpdateInput: vi.fn(),
334
+ promptAppendInput: vi.fn(),
335
+ promptDeleteLastChar: vi.fn(),
336
+ canSubmitPrompt: vi.fn(() => true),
337
+ promptSubmit: vi.fn(),
338
+ onChange: vi.fn(() => () => {}),
339
+ _setManager: vi.fn(),
340
+ _setPrintFn: vi.fn(),
341
+ _flushToConsole: vi.fn(),
342
+ ...overrides,
343
+ }
344
+
345
+ return mockScreen
346
+ }
347
+
348
+ // ============================================
349
+ // Reset ID Counter (for test isolation)
350
+ // ============================================
351
+
352
+ export function resetIdCounter(): void {
353
+ idCounter = 0
354
+ }
@@ -0,0 +1,195 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { COMMON_FILETYPES, getFileName, resolveFiletype } from '../../utils/filetype.ts'
4
+
5
+ describe('resolveFiletype', () => {
6
+ describe('common extensions', () => {
7
+ it('should resolve TypeScript files', () => {
8
+ expect(resolveFiletype('file.ts')).toBe('typescript')
9
+ expect(resolveFiletype('file.tsx')).toBe('tsx')
10
+ })
11
+
12
+ it('should resolve JavaScript files', () => {
13
+ expect(resolveFiletype('file.js')).toBe('javascript')
14
+ expect(resolveFiletype('file.jsx')).toBe('javascript')
15
+ })
16
+
17
+ it('should resolve Python files', () => {
18
+ expect(resolveFiletype('file.py')).toBe('python')
19
+ })
20
+
21
+ it('should resolve Rust files', () => {
22
+ expect(resolveFiletype('file.rs')).toBe('rust')
23
+ })
24
+
25
+ it('should resolve Go files', () => {
26
+ expect(resolveFiletype('file.go')).toBe('go')
27
+ })
28
+
29
+ it('should resolve JSON files', () => {
30
+ expect(resolveFiletype('file.json')).toBe('json')
31
+ })
32
+
33
+ it('should resolve Markdown files', () => {
34
+ expect(resolveFiletype('file.md')).toBe('markdown')
35
+ })
36
+
37
+ it('should resolve YAML files (both extensions)', () => {
38
+ expect(resolveFiletype('file.yaml')).toBe('yaml')
39
+ expect(resolveFiletype('file.yml')).toBe('yaml')
40
+ })
41
+
42
+ it('should resolve shell scripts', () => {
43
+ expect(resolveFiletype('file.sh')).toBe('bash')
44
+ expect(resolveFiletype('file.bash')).toBe('bash')
45
+ expect(resolveFiletype('file.zsh')).toBe('bash')
46
+ })
47
+
48
+ it('should resolve C/C++ files', () => {
49
+ expect(resolveFiletype('file.c')).toBe('c')
50
+ expect(resolveFiletype('file.h')).toBe('c')
51
+ expect(resolveFiletype('file.cpp')).toBe('cpp')
52
+ expect(resolveFiletype('file.hpp')).toBe('cpp')
53
+ })
54
+
55
+ it('should resolve web files', () => {
56
+ expect(resolveFiletype('file.html')).toBe('html')
57
+ expect(resolveFiletype('file.css')).toBe('css')
58
+ expect(resolveFiletype('file.xml')).toBe('xml')
59
+ })
60
+
61
+ it('should resolve other common languages', () => {
62
+ expect(resolveFiletype('file.java')).toBe('java')
63
+ expect(resolveFiletype('file.rb')).toBe('ruby')
64
+ expect(resolveFiletype('file.php')).toBe('php')
65
+ expect(resolveFiletype('file.swift')).toBe('swift')
66
+ expect(resolveFiletype('file.kt')).toBe('kotlin')
67
+ expect(resolveFiletype('file.scala')).toBe('scala')
68
+ expect(resolveFiletype('file.hs')).toBe('haskell')
69
+ expect(resolveFiletype('file.sql')).toBe('sql')
70
+ expect(resolveFiletype('file.toml')).toBe('toml')
71
+ })
72
+
73
+ it('should resolve frontend framework files', () => {
74
+ expect(resolveFiletype('file.vue')).toBe('vue')
75
+ expect(resolveFiletype('file.svelte')).toBe('svelte')
76
+ expect(resolveFiletype('file.elm')).toBe('elm')
77
+ })
78
+ })
79
+
80
+ describe('edge cases', () => {
81
+ it('should return undefined for unknown extensions', () => {
82
+ expect(resolveFiletype('file.xyz')).toBeUndefined()
83
+ expect(resolveFiletype('file.unknown')).toBeUndefined()
84
+ })
85
+
86
+ it('should return undefined for files without extension', () => {
87
+ expect(resolveFiletype('Makefile')).toBeUndefined()
88
+ expect(resolveFiletype('Dockerfile')).toBeUndefined()
89
+ expect(resolveFiletype('README')).toBeUndefined()
90
+ })
91
+
92
+ it('should handle lowercase extensions (case-insensitive)', () => {
93
+ // The function extracts and lowercases the extension
94
+ expect(resolveFiletype('file.TS')).toBe('typescript')
95
+ expect(resolveFiletype('file.JS')).toBe('javascript')
96
+ expect(resolveFiletype('file.PY')).toBe('python')
97
+ })
98
+
99
+ it('should handle full paths, not just filenames', () => {
100
+ expect(resolveFiletype('/home/user/project/src/index.ts')).toBe('typescript')
101
+ expect(resolveFiletype('C:\\Users\\project\\src\\main.py')).toBe('python')
102
+ expect(resolveFiletype('./relative/path/file.json')).toBe('json')
103
+ })
104
+
105
+ it('should handle files with multiple dots', () => {
106
+ expect(resolveFiletype('file.test.ts')).toBe('typescript')
107
+ expect(resolveFiletype('file.spec.tsx')).toBe('tsx')
108
+ expect(resolveFiletype('app.config.json')).toBe('json')
109
+ })
110
+
111
+ it('should handle hidden files with extensions', () => {
112
+ expect(resolveFiletype('.eslintrc.json')).toBe('json')
113
+ expect(resolveFiletype('.gitignore.bak')).toBeUndefined()
114
+ })
115
+ })
116
+
117
+ describe('COMMON_FILETYPES mapping', () => {
118
+ it('should have all expected extensions mapped', () => {
119
+ const expectedMappings: Record<string, string> = {
120
+ ts: 'typescript',
121
+ tsx: 'tsx',
122
+ js: 'javascript',
123
+ jsx: 'javascript',
124
+ json: 'json',
125
+ md: 'markdown',
126
+ py: 'python',
127
+ rs: 'rust',
128
+ go: 'go',
129
+ }
130
+
131
+ for (const [ext, type] of Object.entries(expectedMappings)) {
132
+ expect(COMMON_FILETYPES[ext]).toBe(type)
133
+ }
134
+ })
135
+ })
136
+ })
137
+
138
+ describe('getFileName', () => {
139
+ describe('Unix paths', () => {
140
+ it('should extract filename from Unix absolute path', () => {
141
+ expect(getFileName('/home/user/project/file.ts')).toBe('file.ts')
142
+ })
143
+
144
+ it('should extract filename from Unix relative path', () => {
145
+ expect(getFileName('./src/utils/helper.ts')).toBe('helper.ts')
146
+ expect(getFileName('../config/settings.json')).toBe('settings.json')
147
+ })
148
+
149
+ it('should handle deep paths', () => {
150
+ expect(getFileName('/a/b/c/d/e/f/file.txt')).toBe('file.txt')
151
+ })
152
+ })
153
+
154
+ describe('Windows paths', () => {
155
+ it('should extract filename from Windows absolute path', () => {
156
+ expect(getFileName('C:\\Users\\project\\file.ts')).toBe('file.ts')
157
+ })
158
+
159
+ it('should extract filename from Windows relative path', () => {
160
+ expect(getFileName('.\\src\\utils\\helper.ts')).toBe('helper.ts')
161
+ })
162
+
163
+ it('should handle mixed separators', () => {
164
+ // This could happen in some edge cases
165
+ expect(getFileName('/path/to\\file.ts')).toBe('file.ts')
166
+ })
167
+ })
168
+
169
+ describe('edge cases', () => {
170
+ it('should return original string if no slashes', () => {
171
+ expect(getFileName('file.ts')).toBe('file.ts')
172
+ expect(getFileName('README.md')).toBe('README.md')
173
+ })
174
+
175
+ it('should handle trailing slashes (returns empty string)', () => {
176
+ // lastIndexOf finds the trailing slash, slice returns empty
177
+ expect(getFileName('/path/to/directory/')).toBe('')
178
+ expect(getFileName('C:\\Users\\folder\\')).toBe('')
179
+ })
180
+
181
+ it('should handle root paths', () => {
182
+ expect(getFileName('/file.ts')).toBe('file.ts')
183
+ })
184
+
185
+ it('should handle files without extensions', () => {
186
+ expect(getFileName('/path/to/Makefile')).toBe('Makefile')
187
+ expect(getFileName('/path/to/Dockerfile')).toBe('Dockerfile')
188
+ })
189
+
190
+ it('should handle hidden files', () => {
191
+ expect(getFileName('/path/to/.gitignore')).toBe('.gitignore')
192
+ expect(getFileName('/path/to/.env')).toBe('.env')
193
+ })
194
+ })
195
+ })