ui.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { z } from "zod"
  2. import { NamedError } from "../util/error"
  3. export namespace UI {
  4. const LOGO = [
  5. `█▀▀█ █▀▀█ █▀▀ █▀▀▄ █▀▀ █▀▀█ █▀▀▄ █▀▀`,
  6. `█░░█ █░░█ █▀▀ █░░█ █░░ █░░█ █░░█ █▀▀`,
  7. `▀▀▀▀ █▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀▀ ▀▀▀ ▀▀▀`,
  8. ]
  9. export const CancelledError = NamedError.create(
  10. "UICancelledError",
  11. z.object({}),
  12. )
  13. export const Style = {
  14. TEXT_HIGHLIGHT: "\x1b[96m",
  15. TEXT_HIGHLIGHT_BOLD: "\x1b[96m\x1b[1m",
  16. TEXT_DIM: "\x1b[90m",
  17. TEXT_DIM_BOLD: "\x1b[90m\x1b[1m",
  18. TEXT_NORMAL: "\x1b[0m",
  19. TEXT_NORMAL_BOLD: "\x1b[1m",
  20. TEXT_WARNING: "\x1b[93m",
  21. TEXT_WARNING_BOLD: "\x1b[93m\x1b[1m",
  22. TEXT_DANGER: "\x1b[91m",
  23. TEXT_DANGER_BOLD: "\x1b[91m\x1b[1m",
  24. TEXT_SUCCESS: "\x1b[92m",
  25. TEXT_SUCCESS_BOLD: "\x1b[92m\x1b[1m",
  26. TEXT_INFO: "\x1b[94m",
  27. TEXT_INFO_BOLD: "\x1b[94m\x1b[1m",
  28. }
  29. export function println(...message: string[]) {
  30. print(...message)
  31. Bun.stderr.write("\n")
  32. }
  33. export function print(...message: string[]) {
  34. blank = false
  35. Bun.stderr.write(message.join(" "))
  36. }
  37. let blank = false
  38. export function empty() {
  39. if (blank) return
  40. println("" + Style.TEXT_NORMAL)
  41. blank = true
  42. }
  43. export function logo() {
  44. empty()
  45. for (const row of LOGO) {
  46. print(" ")
  47. for (let i = 0; i < row.length; i++) {
  48. const color =
  49. i > 18 ? Bun.color("white", "ansi") : Bun.color("gray", "ansi")
  50. const char = row[i]
  51. print(color + char)
  52. }
  53. println()
  54. }
  55. empty()
  56. }
  57. export async function input(prompt: string): Promise<string> {
  58. const readline = require("readline")
  59. const rl = readline.createInterface({
  60. input: process.stdin,
  61. output: process.stdout,
  62. })
  63. return new Promise((resolve) => {
  64. rl.question(prompt, (answer: string) => {
  65. rl.close()
  66. resolve(answer.trim())
  67. })
  68. })
  69. }
  70. }