From 86c0aaefdd4b0b737d115c337b2ed08a1e76c113 Mon Sep 17 00:00:00 2001 From: Nazar Kornienko Date: Fri, 27 Dec 2024 16:01:44 +0100 Subject: [PATCH] improve spinner & task management --- README.md | 287 ++++--- bun.lockb | Bin 303596 -> 317860 bytes cspell.json | 12 + example.png | Bin 61220 -> 0 bytes examples/launcher.ts | 57 +- examples/main.png | Bin 0 -> 75352 bytes examples/{1-main.ts => main.ts} | 0 examples/{4-args-a.ts => other/args-a.ts} | 0 examples/{5-args-b.ts => other/args-b.ts} | 8 +- examples/{2-mono.ts => other/progress.ts} | 66 +- .../select-example.ts => other/select.ts} | 30 +- examples/{3-simple.ts => other/simple.ts} | 24 +- examples/other/spinner.ts | 126 +++ examples/other/task.ts | 155 ++++ .../columns => other/temp}/auto-resize.ts | 0 .../columns => other/temp}/lorem-ipsum.ts | 0 .../temp/resizer-tables.ts} | 0 .../temp}/responsive-table.ts | 0 .../temp}/terminal-columns.ts | 0 .../enquirer.ts => other/temp/wrapper.ts} | 2 +- examples/src/prompts.ts | 12 +- jsr.jsonc | 2 +- package.json | 23 +- publish.ts | 3 +- src/checkbox/index.ts | 2 +- src/confirm/confirm-main.ts | 70 +- src/confirm/index.ts | 2 +- src/core/core.test.ts | 4 +- src/core/create-prompt.ts | 46 +- src/core/errors.ts | 27 +- src/core/make-theme.ts | 3 +- src/editor/index.ts | 3 +- src/expand/index.ts | 2 +- src/flags/main.ts | 56 +- src/flags/mod.ts | 17 +- src/input/index.ts | 2 +- src/input/input-main.ts | 47 +- src/multiselect/multiselect-main.ts | 67 +- src/number/index.ts | 2 +- src/number/number-main.ts | 4 +- src/password/index.ts | 2 +- src/progressbar/ProgressBar.ts | 97 --- src/progressbar/index.ts | 2 - src/prompts/index.ts | 9 +- src/prompts/prompt.ts | 27 + src/rawlist/index.ts | 2 +- src/search/index.ts | 2 +- src/select/index.ts | 2 +- src/select/select-main.ts | 61 +- src/{progressbar => task}/helper.ts | 29 +- src/task/index.ts | 164 +--- src/task/progress.ts | 79 ++ src/task/spinner.ts | 159 ++++ src/task/task.ts | 733 ++++++++++++++++++ src/task/types.ts | 16 + src/toggle/index.ts | 85 +- src/types/index.ts | 44 +- src/utils/component.ts | 2 +- src/utils/messages.ts | 32 +- src/utils/platforms.ts | 2 +- src/utils/prompt-end.ts | 43 + src/utils/prompt-tmp.ts | 8 +- src/utils/prompt-two.ts | 15 +- tsconfig.json | 4 +- 64 files changed, 2060 insertions(+), 720 deletions(-) delete mode 100644 example.png create mode 100644 examples/main.png rename examples/{1-main.ts => main.ts} (100%) rename examples/{4-args-a.ts => other/args-a.ts} (100%) rename examples/{5-args-b.ts => other/args-b.ts} (54%) rename examples/{2-mono.ts => other/progress.ts} (62%) rename examples/{separate/select/select-example.ts => other/select.ts} (66%) rename examples/{3-simple.ts => other/simple.ts} (81%) create mode 100644 examples/other/spinner.ts create mode 100644 examples/other/task.ts rename examples/{separate/columns => other/temp}/auto-resize.ts (100%) rename examples/{separate/columns => other/temp}/lorem-ipsum.ts (100%) rename examples/{separate/resizer/auto-resize.ts => other/temp/resizer-tables.ts} (100%) rename examples/{separate/columns => other/temp}/responsive-table.ts (100%) rename examples/{separate/columns => other/temp}/terminal-columns.ts (100%) rename examples/{separate/fallback/enquirer.ts => other/temp/wrapper.ts} (91%) delete mode 100644 src/progressbar/ProgressBar.ts delete mode 100644 src/progressbar/index.ts rename src/{progressbar => task}/helper.ts (73%) create mode 100644 src/task/progress.ts create mode 100644 src/task/spinner.ts create mode 100644 src/task/task.ts create mode 100644 src/task/types.ts create mode 100644 src/utils/prompt-end.ts diff --git a/README.md b/README.md index 0bd6d13..37d17f2 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,127 @@ # @reliverse/prompts -[**Docs**](.github/DOCS.md) | [**npmjs.com**](https://npmjs.com/package/@reliverse/prompts) | [**GitHub**](https://github.com/reliverse/prompts) | [**Discord**](https://discord.gg/Pb8uKbwpsJ) - -

- - version - - - - downloads - - - -

- -@reliverse/prompts is a powerful library that enables seamless, type-safe, and resilient prompts for command-line applications. Crafted with simplicity and elegance, it provides developers with an intuitive and robust way to build interactive CLIs. - -@reliverse/prompts is a full-featured alternative to @inquirer/prompts (Inquirer.js), enquirer, @clack/prompts, terkelg prompts, cronvel terminal-kit, unjs consola, and similar libraries. - -## Installation - -Install with your preferred package manager: - -```sh -bun add @reliverse/prompts # Replace 'bun' with npm, pnpm, or yarn if desired (deno and jsr support coming soon) +> **The CLI prompt library you didn’t realize you’ve been desperate for.** + +It’s blazing-fast, type-safe, and has built-in crash resilience—so your command-line app can look slick without bursting into flames. Forget boilerplate-heavy setups—this library makes CLI development smooth and effortless. + +## Rapid-Fire Overview + +
+ version + downloads +
+ +- **Docs**: [docs.reliverse.org/reliverse/prompts](https://docs.reliverse.org/reliverse/prompts/) +- **NPM**: [npmjs.com/package/@reliverse/prompts](https://www.npmjs.com/package/@reliverse/prompts) +- **GitHub**: [github.com/reliverse/prompts](https://github.com/reliverse/prompts) +- **Discord**: [discord.gg/3GawfWfAPe](https://discord.gg/3GawfWfAPe) + +## Install in 3.2 Seconds + +```bash +bun add @reliverse/prompts +# Or npm/pnpm/yarn if that’s your style +# (deno with jsr support soon™) ``` -## Screenshot +> **Pro Tip**: Make sure you have [Bun](https://bun.sh), [Node.js](https://nodejs.org), and [Git](https://git-scm.com/downloads) installed. + +## The 3-Second Pitch + +> This thing is **blazing fast**, **type-safe**, and basically a bulletproof vest for your CLI. +> No more spaghetti prompt code. Just shiny, stable, next-gen developer bliss. + +### *“But why not stick with Inquirer or Clack?”* + +1. Better typed validation, bigger ASCII art, more interactive goodies, and next-level color theming. +2. Because you deserve better than “just good enough.” -[![CLI Example](./example.png)](./example.png) +## Key Selling Points -## Key Features +- **TypeScript-first**: So your TypeScript dev heart can flutter in peace. Enjoy IntelliSense and zero guesswork. +- **Flexible Prompt Types**: Text, confirm, select, multiselect, password, number, spinner, toggle, and many more… you do you. +- **Schema-driven Validations**: Easily integrates with TypeBox, Zod, or your own thing. No more “hope it works” solutions. +- **Accessibility**: Terminal-size awareness, WCAG AA color contrast, the whole enchilada. +- **Crash-safe**: Ctrl+C or random cosmic rays? It shrugs them off. -- **Type Safety**: Built with TypeScript, ensuring strong typing to prevent runtime errors. -- **Schema Validation**: Validates user inputs using schemas for enhanced reliability. -- **Flexible Prompt Types**: Supports a range of prompt types, including text, password, number, select, and multiselect. -- **Crash Resilience**: Designed to handle cancellations and errors gracefully, ensuring stability. +## Why @reliverse/prompts? -## Prompt Types +Consider it your brand-new sports car, while your old CLI prompt library was a rusty lawnmower. Also, it’s a feature-packed replacement for Inquirer, Enquirer, Clack, Terkelg, Terminal-Kit, and a bunch more. -Each type has its own validation and display logic. More types are planned for future releases. +[**Go deeper in the docs →**](https://docs.reliverse.org/reliverse/prompts/) -- **Text**: Collects text input. -- **Password**: Hidden input for secure password entries. -- **Number**: Numeric input with optional validation. -- **Confirm**: Simple Yes/No prompt. -- **Select**: Dropdown selection for multiple choices. -- **Multiselect**: Allows users to select multiple items from a list. +### Straight-Up GOAT Features -## Input Validation +- **Full Cross-Platform ESM**: Seamlessly works with the Node.js and Bun environments. +- **Extensible UI**: Because color, typography, animations, and more matter to your terminal fashion sense. +- **Built for DX**: Minimal dependencies, clean API, full validation baked in, and more. +- **Mono Component**: Perfect for rapid prototyping. Or if you’re feeling lazy. -All prompts support custom validation logic, providing immediate feedback to users. +## Speedrun Example + +```ts +import { inputPrompt } from "@reliverse/prompts"; + +await startPrompt({ + clearConsole: true, + titleColor: "inverse", + packageName: "@reliverse/cli", + packageVersion: "1.0.0", + terminalSizeOptions: { + minWidth: 100, + minHeight: 16, + // 🗴 Oops! Terminal width is too small. Expected >100 | Current: 97 + }, +}); + +const username = await inputPrompt({ + id: "username", + title: "Welcome to @reliverse/prompts Demo!", + content: "What's your name?", +}); + +console.log(`Hey there, ${username}!`); +``` -## Contributing +## Task Management -@reliverse/prompts is a work in progress. We welcome feedback and contributions to help make it the best library it can be. Thank you! +The library provides a powerful task management system with built-in verification steps, spinners, and error handling: -Here is how to install the library for development: +- **Spinner and progress bars that actually move**: Progress tracking with current/total counts and status messages +- **Task priorities (because some stuff is more important)**: Critical, high, normal, low +- **Built-in stats, error handling, and cancellation**: Task timing and statistics, built-in error handling and cancellation support +- **Customizable spinners to keep your eyes happy**: Customizable spinners and progress indicators +- **Nested subtasks and task groups**: Group tasks and subtasks for better organization +- **Automatic verification steps with customizable delays** +- **Simple error handling with proper formatting** +- **Progress tracking for long-running operations** +- **Custom validation and business logic support** -```sh +Visit [docs](https://docs.reliverse.org/reliverse/prompts/#task-management) to learn more and see examples. + +## Playground Mode + +```bash git clone https://github.com/reliverse/prompts.git cd prompts bun i +bun dev ``` -## Playground +Check out `examples/launcher.ts` for a smorgasbord of demos (including a quiz). Who says CLIs can’t be fun? -Run `bun dev` to launch the [examples/launcher.ts](./examples/launcher.ts) CLI, which helps you to dive into and explore any of the examples listed below. Experiment with @reliverse/prompts by running examples locally or reviewing the linked code: +## Examples to Copy-Paste -1. **[1-main.ts](./examples/1-main.ts)**: A comprehensive example of a CLI application featuring a well styled UI config. This example showcases all available prompt components, with code organized into separate functions and files for better readability and clarity. -2. **[2-mono.ts](./examples/2-mono.ts)**: A quiz game example inspired by Fireship's video about CLIs. It demonstrates the dynamic capabilities of @reliverse/prompts by using a prompt() that includes all prompt components, so you don't need to import each component separately. -3. **[3-simple.ts](./examples/3-simple.ts)**: A simple example highlighting the core functionalities of @reliverse/prompts. The entire implementation is contained within a single file for easy understanding. -4. **[4-args-a.ts](./examples/4-args-a.ts)**: An example of how to run commands using arguments. -5. **[5-args-b.ts](./examples/5-args-b.ts)**: Another example of how to run commands using arguments. +1. **1-main.ts**: A powerhouse CLI example with all the trimmings, with advanced styling and all prompts. +2. **2-mono.ts**: A single `prompt()` for multiple components—perfect for CLI where performance doesn't matter. +3. **3-simple.ts**: Less code, more speed. +4. **4-args-a.ts** + **5-args-b.ts**: Turn sub-commands into a more headless experience. -## Extendable Configuration +## Custom Config FTW -**Example Configuration:** +You don’t want a one-size-fits-all library. We got you: -```typescript +```ts const basicConfig = { titleColor: "cyanBright", titleTypography: "bold", @@ -101,110 +136,60 @@ const extendedConfig = { const username = await inputPrompt({ id: "username", - title: "We're glad you're testing our library!", - content: "Let's get to know each other!\nWhat's your username?", - schema: schema.properties.username, + title: "Testing out our fancy library!", + content: "What's your username?", ...extendedConfig, }); ``` -## Mono Component +## Mono Component: One Import to Rule Them All -The Mono Component is a special component that includes all other components. It's a great way to get started quickly or to see how all the components work together. - -This component requires providing prompt id. To have typesafety use something like the following: +If you’re lazy (like the rest of us), in a hurry, or just want everything jammed together, the Mono Component wraps up all prompt types in a single import. ```ts export const IDs = { start: "start", username: "username", - dir: "dir", - spinner: "spinner", - password: "password", - age: "age", - lang: "lang", - color: "color", - birthday: "birthday", - features: "features", + // ... }; ``` -## Prompts Library Comparison - -> **Note:** This table contains approximate and placeholder values. More detailed assessments will be provided as libraries continue to evolve. - -The mission of @reliverse/prompts is to achieve the 🟢 in all categories. - -**Icon Legend:** - -- 🟡: Not yet verified -- 🟢: Fully supported -- 🔵: Partially supported -- 🔴: Not supported - -| **Feature** | **@reliverse/prompts** | **@inquirer/prompts** | **@enquirer/enquirer** | **@clack/prompts** | **@terkelg/prompts** | **@cronvel/terminal-kit** | **@unjs/citty** | **@unjs/consola** | **@chjj/blessed** | -| -------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | ---------------------- | ------------------ | -------------------- | ------------------------- | --------------- | ------------------ | ----------------- | -| - Full ES Modules Support | 🟢 Native ES module package | 🟢 | 🟡 | 🟡 | 🔴 CJS-only | 🔴 CJS-only | 🟢 | 🟢 | 🟡 | -| - Works both in node, bun, and deno environments | 🔵 node+bun (deno support is coming soon) | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🔵 | 🔵 | 🟡 | -| - Codebase typesafety with intellisense | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Runtime typesafety with schema validation | 🟢 TypeBox & Custom | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Usage Examples | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Customization | 🟢 Colors, typography, variants, borders, and more | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Custom Validation | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Error Handling | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Ease of Setup | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Crash Resilience | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - General DX | 🔵 Clean and understandable TypeScript code | 🟡 | 🟡 | 🟡 | 🔴 JS-only | 🔴 JS-only | 🟡 | 🟡 | 🟡 | -| - DX: Classes | 🟢 Minimal number of classes as possible | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Documentation | 🔵 | 🟡 | 🟡 | 🟡 | 🔵 | 🟢 | 🟡 | 🟡 | 🟢 | -| - Extendable APIs | 🟢 Works well with @reliverse/relinka | 🟢 Huge number of community prompts | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Designed With UX/DX in Mind | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - All components support Ctrl+C | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - As minimal number of dependencies as possible | 🔵 | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| -------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | ---------------------- | ------------------ | -------------------- | ------------------------- | --------------- | ------------------ | ----------------- | -| **Components** | | | | | | | | | | -| -------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | ---------------------- | ------------------ | -------------------- | ------------------------- | --------------- | ------------------ | ----------------- | -| - Visual Components | 🟢 Animated Text (incl. 6 anims) & ASCII Art (incl. 290 fonts) | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Mono Component | 🟢 Mono (All-In-One) & Separate | 🟡 | 🟡 | 🟡 | 🔵 Mono-only | 🟡 | 🟡 | 🟡 | 🟡 | -| - Start Component | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Text Component | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Password Component | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Number Component | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Confirm Component | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Select Component | 🔵 Native separator support | 🔵 Separator supported via `new` keyword | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Multiselect Component | 🔵 Native separator support | 🔵 Separator supported via `new` keyword | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Search/Autocomplete Component | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | -| - Task/Spinner & Progressbar Components | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | 🟡 | -| - Image Component | 🔴 Planned | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | 🟡 | -| - Range Component | 🔵 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | 🟡 | -| -------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | ---------------------- | ------------------ | -------------------- | ------------------------- | --------------- | ------------------ | ----------------- | -| **Arguments Support** | | | | | | | | | | -| -------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | ---------------------- | ------------------ | -------------------- | ------------------------- | --------------- | ------------------ | ----------------- | -| - Fast and lightweight argument parser | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | -| - Smart value parsing with typecast | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | -| - Boolean shortcuts and unknown flag handling | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | -| - Nested sub-commands | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | -| - Lazy and Async commands | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | -| - Pluggable and composable API | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | -| - Auto generated usage and help | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | - -**Related Links**: [@reliverse/relinka](https://github.com/reliverse/relinka#readme), [ESM/CJS](https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm), ["Pure ESM package"](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c), [Clean code](https://github.com/ryanmcdermott/clean-code-javascript#readme), ["UX patterns for CLI tools"](https://lucasfcosta.com/2022/06/01/ux-patterns-cli-tools.html), [DX (Developer Experience)](https://github.blog/enterprise-software/collaboration/developer-experience-what-is-it-and-why-should-you-care), [TypeBox](https://github.com/sinclairzx81/typebox#readme), ["ANSI Escape Sequences"](https://gist.github.com/ConnerWill/d4b6c776b509add763e17f9f113fd25b), [@chjj/blessed](https://github.com/chjj/blessed#readme), [Wrapping](https://github.com/SBoudrias/Inquirer.js/pull/255), [Visual Control](https://stackoverflow.com/questions/68344362/how-do-i-get-full-visual-control-of-a-terminal-with-node) - -## Wrap-Up - -@reliverse/prompts is a versatile library designed to accelerate CLI development by providing customizable prompt components. Integrated into the [Reliverse CLI](https://github.com/blefnk/reliverse#readme), @reliverse/prompts enables you to create a unique design aligned with your CLI app’s aesthetics, similar to how @shadcn/ui supports customizable web UI components. Quickly get started by copying configurations from the [Reliverse Docs](https://docs.reliverse.org/prompts) and using components that fit your project, making it faster to bring your CLI app to life. You’re free to customize each component as desired, with default designs provided to ensure an attractive interface from the start. - -## Learn More - -- [Temporary @reliverse/prompts Docs](.github/DOCS.md) -- [Reliverse Docs](https://docs.reliverse.org) +## Comparison Table -## Special Thanks +We’re not shy. We lined up **@reliverse/prompts** against Inquirer, Clack, Terminal-Kit, etc. Our goal? **Turn every feature dot green**. [**Check out the epic chart**](https://docs.reliverse.org/reliverse/prompts/#prompts-library-comparison) + +## Arguments Support + +You can’t build an amazing CLI without argument parsing. We’ve got a built-in fast parser that typecasts your things automatically. + +## Wrap It Up + +@reliverse/prompts is more than just pretty and fast prompts—it’s a full-blown CLI builder with customizable designs and robust typing. It’s built to slot seamlessly into Reliverse’s ecosystem, but even if you’re rolling your own thing, you’ll appreciate the minimal boilerplate and fancy visuals. -This project wouldn’t exist without the amazing work of the huge number of contributors to the list of projects below. Many of the @reliverse/prompts prompts are based on the incredible work of: +- **CLI builder** with style & resilience +- **Customizable** design and color theming +- **Zero guesswork** with TypeScript integrations +- **Minimal boilerplate** with maximum results -[@inquirer/prompts](https://github.com/SBoudrias/Inquirer.js#readme) | [terkelg/prompts](https://github.com/terkelg/prompts#readme) | [@clack/prompts](https://github.com/bombshell-dev/clack#readme) | [create-t3-app](https://github.com/t3-oss/create-t3-app#readme) | [create-astro](https://github.com/withastro/astro/tree/main/packages/create-astro#readme) | [cronvel/terminal-kit](https://github.com/cronvel/terminal-kit#readme) | [unjs/consola](https://github.com/unjs/consola#readme) | [nodejs/string_decoder](https://github.com/nodejs/string_decoder) | [TooTallNate/keypress](https://github.com/TooTallNate/keypress) | [derhuerst](https://github.com/derhuerst) +## Special Thanks + +**@inquirer/prompts**, **@terkelg/prompts**, **@clack/prompts**, **@unjs/citty**, and all the open-source legends. You built the shoulders we stand on. ## License -[MIT](./LICENSE.md) © [Nazarii Korniienko](https://github.com/blefnk) +**MIT** © [Nazarii Korniienko](https://github.com/reliverse/prompts) + +> **Stop reading. Start coding.** +> If you’re serious about CLIs—don’t just build—**Reliverse it** with `@reliverse/prompts`. + +## More Goodies + +- [**Reliverse Docs**](https://docs.reliverse.org/reliverse/prompts/) + +## Screenshot Brag + +[![CLI Example](./examples/1.png)](./examples/1.png) + +**That’s it.** Now go forth and build unstoppable CLIs with `@reliverse/prompts`. And remember: + +> **Don’t just build a CLI. Reliverse it.** diff --git a/bun.lockb b/bun.lockb index e81d63927b5153c1190c24d58c650563231c4871..4d0b7f1eb315395d56a75be8d202a773b2424832 100644 GIT binary patch delta 67588 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 delta 59240 zcmeFa3z$}8-~NB!_jK3XlhmZN(|#Y*zGiCbZoiw9rhT-VYHFrtrkZI|$P}U`VJx`{ zAw;1_QXzz>2q6mXc%l$O6ypCm*Sgl2_xXFC_kDlw`#*li|2W)7=bYE~y!PK~v#zyf z?$tvZFZlYEinldy`hANEFZY=J+T7U3uDz+?p%**-^!eqp%g>ls#wlEXdH%%t(b20) z1@tLhG@^Dv&bg3lct0uz0`o752?QeWmqf(D4`YiDVV?&llDiUo30xK)N4z-Ra(dXy zKP@w7Qo{7ffkW0F4won0l+uAfIrvSuVgZ4Sw7lt8<^%#`%Xksb5OE=TkOC{fKT@$W zE?5=krO!^!nUxWkNvqYsyovc)>GbC%;?SR(a15 zU!b1NNSl?R4AXPdTsQ2aRJC+BtO~9qp?W+qBQ0whDSZ2RBF{$;6R(P&!d7{|P`dQ# zIq9=9v(p3DVaU#zJ0n{aEN;!1*fFuHbRPM^xSmjK*$Oi)x84N!%8qAH*I2iULeqr=Bh!{V0qG? zW7+AsQ_@=p0%J(8hGpg@sLsHB7kTLipvz+oY6b#yc7A7TUxTd%m#IYuGzTZA<;|K& z%W~86^D-yT4SYcltJ~x&+@f(Z3D5@(7e2i z8PfuRz{YxBg^$AOSo*|?2~+bXqzH@ zUjB2~>gY(y*BtI|`KCr*y0odYRZ5_C<3NDE&MymV>i$N&+L@o5Nxgxin~9w;X+j_tT^&lxo0~InTIQ@jYCCbI zqXjpRO#M%VwW&|rEUF=6}4H4UK!sM*9DgHkG zd`GXLWs|-9{_gfGn}F-VtjvVG%&XE5V^<)*T^g=@;eXAwj-9;RZ%voB)f!H2_06X9O2fKR}o`x^LPU`8oIxmyWl)d^Gx_bH{ERU^+HI!M?^Ji!X zcUgTYtcK6Z?3*(;Z^qofb2fsOW|A(T$uc`FD=;ZNeMUn1%&g~odl}Zj^4M})zzwj* zI@;HHInumfQ$Mf1oV1+jnYcJTZ$f@%)}%o4rQY`35Y}8RZ~1J0&;HEvTd?~1EG)-A zZ25M}*IJ%xdAQ~79v94SZiO1K929H$bc$zxYWW>ltNjJbk6XUW@*>N*)3dVjX9NNX z!vXTrI$2dXNBH_51>u9dQ0QxDK3b?V2|Jmmz^bef0fs zJ$Nh3PBZ^5%h$jvXFRM5yIH-Vwc}uI`xDb9YP-a#RE}Wj`)ieZ_OZvcCt`AJG`%2!#w5+sA>C3P+mlnX4;Cxu=qNLXp zn46ZBm6S6Y@Npvhw+_8)-uiQYk*T9K+UW=w?&dLlp zC(kQe;7>1q8v66upKkuVu9f5Y*q^5UH1y}Yzh3-#@2?|&{rJ<`Uk`Tr7R>h-hQGl4 zdG9YUyI|(~3(sFS{=BD4TEl@h`CbF-&G9xQzsnb5%Qbnkr%adY7SHv@rT~r$^bE|e zbd@)_6Q)nknvj;4K52S({;bTbyf}3Eejlu{dEGMSV!X$|=H(?^nUOYY_FSjq`OOQO zP@X2+xhuW7@dd06B<)&n5^sW4%%j%cYvW&}-I^<#ur>GYhc$<8f;Gp|;d<}@SQ~8% zxE5Rq)?)dQ!$}=ooj)d^46ndSxE@wPcUpVm^sMQ*>~z;)S4Yo;FMx-@7s3-4dj0KS z;~T)rA7}0FX{gHm1XlVtVJ(J@@OhfdD{VwGSgU0;lTV&MvdEkL`(Q0+|H$l4LPjKG z`t)gO6SC5;XA-MH_6R*c8(S3(hSgIpxYM&{rw7g~@mA|Mum&E*Ah_0`Ie_B z0=tVXxCvYZd*Cfz!+OC=UkP19_aLiD%RN0WD>H{xG_S~30IR22>9cb*g+8$QE0*`b z1uDqB24&_2auBrM(_!iFIG)}14zIvQuo^asczLKT+z@UGmxcYK_hjAfv8gBA>FM<> z&q&CcJ~3?;7rZP^G_wNr4E|TfY82p(iSa7p3^Hq0`lJAdso84zxaD3!>3QxH=c>oi zJ9loN(h4tqdftrObT+}#l%t`z6iYM1{64ngjm^-D#%Szr!ma?%Sm{+bH7{XqT6R_-EqBU{v|JV=x;%8(y&f-xRc@2} zyoUHY>eU4lq=ZvoRaF0eZ}twv)~aX;t6~1w`VH`V`oyi?)$dMN>03PLT@~j%;7ztF z*qZ&9VXK~h9@+v!L>(fofNR3nQjjwA#+D0b<;|hbfx!5Oy#gMGE1>`L!NcEZ{SDRM zK>hvE-v|Bu(QeoU|J@VF|MCH(Q(*oQmXBujb+CGzo0c0Z335LtG+8IUYR**Rz?9Q$jNE>S+nvcW^unj z1wBZh?P5kkcADFwXS`KB9@ZQj2CIRy>7*+5Z)?&wd%AynP|ovC3bbpRGqrN> zj(!vTlKrOmHTX^V=NqKLZO)gKYZVNjBDpLX)-v~pq!D&y>`GQIWz&6u*OYEQTpphH zs>g3&%VV_H-C$F8c=kis7oxMPxI033?-VB`s3^8)20G;5-na6Ho+sAB>e(t-F5f~r?N?`EReYAQ zX$2p{)@pj(#=i?|$A1-8`3>O$wd9-Ey#jCl*lXEhID+2)6R+SRSav)aRA8-xUIC}~ zc@-Xl)x#Iz+VIVXJP-Mokcktg=j&p78AGXtZa?gm(~kPxv29F*+vB5N0~*6}@%gY^ z`_mDxfrl)=4y(cq@P+W*mYJCD9O(TIPu~G6zki1I?+zyGqRIN-^bh>6$#tL2kO-H@ zX4jd$4oO<&^v7ZmR zDrUg26`P$i4Q{KDvgwZ_hejV6c6?1?`42uQJ;Pbla7}FGe#eHFyS>3@8(TIyUV3B8 zgrwlc8O@gmH&$rbHx&EbtMg{u^WmHCZ5-LUWiZkZr*)*W5od4v#L(0jC#7vP@+4v> z#L`Y`+r-eDaCq~2T$^-&KodJo-pZnq~J(zDP3PqL@Qg?$+QDS2FeXQ=TeqmX!$3Z9cnxs+~t(`q2zkyJ5lE*rG+a*T+ zfz=x;;H0)sj5K5NsU4-=HfEeB??kpBwnhv)@nrZCYYq zOpLsMC69-l)Xbz8YyDEs9h@xM?QX4|fUaGAZ?-hpC zJ~4bH)>vmx`{c+zLP>6_RC-vBZ9;ime}?*1bPD@LBiAF!Gj7(%b}acY=ob4emby)q z9TG#6E^rD{qM@fRaCSp+m7KW#(a@wyP73s3C8w}|G@?ytu$w);OJZa&mL^7w6Q7tE zS%sDC72P2*@(GqVYl}K11ut}Gaz0zya8iU_=e>cY$~{+J$hN0uGUiOAp;esS1EP@| z5jDo{OpffwQU=;SATiR0D~0WBzr@h=s!rTx(a2MX?MQOIW>lmuTcp~@6v2lRv07t! z1Gx-K!{fFk^ma8TZcsE5Q{5Bk(4fRnZgr;+akCXePEnu4$SJJ0XR56UCT)s8jakFs0#3HG%>OR%UcIp z6_wePRUIyFlNh?awv#d}8roUgDI6A!JX9wT7)Tr*qnY1hX)wI?lT_EQsAy1P_-3r0 z?u>j#A-68(ZD?9OCvHSE@?t%|i405Vk9tlaV#oU4+zq%+$i-4G=r(mdh1C*^IGpfl zeW!3_G+ea-UQ;EZ;SHR)QPI$?4V)C{#Rg6x6x-0*Jt`XR*N_fr%ZV%`Smmy?$$64vzBV#Y|7Kj@cxecqQTSNRiNwFB0dIlxe zNpRvOL?goziakon4wm&cB_B<2c29_g>#^5#a_7ZZLMjf2k4_9ffYs97>)$1$xk*R5 zCPrdg1Ogqf%4&NGkHqTgEWM^vu!U1NDH{0@Tb*{VgpnHb!&_2pUXjbNG&^ZL^X|Tu zPGLG35VZ!q4Kcoz6E`^;zPuGRI!nhTM{XnJjgv<0JuHnorPH1AY!$M+x!)g4lc$tg zA6bkw6f4HvWe#HTPdf<{E4_`kX1wioBUX3f*gM)L#bU@qrJSO@NwG9tb+hism5rq+ zH&v>Do zAgtkTN?olUR-8KrzP72n{kRDOtp>PF4d-GF(wQOhG9j-EMWYfUA*$58;Tp~rr#BXb zc-@X%izNp!4otaS9i5aJ(MaWFuPN?Ci=<+ynfQrD7uh(5gZ+I^vXe418YxY~`;vr7 z!bpt5QVlqXz4d-9wS^($gz_#{Z)d=;N zG&89bMtj!_cM!5QL=(erVzKray7So5F=$8p?4(!>YLj#5+KpYDlzgT$Vyc^heLUQi ze)V<-{YFAwD;di07A%_6HaYSeA=Ts_+#+qedF8W5wMz`=VsYBq-6@uUYNFb##PD}m z1DvHCE&4FMn1FHwm%Rx+IJ6a8k7IdFl~=#S8tBGRaHJcf#kgpnV_sd2RXoU%4Oq0v zmU#-x>!WH&=v6#Bv8G_DON<+(tibv+xx6Wi$fKe z$6hIy6QaXvOL6G);?N~bPcJr?P)|4AGsU4_ibK)Ce(ZIAD70^|ld>=xP8k*mT;U8@ zm>gbBXp|fJozO5hG-S9RyPnVxR|}5d4?f(`SVEa@=ygJAZm7vfUn?TyrTd1^6gPI* zD1LqFhMpxf&J9(&+z-tmOG+r~L5H%CM7k8=udj)p%P&l4Z%;p@|MH=xi_LcN_mOOiv4Cpd*mqv0(RbStNw zsq#dx5$--18ZgmGxg{F9ZK6{M9i8axz9kxIGRbQ-SG>HWSPZY3>_3s!Selikbp#F{ zz#8u?y*W8NEIkmo+^zZvLfrD*oE-W#-HGcQjdYsqmFDg};n`T--Ig7n?CicR8W}jn z+fUr}9a=ucNhyj(en!-?b9dtK;0%_s@0^lWGMozZaH9Cr`DGdVnm5MxT{1wwt@Q0eJ@YziSyyPeRb zZtNjKUXBJc{B#+FymU_z^3wfQto59!{Y7=$PRN!*$d;1p=glI-m4$Rq7Hek+c{zIK z`8f&+rMT(dC*;+8(JVh*1|i!PLT-7H9|>u?c}Jao`QG`;vpUXU1-NnXY{s`^vGV0} ztm9Z3fih0~l}WL4y#aIY-XeEmB@x9f1iSWISh_ASxv^?qhJnJ~FiU z8mDj-yFX$}MB2r1o&yo?>N0vaobn zrulk;fTb3bkGL`gUYys)URXojQc{Uqfu&0j#}@K^jK$_+Ye=5&-SK<%EyeO`SAAb# zF~M!hAq)I*QYnvNO)8Ene;s>Nv6YR*BDVSVVg1>o7T5cw=w9_Etif(d)pwvcPBpZ; z!C!BwGdOo+jV>;8I~JEVYEUWV7y7;3%fTC?Q*qQcjpx^a;c_gFOYErNC|_YOGJ zZn0DNSTvNk*x60orp5j>LA%c}EX^HG!D&q2LN6bahI^^&u)4eFz*h-r&ts3G85Ndr zRl+K-85>%=#3@`C4Oh825SYwd?-WZwZeXv?Obl(k*-2R+4gZeFWaadiwA5Q6Y=!KP zxl5h6CwLNxsP=mIUq4}8hINr!+ss?MmFVr=8?fA`eUYyS$u;iXQK-$WPT`Z$(66^T zyP=zkoVX3q@OMS-hR`87lytkEphYrn_u9r0a$ZubHQa(jM{ajgo{C1QJKlZ~(4jRl z2utnafX3Rq6RRVZcWF87I4K*Wk?0+Mk*QxM#bWey)9*du8eK71CMk*G--*g~Z%k(_ z^A?O(#d>RbuKgNI+m*LqlJ4}EmS)XtYq?J%BTr*_1E;vJvD&*$(=L=?{2Ef9NQ%Xf zpLn=Q!fjX@9qzRl$+K8qHXchwS}gZw265cAPQ~)pyi%^gQc89ytV7nqbv$yYwZbdY zdm4H#u8m#ncW8_pDmfD2Hs2;{r&%C?O%J=$vsd_yCOGC)UPs)d_MPIn`e~#rnRc>{k zKQH8Nj6|}WuSB5-?sHOJ;7ot4f0APn1Mce-e8h=+H5yKSgf=_nUQG@!CUmJA+E*N^yT;eDi$hzBL*cc$;4ANCg!;N6 zQye;69BTZiA3MD`w7EF+M{%gnV}80@3HA2cQXH!BxUZ!ZhaMr+(@pnPaj3;QU&|{F zZT3TvUlsEG80oU!^AuYSCxW?Ht(^f&lEYgGaT~)gL(Z*tQr?J$Mm^yaLU%sl?0zE} z+53d|goI6ELSpE=C!Lfxqmk}UdXtmK94zHUSZ&=g(AoKUEcanZsNx1E?yYF(t_@BK zba;bP_*OJh=P7SZd5`C2Jmti_9gW*ZBTVU$G1lVuN2D}Z zNu=}^!rQW(azm0MWu9i5dnF8I^ThH>r{|FyvAoLyC4^sAoVy#IA*8aHNnGz*Zt_mg zo^>sjHUcbaeaptVwMNQ6wl+D{mT5k2SdAn{d zmO9Tu<38gxtjpZ3tn#y-i@fVze=K#^YsTGJW4-dIIQBWOyWWN2a;(-~c`qbJmSeTY z;{3-I{Vf~k{T?CkyuX8K7`tLMcT;MJuPwIrVm*$fGTj|Md(&- zwU{mz5lO zgHW=|cWdPN?xtPdG-WuG zl43EYx>@9&5xc#^t9uEFyo5ElIIiLwfxs-!!daWJM!FWOGE(kMuL3XML@YZeNNKF) zojl&a^6JyTwc8U2OeikXVC5EDJ>M$+#R@IEAM4L{#=Y&`C(wm%NwF9?UN#aYzT+)B zuPKjW6?Y;08`kCSf%t-ViwobM6pJywxPZ6+gVo}_l092kY!#&@#bVgTQ*Y<@y(V#_ zVvE>}b*WoZ%)UTiPI0HM#_EaXjl{?ge0T4qgoYpbi$}9)6jonSdMo2KEVN}#DC&%q|Bnwh)YII09BTG+oiX|`>nadu13m^81vbzPArkOj^;l)@<&VaG} z>YI?(CV7eyLl+)#3V(=3#vkz)U;Ku|@VKMy6S^Ne#S$1sTGspqrtzo#V{}<#v2+{b z#jX1f)^AvLp^~!SXWk~^rM#o075e%!C+??cc=SK`(>tf!Psx!(gf6F8_c9$yI_B*D zDH^&G>cVfSk9l3HaQmN0~vkkuvn57Uhk2Yo`#bU?_95(S{jW7Jo zm9YzDe&H0JiAFXeY9FO_oEg8x>Wam{v2(RJUUFwxh!rKyyXYOj>VbuSHzr2`LD1F9%s{+WL1=Ab+OV-u=f9(C%S)-6_{od zh*dzgwf`%u3fP0)d^2F#JSTKN;?hp%KdKazB6O`M{##aVIYsHO2eNMf`uume4C$8u z^=7H>X9Di0B&&j3tS**)tF^^pa0gI9cLK#5%gbSXO0v@31;qCNeeSX2>TxBrCm5{KRLS4BvREsJOPBtZGH?Va{wN5T&Y@rxb7?48r$8FJm^<3+3vQm1 zus;8e)rD`}R32-#{9x_BV%77bjW59kZlg}y2(b$O87RXUppRJgSs8r9>fCQK`23%< zCb}&^6`XUezh*V;4?gmJL6vNl4j;Ca>-E93cA zFK_jdEU5xNG~Cr}d`Xs6-ReFU_yMsRQWI91S~j6r!P?gTD^^q;8~^WE9jHe-aRV=X zb2p&L)5I1aR?wZzmesIJq?>aw!7AMp-9kV9i6ynPx>(uTz^bpE)x~AZ(o(_3=J8U& z*njy$e<&O1YBP7Y+!N+spqGAFRi-p1`uR4!SiuEByD%1Dorkd0CJ?JZw^_R+S3!To z>i=VQH>Us10{;sQt4w{*+jIqf;QtaA6u0ER(tv8Td><{>HTM(S1F`1NA#48?mnZ%t z@tOnQ+jJf?{t9SP{RC^w&)Nk4j+NvWo313QoZr#aApKB7%fKo(&J{gYL&{@^H2?G+ zd40r6SjpOA)lu2nV#QarwphXH))p&xk+n;*q*_)NtK8bKdt9n-BT8~S3EEm+tYCY~ zNmeh(Rf!*D_5TKY>+ipjfolGbD*6}s?D{X+0J(SwJ*f@n+8)ocJR4U0Tv%f}AJ#{# zFSo#+%=~kdjW|id!VI_Fj+G{L7YFTfG;a_0Apxu_=u>2;>zrb7kPz8Ho74U(z55UUz5v-3`Lvz&HC0Xe{wYtZQ zzXEFU=QcvDicY{fLVs)R?`?cZR)IfQ{jXS2r}+^J>(xd||GP~ucCSBw5KxawQEPp; zF|3Lc)C$YW(*j!sw6yxaW2I|FI^}C))BhE_^S@+-GPboD+uMv{>4}z;EO)T+V#Rla zRbeNqi=}tAc1e~Vjj^{Y1YDPQvkApY&>dERJ+0l##{WB3`aU*YNmhA%tuEH_F*U}n z|5OAe7;F=WRnSmtixof2+9g@~aCAkDvhgKZVuGTvi* z`j+jOSi!y4F3CE72Hv$1|BfqCz&}VQ7ap_e#j-!Q_P=AL`@*Ix$?o<4gpCkuEWd)4 z;cLq$ZM;~)@2q|bR{9?#{tMRJ`oqSTWaSIuE_ePbpwGW!Wr(rq#A;wEYl{_(wYFH3 zI38BM3#?v}%c0jP#p609sAm)W6>IBkM!aTsOIQ`R5}Pp~wY<*q23X}j4XXj0V12|2 zZsmve%V94O(Ae*iYFQcI#8%JVf>prVHeRgYdsctn@;=KSz#&t!a9qA!up8i81IM2sy+r$daUJgu(HHU{3lj3FR*$EE^r-M!$$m1SdOYkIpU_ay#Ji- zrBMkrvaM`Jv0B{5ayzSw)$=54mt;+uD7qTZ%f|l|D}P^GPX7X%us^I3ywutySs5;~ z@q;X<+I0Vl$>KhU9{?-=zj_$2w>!C?zhZgdfABQkE%!fp7+;`YO1YnsEKiKHdP!D; z(yT64x(U|)E7qFPLwJ3}%AYNRkH=m7z+bZ}`1@(R>#ybfl>h#I8jlmSr2c*yj}!j& z(|WtJDuGtf-%sQJej4vRq1WBu-%sOtEdTe@cqRg$|H?!0|HX8FKaKaE!po(9KaDT> zP+T7Q|K7G2#*!6jNBsL~{NGRG|9%?(_tW^lpT_@hJ}lRk{!iuo{WP9m`{|0q=kKTS ze?N`)?$7^z8vpmxcz)5Nhv5H{r|{ZTl>h&qPviA;U7!E8r}5@&%it_ivvsh)+0rUl z&g2sc#+dD`gCk5vYlMbv5W;3=8-%KD5cWwZW9qg=*ePLQTZD+&D`8Gsgm&!^%9;i3 z5Sp|@I3}T-Y1JNKzl3G&5z3pR5*D>b=#_{NZ;BETk`fVkzefMy1*TsIgyRy{bwH?W z)^r+Of)>4-3_CqhlLswcw8WQ2q+ z2(``HUI?+BR7P)vx+c;GVT*+9J_z;ARtXuM5o-2DXlOF~B2n=k`HfJTQ>4h+6 z5JG3Ob`ZkI-U#JV5xSUBsR*%s5VlF^W+H^TUM6!0Le+i< zdnEKR)rKPMlrV27LO-)h!kiR@gkcE%&D>!KO*Apu4M!MY77Rz&FX5Pk%S@{g2#YR7 zST+J7)ns-?NE(1}Qo<0^VI;zF2`fh;3^OMrEFXw4U=+d#vtkrK`d)@`PQobD?{b7Q z64qUgaD_Q5Va*_fF;^grF>9|t7@3MtZZyI;Gio$K>|lg#64Fd$48j%(*<%nUnynHt zh9J}&i;!+I$0Af6im*q*6jN;+!cGbE#vx>yT@vODLr55pFwM*zkI-Z|!a)hyrfC|& zehEv{5T=_05*Cd>=sW>ordd1zA!#JSNeOwT!$gGR5>`$`$Tue>EFXn1U=qTWX2m3g zzLz7MlQ7rxOGh{(VO=`H)#j{(HCG^vnT#;cteuQ7ax_A@DF_8-)D(o+F$mivEHIG_ zge?-XGZ3yfTP0+SMW~sHu+U^?B2*oRut&m8rrK15of76vMObWhNtiPpAz>QA5;J!i zLX$LvgA$gSrdbI4B`nQCxYZnxuxJ88=WK)`vp5?eX(GZ&36ANIgK%8J${d7c=7fah zlMn_>M=)l^bcDX?2M^*pT@*yAt6E(`pXFqHKg^a}YL|qY{#G5PHo;*l3F8 zA{>`+TEZsN?J9)j(-Br*g|OM2lF)Ys!mz6mwwhH}Bb<>Cz6RkrlX?xpnwbcjBy2Om zc?ctO5z^-&yl6H^h|NQ&d@aIulXfk_7705fykg=D5He;V>?uIlVRp?&sG5(EumIt8 zGj{>PP6-Dk>@rQSLzpugVd-@UZ=?==-fO$&F87Y0ObCftFt<|dRKQqBcT#bqcX z7op@YL-`|MUX~KO7^UHzxH)KM-ie#HNZ2PK#?&l zTtf7*xqiV!@{bhryDXNpAUn-ik)rrX_61+zjFZ%&CSntt~{ z7noI|O6IJnvPoSDU1-*ds+i!tP*pQZRLyJdqs^*(+8o(W`U@QIUs6kT0I0cGmAwR zo1>yjOo!D_f+-R;Hz!0bOt*)jmS%;hl{qD9ZTdX|wK1ziZOvIxJCnKwYH!wx5>0R| zlw?MUI+zWjjwbRblx)&Ooy=A!)H!H&M}xzIQ4{|dY8R6!>T0%&x|wQ^L*30xQ4h0A z)YH^m2lX;@MZL{lQ6JNEy+(2s-dMUGZ}c+<5P~VD)e}&EvsiSgIVu`pIy?ytG)1Dz z%n2woC}?tNNGLUEuIfUA2Agghh#g{9h=!U|qG6`rQ_yg;N;JZp6^%5h8=+BVt>|(S zd>XpKjDpOXH8g13(==#|iEKg`xfUUN6T&#NRYL5e2sNKUNHdwwAZ(GaN5Vu?Z8Ji~ zV+iv$Bcz*M5~@Cqkg$a%FePYi?@n`eN?C})31RORlFV6$&~7WjG_znULX-6f$0TH% zR?pJF9J5$7-5eFoFdd$QW||^Vt~nvfGu@ttW|?J9M4N6kTt&i*7L0UWOK$nUJZv znTGFsnTFqF>b`=oQ^LYm5Eh%g66S1CUtdL7VivrrzHU`tB`h_qb|CDRuxtmyt>!2~ z@HW%oHK@oGiEcM1M2_k9I&_CwAzEfmiS9K0c0$Ii5-m4pMJr6|F6b_^R&=)s?uPC$ zqeLss2GPAH@&kOs42Tvt9I%skR4NZDxudHoHWRn7VJNuP>{w zZ_)6zX0L=fuc)tYBRpmnysf^zs=i8CXIj0ZzDij34#E@WsDwp35PI!J*kFqGA|$;eLc2X6Al` zs(TRjNqF7VJ%F%N!omXxyUbn*bKXK|_YuMyX2C}YP2NU0CSi|h^)bSJ3Cli4c-tJ6 zu;?9xUY{WBHASBwB<)2wE#W=W?I6N&39Anx>@%k%EPoea*dc@u&8kBPecwX}A4WJ} zQV%1Xk+4a^$0m3LVa@vp=|>O_nhg?0?n9`2ltp_uXeJ!hb?XC^9a4@4O~p@9wn)kU z6y>v^d09%vhbRp{LpjF&^chOk{V4mSd=WJD{(-Vn%EEu3oCunCrOY{i((V|_S3z^# zF_b1Bp&XNPGH6Yz4Vq7-EczIw*B2!od-%DA35M|g2l%Ip;JBi-i1>2s~<#knt%(!*39H)bI^L)z1+2Nho9L zev7bE!oqJ6B4)3IIsZUt_Z>o6v*0^~CdUwtNhoJpokG|zVc98!^5&?7MV}+|`W_+P z6n&47^aa9c2^W}dKOh{Ju=)pt%I1`W<;M|*{fJP-tojk5?+JwPX@qJf^)$j637aI; zFu|V?)_jSO{u4q?vq8ehuMjH#j8NO8{frR%HNp-Fbxr&kHi>#BQ&it<7d0@|&O!~% zOi?4VOVrrZ{RL`b=8Bq{y`pBO>95emW`XDub3l|}TKxt!H;Y9r%u!KG)8QP{$`pxO zn-iiorrYmOTeCvc&YTjpH~s#A63r@6k~u5tuq-u1SAPtaTec~rhX}zS_L|e`X%L~a z*&t!$PwHt1p^HfiA;kWyo=WIu;$slDNXU;t=wY@aa0sYY3gQqDhByR>I0Tf2`kDnI zP5>fK0A(Of03uERB2ECY5GMc;CjikP(=7s}niZnK=9FlN=@$nLHLFC!%vsTJlUf!U zVb+R9n&5fRC^JfQx!EAP!bHl2Ml4$s;%Z-xc8@VzvCYUJLe29L#+l6X)zuKf9tmlt zT6uLDN7yN0X*@!vIUr$97@>1TglT4R zMT91$5qe#KkZp=CK-e$gw1nxVTP1`=We`?ZLYQezNl1!C7*-h}&#bD9a9l$8LWF#i zdLhE{2*M@_SDIiIguZbI=~WQsnhg@pNZ>!|(({3|st9Y!BJ7Yb&%{?l7&w zvt2@LIfRDQ5f+%4)e*Kx*eBt7Q?~{}#`y>fYalE%dnHsYkI?QSgqzHQix757I3{7S zX;l+pP6dQzH4&DWqY|3LBlN0;u+$XQLf9|iw1ittx7rAcDk7||jZkDxNl3Z?VOSjm z$E>P@a9l#TF2XXCS{Gq?C4@~9j0x65=vx^fy&l2}vq8cc36<+3+-=h8Bdoa)VTXj3 zCcXi}$SMf=4G``#)fytiRz;ZC5MhOS% z2#=Tp5_U@H+yr5*S=U5*{-hnj$p02w`PYgmvbGg#8i*G(&j8tZ0U?s3yWW z2^&nmixHA)A*{O?VWT-K;kbk`mmq91YcD}qUK^oY0>Wl9DgmKy9fWNXwwg$DgfkMd znz>uO-5EvrEDj2??zbUNLi9A!IZ_ zI4EIbISG4BzxD`8O%c|$M|jVim2h0bm_&qqW^E$E@@5F-k`O*LqmmH% zUW~8}A#@;Q;yQ%5P)f<}fbwz3Jc|8Zz}d!Jmc9Rj|ouL5T-DQR1jVW zrxnUF{;#OeS0Te2#yCKaHlKLgsrZNo`Sv zbwl|fWFF{-a$HKdJId*h8QdLZc{`L%QhpAZP!E*8?NQQupqvevr=*;bQn@F}uOTy` zC(0V$8)|k)IfsXOp^QvI$?t{o2R@P#+X1CvZye5pf!;WLi-dg=creh1UAmN+E8?j@ zpU}6?{5GY6@taTf4ZRUk_|Ac$*zo)3^XH6a!)2i^lFT4!8~93kWb>(Up&mhr<@#RW z{Rd>jD)Ghe&B1x0yJI$AIwVvoCj9!vd}UlIxw}yICr6OId`pUy=y=)pv?Eb~{}UXp zpzNQydWFOMB_&_Gncuv{gv^}gQ}Z^Tnj0$RMum6s_xfKe3xTgZ~z;q~`w*w>9|gLj~3FpjvrhpEUO` zL-ilM(Hrlt?jM+7awdgt4=Hx%q1O^Eo@k-C;6auR$xG_MYG0l=j^V*6&r+ zHm#1(`{!@|{hCnwGHzopy@5m{j@SWn3%he6(&5kS*j{Xs7KSD{gW6Pb)8DVik3P4N zZbju@Iqpr^H{o(xBR2&%zjPCxi+fUE!RGU0DO0+BOs9h1|L{K2{BP*%x3l{AwsPo; zVEX7=`}%`@{e?(534E4VO<(TPw?y^1*=qWgXa_&QTp9S^j=bM$7ozo-zxn931xlxvvgm84`aEDYeZRS! z)%02erPCWk^gVlh3Ldhe-dz)G#no1;fmYUP`s+(&z6ktcwMWqSr~h&^@SfGy+H|$h z-nW|Go1nb4!3S1*%+m@2br82HmXBVnpkQ6F-D>NsRu63lnw+B-FQ{kr!7iKbH8lPO z8i2R0wi7|YhTuJ`?Xp@Uw7&kkZ~PZ7G)5e56Z$V-Xo5DO6JllH>`n=k>RND*Ma)ilee0Dbg^2mZOUT;Dp> zg!&jk6>}X7JZjx~$mVT@roY+I=djgU6CRAF`ExwH`x}}jrB;_-&ZN%;G*m&YF5df8;JUJs6+0p} zBUbLMY_(*<*+8EQt=5UKzH6y9U&U&j33t-u;8WFVTCSa~R?TW$@&je9R$cEtP;0t^ zWh9U*YuJR{2sgqr^3X+A>rVJ{W#CiOYCQ;lZM9lxbXxEA40Nw5KuM;3jCANc})_J9N#_R3F!{Kntt+@5<#ff-h7YqddW-w@dYZfCVr!Y6<} z`paGA9Srof*WNJi((qmiHw2@%75x`$=o_bftfrT1sJ>x9<1P;++XD3sRDJnf9`awd zF@kVctLcRss(2)L6zCJR+9;{7+MaZ=;^ic`(rR6;rk6?TeK-1av)X9Fx=<-jFX>Pv zb;1PrTvBoKGtFX#2dn8qppCyKs0C_+I-ssu&?2UOK|H~VU<{2N3&w%rU<4QmMuE$L zwtszLUR%E2!JutE0^&efa30V$UmjEd+TPWa(x8me1MTGJfpXw{P+s1zK%gSfveYWn zs?+MxYN-yi7&Q4c*)_Rq15Id6V9nS1paIZ4)hiH6gC7W=20wwH!5MHC=(6!EI0t?Q z?`rkEM?lw!eL&ZS1K=Py1P+5E;3&{v>Fx$^fH%Q9upT@Cv}%Gt-xSiNV^%YsR}k*9pDUtuGh=27=4LAdm_MgP~v;(4}Go(B)wi zxEyo_dLvyc&>9%p*81zM_Fnp$;QW!egQ(4e+V z&PzZGps&x@2Ms_&&;<0s?Vm8_2f-n57#smd!KdIe@DFedd=9<<&w}T`^Llf`HUckz z7r}Ut1}1=sU=m0Nlfhal(nU^7S1VN)H@!=v61WiP8de=#1Zsg)(p<#q91iyf13+)^ zEgd@rz6aGc{x!fwU_Q_?)?TAcO`F&{5^2Y547BSu187=bP?6NSKbEifIVOXcnWL;1yA#16LZ@GN)^JP)>k7r=|)C9oa53|;}R zf*s&B@H*HDo&-080x%!k0Di&~XTg`?EATZq8Dji($*&I@f=fUGSc@kf1&@Kp!8))W zJOQ2r8^BXwBX}BY0?&ZWU<=p^o(0c=I+Uj)!Uy0(FdJM6=7706eO*OB!=Tq3P5={u z&I)ZoeNX{Z26{`T-kf;`m;M0)gwH`Qf|tN{@G^J>yb5-J*T7D&3+x7OfH%P&@D_NR z`UCHPz2IGN7q}Z_gPXziAPwl+q3cX9D(wk6F!MWtWS}#L&KP=2$1I??WSj)wfN#Nf z;0JIT`~-dm5z^}nQg9CAW$+5v0bU0?K`+n{GzE3RV8(C=_<=^$q5=A{a7S!i1lxmF zKv(RI#6JnXBm5P3gs|S-^&L0`^kOg_8$SUDLmbj{HXH;}!BPsn6|^O+7xqQKVeF$O zwN*@&f)fP41YZH2cl6T1cAz~-1W7<=o@7uP1i@MAKMlSC?}L5d1MnUg1$3?LO**~L zVgMKj^pXr6iMoRxpeOi6Z<%p$#2w&HV8Gp=JdqWE-i~uIxCA5sor`o18j2HiD&VN$ zzIIpd3;G^>4c1b*US#$I4fqk921BuRRvHdQfRRAwq{~A|TsPfpXw{@GF&l2Tp-6XvlG(v(ks)0Qd-e0uF*h;4qj0 z^rjCTk#v;N3FKYMdJpInqf?8%vRNMJu2pxWI<;J-m3}pWc|dm@OTm0_9k?Fc0Ccl| zBe)q1!*hCXPd}g+{^-7I2i#u zJwY$f8}w1H`+|NT1@s4(f&pM4xD4p_rU|GG4$$)JKsHDRO+hnoG0!0VIG+Kn@*}2lNN>x`R0%tfbTJ zb)^r|+LJ_n13H1`z`YY7kq-L4tK_MUcqbWj0$o8j&>ge}Ex`wr^(J@;JOy&WS<3s0 z2I%EEYJ}XbvJ~#A&9n!2j0CTf_!^+Y`)y!kMViRxp2mhld%c2xplOrTW*GpwAHNUW z3s!>VK+8){ko08fc2ETR0F|e5^;AnMX$i;z@6(8>u(l2zNi``oIWOh7 z%WyJi2QC41KyB&|)FMzFR0CDOg`hI11aP9961V_V1hIg&x?kz=$d3+y9p8P#kqGw$-GMT816_d%ivktW1@r*DKtG^H_W|;h z@14Gc<&hMiMh^g&fq`HO7zTz?e_#lK!5|e(0OP?Jp#6S07zsuI{|b5qVIAVffpm}t zCIaQ11SSI=YaRr*fcwC`U?tG@eHT~(rh-h3zxHzj?gZM+?f?$B9oz;~$Wl-UmVm`z z5tt9i9+(cYfp)-YAO~Ctt^zZ_Tx-vPXM;!wj8(=qx z1#g0Pz*{!_HoOviFS-uCSfQnakB~w_%`~;LnnyOKJPv94Gmav+rIHgmbKfv$c98mt>fKIO^yAi@J z6=Y|sM?g0mx>ql4jz(i@nESiL#JacawaBRZ_qw1C&~ev4mg`=!2B;3I0i6nTI?yRW zH!?agTmW=>&?!PUI66z|GNtpBo)73|rx$gUhIPbl3)+Cz!GI~>H6~op5~BssHPpZO z>S&@PijFEeqBI7LKts>~=x*v=@HTi0yaslFS3p}TYXe>ZS=cWFU8Y_FlR*n~dA>PF z*Ck5cnFy*OjE56o9scG1uCPvuy2z_Q-4Jwwl{QLPPe@|GIB+Q#3zT*Q7z0Lu%fMhT z2#f|-fB~QzxK#IzDFk|g9-uqu2l|3Opcm*3G)zj~AK$WY3s!*C5a=EqD09Ec+ zoJv?_D9=dXH*#13#t<+R^dP}-Yb&foenPc=n2nRB!Y6<cqhX?ydf_7!QE0U<=p`o&lS{)8Hwv0XzxTgLU9> z@ECX$tOaYpBj91M8axCZ1gpSGa1U4vZUU-&k;_a6zvp)&6xzt;@SWfeungP`G@MJ| zTY&W2z^z~@kajyL0@B5P*dc5{ELZ{VvSHQd{?8t`!96akRrdqgnv?edC6Z?pC%BnP zu+sjs_Mh1*N1c`j3S{_&_!T{YRn?82ZTc%S%5K)2<(JueG%tF9Xs9pL^T?l8Rq&3UjgDv|$0;;-CWfpq_=du=2BwRiFVf7iY0 zNlhxR0_1kh2aSCVP#IJQ{=CpUQD-hJ5m%{1d`tn6Q-FqG7^q653idN-a>>=Q6|M$r z-28YIuJmd|$$}LxucIR$7SV%*M9?0z18qSY&>FM?EkO&=93+5C zz{Q{$XbSY?qcLa%8iEF(KBxzJfbKw#S~`Kwpd084x@i0r7*Eefz(YVPkSDg&LQR%I zKiIdwk6w`p_zzn!O+#9Gf(?K@S zkn6-dUgMvGP#I$}+zQs^dlBJ$kW9QT;j;+WhVx*Zq-Mfe>q?tTxGn6T!fwL87WjE) z6P^dI0eYr)HMj~~2@2-$L!!?*jj6B#G*zfVRpCPH8^HBIUXmxafa|aqfcZckxe*is z+U-6o)Q~K-a4g>m+nul=uma;Aa2L26_=)94&3tVj+FUgLa;et*8^mn`_k-ub6X0?1 z7Nv8SoP^m zsv>zo>=!6jCb3$qMwG13_nIo)15}PG^X83EM4dod875EaI0LOv!FW}FC9xjo^eSq{Mw#q1Ihwu#n6{LG~-K(D> z{2h3L@DK3!K$Vsv_aB6R2fu;S;8$=KXopk2GvH_N6Zi$F4C#6fAeMa&4pCN2j2;mZ z&~M-+yrbWi@`-!OygV?bkqq<2z?fC$fy-hpYF4+FcuW4(HOK!J8ywrJdF$rv zP zpqOgG{U#Z@NWHH}x`BOe{IN={^9PfzW%HKJ*%0}H^o&6% zshA38U}{Vp-&Glv8Z(9Oc5Y9Nsa`!dGiTORF3pjI^G7Vm{K(DMra702>rDBp^qn;Ftlyr_Euk_HR+CdR}{F=t$d&Pk#|okJ_|t-m3Ls+mp}ZZqH5r z`K$k@xbF^&>T3RH_paClBjN&AL{wBFh=8l8AQB}}5i3SbM2Z+eL;{G2h@>bO8(0_% zHY~9aEU0V2uCbw_vAq^VEQw0c#1b_|zn{7HuIo#d0f=?G*GbVW2XSh z6IvyE&1lgF08b1ZfR>=t1grJ@p>^WZ6N)5CJEpiPl$vj|mWL$VQh@@IuI_HsB2qsSC=vizVrdXeuz>XZw2~g; zNu8%A^T9$N${K-(9co&ZB518SF0o?8t555i4L#!mQBaElz7g!n@l(N8eL_u}_rM4j z)KtD#(9)Ulc!_WSX9wfu12rA^6yCtgs4k@J{$W9zRm*$_O2d;BVwYw=>F#4Q$?tZn z7LxpquGsYJQ@0_|QKWNW&}W1|A zuKUMG0N9=2XcMR_0J@U^u#wcsb$5K{XgMALHXi^N@tVCV=J2q9Kh`@<1OBkoxhnvh2mGZLPJYWsFo@va$~c!%;Xu=Z$N(ExICn8M;;`$>4{z8&Ril7_F!g z#lSChTCMC6_oq0|8)UQiPibrj9q<`Yc*3t_ce8t*G^3Ys)IV#fkbPQhL*<*XFe}2b zFl*aTt&tFHWkWtAA=ukiHu#K@^S2aUJ#iE4QglJARVe%0EVOB|#zOZ(n7GK9^)jakqsX)r-KQ9fNscr_&5^A9UJ$!%-l3z;I|RFuw@M zS}sx|T3z$T(zRFG={kKb4BP&wwOWNp>&lyN3Mjm6(yO;#)@Rk$@1=pZbM->0WJ@LJ zMP1zCi5GT2iK9@&W>3znZZ~)|G<1{Q-p7G*z$^9! zf*1a@^d$@D-5a+YyzS91_VghRRLs&NfM6T1XrJ}NwzG9of#7Wl(&Itlb=!A>^YZrR zHX$@g;Y5dh(ShtE!J7p{10d}7)%E`MY3dtjO=YQ8NvU?tSCr-`ypU?;NYRm4 zC335!@<_o`z08puqhQbtjx-ppSl}oRxsH14mAKE=Zk9|htw|tOGh&&7cv;tRdqdw9 zkAYx=zUx41=)eS0GQEuS9RnjhX)aHJXIcD)YKbo*)GAnrMVbB8oD#-BFGX3=8$~Ej z#g6oqJ9~`FSj$MnG9aHcr|XPNcOuJZ==a)5HlEG#teQ8bZr%v};M(lEwOdkfG~BL9 zOG*M#jcLw{78aXu5otv2+)Ye`6rnH?vde1KKee@WdUUibVcnIyFo#% zE8Q6@1c=?*%3-==uagz-OKg*X@RX-Jpe+T&Krchvtu3X+K)(fUv<6IL|lQ+Ev zuUG{yhSkcK+!6$L)o2P&5IhXKk7#0)NQ~JcPraxJ3>ZfCctNYJ-B~u>xgi^hdp=!$ zSLxf6MvfPDswer8eIok*)=zf8LrJB3P6hmh41?zvRyUjFN2R<`FZ82mAl0k34s(>urWd*S#?@GsSQyh*M z5qCkc1n+>{llpmMdX6(vp7~Li3FyDZM>KeX;6A1CN3!N2magObpXzkpO63f#`JWRg z?C$2hk1fx;`e>5XyD_~4m1ioe?XX!++r7Q4RBpg>wEYMz$L0FXn=}}d^ZFMf&j3(Z zqc5`#$2qn6VxrOyf`XZB5_fgS?&O;U%PXc~6)j;pTAPGjKHrZHG0|W@g{U^z*T5tv zMrrTfD|oSLJOAKMuF0@Sp+9|+ESypMe4^J*5=50)^)Ov}Qa@A@YOkIYl>()d%0joj zr#zV-UR)J-Zp_xtu|kx(Dx;TN0G5>OU%JtKua`!J*eqoMi+fQyWQlnS;^*vy-&b~h zzQ>5z*NYq`W4enKgf5_H$I7|el8uNmP}ux#ev3!w%`MbM%ClY+!@MSW&2#^sQ{Ue9Rb#0krM6^&S(IL5SFJd29?+d#?$LKmVSF1hb{ zJL`A+!ucH{1r!`*r0&6?E@l5J*DcCKBU*QZ_^5iUXG_7$XC4VS&^^oXH4&$JvaS~v}aRa=3=HHFZr zU`v;%Y_2L{ZqDJl4yRP+9RLK^N1gXJSvlJyuq&@Oc}p4#3VX(9wt+KtBkwq}QNk@rh|E&-uF2HRMYuw`K z+JP)0U`UdswGi%;HV=o_t&}{IE1AyRg{4i?Lw3?lCNWKlcVIfrf znP6qka^geiI-{oo-4JNAQTvYkn)xNteB>`uBEC3;ET>_RyF$o$8Vu$WO2Pd6aVWVh z5v&}zpc@z}$G#uM25*+$x6m53i3p`UpvCcF@>o6Qh9@6fx?-|gH5zYtTl^}FN*S?0 zdDd%>UN0_wb4StuuF%meH;k;((KBLjmz{#v>SOfAb{n_wtVL=@09mT)gi}Jg;GkB< zuJ($c&FQe;W>}cl)xCbnLZ6^ToX<&9=k>QqwPcEvAv$ zKycOOugdHmW=6BSn|X{P`_CZ{L)tw59~F&?kBAR9!`bhEUOo@+40wnk@WCVevXV~X z&QbDWTGCMez;pFZPBSLzH*LIv9#K%xv79b_MYb87F%lZ*x z-gur~1PabB`HZ#f3tGk_mt|Pndsc~cd#91Xgs_&wci>eou~QOdqzrBZ%Sp}XG)@xyFN9lqDG7JMuf?YR+5VCvv4k_LYl2YEyvV-~*A@L6J7K57zd#)1@>} zD4w{c8BZ0=TPsoe1Uv0b#KaEHUv1!(%DmW2n}gC2Qt!+#ANcG1oj4CMgfy>2>XHS` z1_Hs-`wR=%wqw>IoKr~%NRLdUSRiyMiu5k`UVRtvc_faK3^KAo!Kq!EL&465trjle zty&3~`H8fTc@HayU-BMJ@AJY!-jby2m204IdJ*+Q>%*->ytW#7pC(eBxzNmNf*gOu zEz`?>{@{gZM6{hizCh^u0KxsY$?4f^jc+;^xJv&Kpm31C89gNUMA@NWBPD$T&1T*e zK(J+8C$Fpa$B=4#v!L*92Za;9yJLrj&gc}i*ho1yfv&S=KLcS6#Pcp~U!6=ff21HV zSAR_)%XvUpC&}~OW@hM2-L4zw6$EC)F^Rg*gM%PqtXPUNCv%?QDOMdeT1}+VdBS3K z;zUZprXWt4D5oSAmz~5Z4~Y%Rc@x65vTdlRPo$IcQDE0fChY=rWR*+-+#XA&v;_!@ z7nA7>TCrBLEa~l~wgc6_Eb@^gVROLoxQs9$S&}*%61SuNF}7MYbUUz6_I2#~T6JhD znG?=sHl)hQQOYIDEq~?e>>=6HRXQH5yh}?IX@?z;KT1Q;YCCv2yE&R!drsHEzi?j2 z6*^2STSBYGf(cnHxKmmVVzWU7Ln|jBM%4`O|DnxXgoBv(X2Vv=Vk9B3y`jed?(Ds1 z_jjEuor95Eg~ zKf+wV*J6QCx^bzl~I@%Nmj6ck=bZkZI23w;7J zsmn&RUu04mKTpb}Sbk2=r0+HgF4YnJaQTjxM}>w>5Czs}%F{P2y=k)7_UC-nf!Wu& z>dbazlDG<-7c!|%9$LOm;^$v7$u|#iLOvI5NT*i`jnz0LEN9}YOuEis^DJ^$jTQIW ziGqK?vrQKMa5Bt>yO=y~TW3)zx1L$#vj+5`S>&1zXN<^_C%K8bEVzF~1z(18o(gA- z$)Yzvs3&JpNuKQ9Msx5<~Y_RLd#BpYvlkX~%BjG@l-CL2sV(=>_-Zm`!cI$FoZ|`G1dN zZby=XV%zV14&0j>hGNHX7+XM;4}^NeLVC>{R*T4b9gfcDERsjOaK7)63pdjd@j{ztfP2c91`t@ZP8Q6qcmXrZso>MA%^I#; zf1B%P`SRGTSx)wP6v-o((vJ1eplX}PE+x$dg!);_WGC6!bV%;2sc)M@6fYZi(qd3J zyp+EPyD_3c4NplOiPCC0MQ?yQvb$*2%~sF~$ohxgFy4v{SbB|D${E4`n@hXnZ;Aac zdh@Eh{{wFh5dCxIX+1L3?T=bBcg&G2EG40RbIE}{PVs+T)nOzM6V74eR>rl2ErBO% zNOQsYr`cz@6tD?0l5$DhjFxgKZIj@v`}eR?IW$?S^tn{JNpKJwt&+o8*0r9ht>;2; zZf^)$|J@5h<|^v9S#Wmz_ujbTZbSu}g${;WU{mgbOG^H@MlsC4D#CGD)Um^}ZMD5&xBnb)j6Eb(kP^aV z(JfJM{{5OYGkN|kAyQFvZ-;b~wXK9OS)WRj-6*=5_Y5@S0%e(<+wPz4hYvGqX7Zpw z;zhAv1YXf(SuP<^bngJbWZ^6UP`7*T5Yohr`EvT;?KS*yi@N>pDVM8=?4Fyb7&3JJ zo8-v!b;;BAk3T+8Tdnd|-t+ltTk2hanw=?tKMD}{bnLf4@jaK|< zi<}ZA&GjDG-^r>UCv{RXX*O&Ntzg7RAS@wk^rLN$26!fLeTsso17sOK2PxMJfrfKH zQ=f3ayLmY#Y@t}36pE7}koQTC=X16XJU%x;@>Xf+*wj|<#8y2G2;LtT47->e@KM-( zAUKalPK0j)>+FJzzsC(9Z~hL%)9j}$MkgWBF=d?PKo$e zofhbz+U4G=gxvONN(ZoQ5Gb`lsWJVd>Ni*A@&PtS6Hr2SP#!Lu#h+2|@=My;*DT_nG5Yt+z`uB(vkvJD?ErgDdP5 z{uWL#n&F!#aR7|a0KLZsogMP?r*Tt^y+`Qj&K_h0R@i9x2>0`&ZGN$t+%gadCArAo zCGQKW4WWl4=d>@7C@Ah=3%OT(XvH6HsT-}LG${9^db&RqB{Rdb|&Vz-eBs{W#V8Zm<68ekPpQt1mgg{|A(^gNR@j z7#91)r9l7hAI`bO$%<0BX+6k|@ATih>z6(fRPOq9Uf|?3C-GDF#hx;d_q)-Q`hULJPj|CzWMETi)A)O#C!x5o*W3aHEtRyNXYDuU|~1> zQPyix`4^`%K6r?D&Wq9mN$yaEvg*{riOZwT<8nH+BP#oLZme-Mc*UQvcGw;@$94Jf zLI1^jfN0OR6Q1wJWEg|#+2vYH-h16eD&GP9GJq?pE=RGt zday*{MK9|?aRB9_U-;wXNlRjkloQ9P&W{*v1rUva*xaf4e%sAGvjHayv!zmImLJ^zMVR|LO=_N@!c!Qx^BKA3IMT6a zpuOrIr~QiVmDMolZs`8M>F)2;GrX@nthlozo(W$bb7S?UMG zI|CScT2M^O-hV&%97Ugl_3B*^Y{kTL^27!9>gJplc#6;XlmW~;M-CXG!6f1aARA$t zoE}UQ^$zCPMuw7)tz!~osm;f`5(;q@*KHdd~Z;O zi8AzIFqgr+mCg45M|XcWhRS?~u~mM*<^qMBF^>Horl&Gz#WCt~9-R9x(rZW%OD@Xx z?egS&_XjK7s~N5I>>|0H#S*H2N#2gzW~@7yv)Y@Ch!&vm@~fAY8ocRdaG{ancZpKL ztIoSbD=_KmotLP%810cuRD}29d2sSRX8rPOt0unncvh8N^zNl>1{x;uC4fAM@khV@ zdF!TL@2%2?mnpCqF~}f#NjM)$^BpweNhRbvPJ@wOUZFZa zp>Ko96pwxPtPDon37t5`I^BA0@t1QM(g#EIHw;(N#V~wwIFE>7uzXdvd4GYZWiyD= zugP11|HiMQ)02MWLm!}?d$&{Z9?s*WwDm!Vdjb)8apc`Ejn>?_*ekhhwe3!Z(@c~NgZ^H-9H zsw`i{dluJFK2xoXFxXV?*oIV>1rKp%i5wff+e|pR>aRWTb!_k~gXaW$$xCVW%B?|v zO+Fh06_uRi-@R8kOsR&1=ip5$$DSiDDV6U*?!NRGbElbr&s*>rGgshdTT02{3fAs1 zAUJwjJfZ9+K4(`L5hbAT-Az}Q^);fd+CMTslB*~e@cChzYhc3f4+3wX zUGp=A;8|DoXR0QC0>WR(Aj||?Q~ot5BHpL6YmnXQKDk}T?-UHOlkZc}bm9Y-pPrUX8yU&^t2wrr>5FhK~y$hu873aS`E>@sZx( zj*X!8y)~z5M#qhJ2@ee)9idMM(DWDR%io2L`p11W-BgrXA$&-2jv714cqHJ<;(nUy z`gZ*_wauxtuf~$r|1LDAInkP$`W~NZ{`g3*$V*6^W UH8|(=q~F3cP4zD4G!tt44@;zf=Kufz diff --git a/cspell.json b/cspell.json index 22578bc..70b316e 100644 --- a/cspell.json +++ b/cspell.json @@ -5,6 +5,7 @@ "ignorePaths": ["examples/deprecated", "dist-jsr", "dist-npm"], "words": [ "alacritty", + "alcalzone", "alternar", "anims", "anykey", @@ -18,6 +19,7 @@ "ausgewählt", "avez", "Baratheon", + "bitflag", "blefnk", "browserlist", "browserlistrc", @@ -54,13 +56,16 @@ "figliolia", "Fireship", "Focusable", + "focusables", "forgetme", + "Gawf", "Geralt", "goroutines", "Greyjoy", "Gyllenhaal", "haben", "Haha", + "hotmail", "hoverable", "iife", "invertir", @@ -105,15 +110,19 @@ "sbuf", "scelto", "scule", + "segs", "selección", "seleccionar", "sentencer", "shadcn", + "shoutout", "signup", "Silverhand", "sisteransi", + "Speedrun", "Sprache", "subchoices", + "suped", "Targ", "Targaryen", "terkelg", @@ -126,13 +135,16 @@ "typesafety", "typestat", "Tyrell", + "unclip", "unjs", "unpub", "unstub", "valign", + "valtio", "venv", "Vous", "vsprintf", + "WCAG", "wezterm", "Whoo", "Wybrałeś", diff --git a/example.png b/example.png deleted file mode 100644 index e29d724db63d83d26e69e2d5be58b626ca626e18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61220 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≥NG@(crk+R-SG8m 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%0Dn2jcvd`931gL77D5Eny}GTx6L$WQblh< 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 z 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≤8uBm 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 M1}t4JX&mr>0M!kQR{#J2 diff --git a/examples/launcher.ts b/examples/launcher.ts index 6341251..2659ed1 100644 --- a/examples/launcher.ts +++ b/examples/launcher.ts @@ -9,64 +9,81 @@ async function examplesRunner() { const exampleToRun = await selectPrompt({ title: "Choose an example to run", + titleColor: "passionGradient", options: [ { - label: "✨ The Most Full-Featured Example", - value: "1-main", + label: "✨ Full-Featured Example", + value: "main", hint: "recommended", }, { - label: pc.dim("Mono Component Example"), - value: "2-mono", + label: "Spinner Example", + value: "spinner", + hint: "experimental", + }, + { + label: pc.dim("Task Example"), + value: "task", + hint: pc.dim("not finished"), + }, + { + label: pc.dim("Progressbar Example"), + value: "progressbar", hint: pc.dim("not finished"), }, { label: pc.dim("Simple Example"), - value: "3-simple", + value: "simple", hint: pc.dim("not finished"), }, { label: pc.dim("with flags 1 Example"), - value: "4-cmd-a", + value: "cmd-a", hint: pc.dim("not finished"), }, { label: pc.dim("with flags 2 Example"), - value: "5-cmd-b", + value: "cmd-b", hint: pc.dim("not finished"), }, { label: "🗝️ Exit", value: "exit" }, ] as const, - defaultValue: "1-main", + defaultValue: "main", }); switch (exampleToRun) { - case "1-main": - await import("./1-main.js"); + case "main": + await import("./main.js"); + break; + case "spinner": + await import("./other/spinner.js"); + break; + case "task": + await import("./other/task.js"); break; - case "2-mono": - await import("./2-mono.js"); + case "progressbar": + await import("./other/progress.js"); break; - case "3-simple": - await import("./3-simple.js"); + case "simple": + await import("./other/simple.js"); break; - case "4-cmd-a": + case "cmd-a": console.clear(); console.log( - "`bun examples/4-args-a.ts Alice --friendly --age 22 --adj cool`", + "`bun examples/other/args-a.ts Alice --friendly --age 22 --adj cool`", ); console.log("Run without any arguments to see the help message."); break; - case "5-cmd-b": + case "cmd-b": console.clear(); console.log( - "1. [BUILD] `bun examples/5-args-b.ts build ./src --workDir ./src`", + "1. [BUILD] `bun examples/other/args-b.ts build ./src --workDir ./src`", ); console.log( - "2. [DEBUG] `bun examples/5-args-b.ts debug --feature database-query`", + "2. [DEBUG] `bun examples/other/args-b.ts debug --feature database-query`", ); console.log( - "3. [DEPLOY] `bun examples/5-args-b.ts deploy --include '*.js' --exclude '*.d.ts'`", + "3. [DEPLOY] `bun examples/other/args-b.ts deploy --include '*.js' --exclude '*.d.ts'`", ); console.log("Run without any arguments to see the help message."); break; diff --git a/examples/main.png b/examples/main.png new file mode 100644 index 0000000000000000000000000000000000000000..5fd48e520791ffc0cb83eb311033880ac538861b GIT binary patch literal 75352 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 literal 0 HcmV?d00001 diff --git a/examples/1-main.ts b/examples/main.ts similarity index 100% rename from examples/1-main.ts rename to examples/main.ts diff --git a/examples/4-args-a.ts b/examples/other/args-a.ts similarity index 100% rename from examples/4-args-a.ts rename to examples/other/args-a.ts diff --git a/examples/5-args-b.ts b/examples/other/args-b.ts similarity index 54% rename from examples/5-args-b.ts rename to examples/other/args-b.ts index b2d33aa..e8321c3 100644 --- a/examples/5-args-b.ts +++ b/examples/other/args-b.ts @@ -1,6 +1,6 @@ import { defineCommand, runMain } from "~/main.js"; -import packageJson from "../package.json" with { type: "json" }; +import packageJson from "../../package.json" with { type: "json" }; const main = defineCommand({ meta: { @@ -15,9 +15,9 @@ const main = defineCommand({ console.info("✅ Cleanup"); }, subCommands: { - build: () => import("./src/commands/build.js").then((r) => r.default), - deploy: () => import("./src/commands/deploy.js").then((r) => r.default), - debug: () => import("./src/commands/debug.js").then((r) => r.default), + build: () => import("../src/commands/build.js").then((r) => r.default), + deploy: () => import("../src/commands/deploy.js").then((r) => r.default), + debug: () => import("../src/commands/debug.js").then((r) => r.default), }, }); diff --git a/examples/2-mono.ts b/examples/other/progress.ts similarity index 62% rename from examples/2-mono.ts rename to examples/other/progress.ts index 19687ea..ccc53c3 100644 --- a/examples/2-mono.ts +++ b/examples/other/progress.ts @@ -1,6 +1,12 @@ // 2-mono-example.ts: A fun example of a quiz game. Inspired by CLI-game created by Fireship. The example demonstrates how to use a mono prompt() component. -import { animateText, inputPrompt, task } from "~/main.js"; +import { + animateText, + inputPrompt, + advancedTaskPrompt, + endPrompt, + msg, +} from "~/main.js"; import { prompt } from "~/mono/mono.js"; import { colorize } from "~/utils/colorize.js"; import { errorHandler } from "~/utils/errors.js"; @@ -48,7 +54,7 @@ async function main() { ], }); - await task({ + /* await advancedTaskPrompt({ initialMessage: "Checking answer...", successMessage: "Answer checked successfully.", spinnerSolution: "ora", @@ -58,11 +64,54 @@ async function main() { updateMessage( answer === "Dec 4th, 1995" ? `Nice work ${playerName}. That's a legit answer!` - : `🫠 Game over, ${playerName}! You lose!`, + : `🫠 Game over, ${playerName}! You lose!`, ); await new Promise((resolve) => setTimeout(resolve, 1000)); }, - }); + }); */ + + const result = await advancedTaskPrompt( + "Check answer", + { + priority: "normal", + displayType: "progress", + }, + async ({ setStatus, setError, setProgress }) => { + setProgress({ + current: 0, + total: 5, + message: "Starting verification...", + }); + await new Promise((resolve) => setTimeout(resolve, 500)); + + for (let i = 0; i < 5; i++) { + setProgress({ + current: i + 1, + total: 5, + message: `Step ${i + 1}: Verifying answer...`, + }); + await new Promise((resolve) => setTimeout(resolve, 400)); + } + + const isCorrect = answer === "Dec 4th, 1995"; + + if (!isCorrect) { + setError( + `🫠 Game over, ${playerName}! You lose!\nNo worries, you can try again!`, + ); + // Wait a bit to ensure the message is displayed + await new Promise((resolve) => setTimeout(resolve, 100)); + process.exit(1); + } + + setStatus(`Nice work ${playerName}. That's a legit answer!`); + return isCorrect; + }, + ); + + if (!result) { + return; + } const message = `Congrats !\n $ 1 , 0 0 0 , 0 0 0`; @@ -81,6 +130,15 @@ async function main() { titleTypography: "bold", border: false, }); + + msg({ type: "M_BAR" }); + + await endPrompt({ + title: "Thanks for playing!\n", + titleColor: "passionGradient", + titleTypography: "bold", + }); + process.exit(0); } diff --git a/examples/separate/select/select-example.ts b/examples/other/select.ts similarity index 66% rename from examples/separate/select/select-example.ts rename to examples/other/select.ts index 7a966a2..d85c4f2 100644 --- a/examples/separate/select/select-example.ts +++ b/examples/other/select.ts @@ -17,39 +17,39 @@ export async function detailedExample() { msg({ type: "M_INFO", title: - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?", + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?", content: - "What web technologies do you like? 42 is the answer to everything. What do you think about testing the very long text? Is something broken for you? What category best describes your project?", - hint: "hint !!! What do you think about testing the very long text? Is something broken for you? What category best describes your project?", + "What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", + hint: "hint !!! What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", }); await confirmPrompt({ title: - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?", + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?", content: - "What web technologies do you like? 42 is the answer to everything. What do you think about testing the very long text? Is something broken for you? What category best describes your project?", + "What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", displayInstructions: true, }); await confirmPrompt({ title: - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?", + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?", content: - "What web technologies do you like? 42 is the answer to everything. What do you think about testing the very long text? Is something broken for you? What category best describes your project?", + "What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", }); await togglePrompt({ title: - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?", + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?", content: - "What web technologies do you like? 42 is the answer to everything. What do you think about testing the very long text? Is something broken for you? What category best describes your project?", + "What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", }); await selectPrompt({ title: - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?", + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?", content: - "What web technologies do you like? 42 is the answer to everything. What do you think about testing the very long text? Is something broken for you? What category best describes your project?", + "What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", displayInstructions: true, terminalWidth: 92, options: [ @@ -68,9 +68,9 @@ export async function detailedExample() { await multiselectPrompt({ title: - "What web technologies do you like? 42 is the answer to everything. What do you think about testing the very long text? Is something broken for you? What category best describes your project?", + "What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", content: - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?", + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?", defaultValue: ["react", "typescript"], options: [ { @@ -93,9 +93,9 @@ export async function detailedExample() { await selectPrompt({ title: - "What web technologies do you like? 42 is the answer to everything. What do you think about testing the very long text? Is something broken for you? What category best describes your project?", + "What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very long text? Is something broken for you? What category best describes your project?", content: - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?", + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?", defaultValue: "react", options: [ { diff --git a/examples/3-simple.ts b/examples/other/simple.ts similarity index 81% rename from examples/3-simple.ts rename to examples/other/simple.ts index 04529dd..2b334bc 100644 --- a/examples/3-simple.ts +++ b/examples/other/simple.ts @@ -5,18 +5,18 @@ import pc from "picocolors"; import figures from "~/figures/index.js"; import { select } from "~/prompts/index.js"; -import checkboxDemo from "./src/simple/checkbox.js"; -import confirmDemo from "./src/simple/confirm.js"; -import editorDemo from "./src/simple/editor.js"; -import expandDemo from "./src/simple/expand.js"; -import inputDemo from "./src/simple/input.js"; -import loaderDemo from "./src/simple/loader.js"; -import numberDemo from "./src/simple/number.js"; -import passwordDemo from "./src/simple/password.js"; -import rawlistDemo from "./src/simple/rawlist.js"; -import searchDemo from "./src/simple/search.js"; -import selectDemo from "./src/simple/select.js"; -import timeoutDemo from "./src/simple/timeout.js"; +import checkboxDemo from "../src/simple/checkbox.js"; +import confirmDemo from "../src/simple/confirm.js"; +import editorDemo from "../src/simple/editor.js"; +import expandDemo from "../src/simple/expand.js"; +import inputDemo from "../src/simple/input.js"; +import loaderDemo from "../src/simple/loader.js"; +import numberDemo from "../src/simple/number.js"; +import passwordDemo from "../src/simple/password.js"; +import rawlistDemo from "../src/simple/rawlist.js"; +import searchDemo from "../src/simple/search.js"; +import selectDemo from "../src/simple/select.js"; +import timeoutDemo from "../src/simple/timeout.js"; const demos = { checkbox: checkboxDemo, diff --git a/examples/other/spinner.ts b/examples/other/spinner.ts new file mode 100644 index 0000000..7e62d13 --- /dev/null +++ b/examples/other/spinner.ts @@ -0,0 +1,126 @@ +import { + endPrompt, + inputPrompt, + msg, + selectPrompt, + startPrompt, +} from "~/main.js"; +import { prompt } from "~/mono/mono.js"; +import { spinnerTaskPrompt } from "~/task/spinner.js"; +import { colorize } from "~/utils/colorize.js"; +import { errorHandler } from "~/utils/errors.js"; +import { createAsciiArt } from "~/visual/ascii-art/ascii-art.js"; + +async function main() { + console.clear(); + await startPrompt({ + title: "Spinner Component Example", + titleColor: "passionGradient", + titleTypography: "bold", + }); + + msg({ + type: "M_GENERAL", + title: "Who Wants to Be a JS Mil?", + titleColor: "gradientGradient", + }); + + msg({ + type: "M_GENERAL", + symbol: "middle", + title: ` + ${colorize("HOW TO PLAY", "white", "bold")} + I am a process on your computer. + If you get any question wrong I will be ${colorize("killed", "red", "bold")} + So get all the questions right... + `, + }); + + const player_name = await inputPrompt({ + title: "What is your name?", + defaultValue: "Player", + }); + const playerName = player_name ?? "Player"; + + const answer = await selectPrompt({ + title: "JavaScript was created in 10 days then released on", + options: [ + { label: "May 23rd, 1995", value: "May 23rd, 1995" }, + { label: "Nov 24th, 1995", value: "Nov 24th, 1995" }, + { label: "Dec 4th, 1995", value: "Dec 4th, 1995" }, + { label: "Dec 17, 1996", value: "Dec 17, 1996" }, + ], + }); + + await spinnerTaskPrompt({ + initialMessage: "Checking your answer...", + successMessage: `Nice work ${playerName}. That's a legit answer!`, + errorMessage: `🫠 Game over, ${playerName}! You lose!`, + delay: 100, + spinnerSolution: "ora", + spinnerType: "arc", + action: async (updateMessage) => { + const isCorrect = answer === "Dec 4th, 1995"; + if (!isCorrect) { + updateMessage(`🫠 Game over, ${playerName}! You lose!`); + process.exit(1); + } + }, + }); + + const companyAnswer = await selectPrompt({ + title: "Which company created JavaScript?", + options: [ + { label: "Microsoft", value: "Microsoft" }, + { label: "Netscape", value: "Netscape" }, + { label: "Mozilla", value: "Mozilla" }, + { label: "Google", value: "Google" }, + ], + }); + + await spinnerTaskPrompt({ + initialMessage: "Which company created JavaScript?", + successMessage: "Correct! Netscape created JavaScript.", + errorMessage: "Wrong! Netscape created JavaScript.", + delay: 100, + spinnerSolution: "ora", + spinnerType: "arc", + action: async (updateMessage) => { + const isCorrect = companyAnswer === "Netscape"; + if (!isCorrect) { + updateMessage("Wrong answer!"); + process.exit(1); + } + }, + }); + + const message = `Congrats !\n $ 2 , 0 0 0 , 0 0 0`; + + await createAsciiArt({ + message, + font: "Standard", + }); + + await prompt({ + type: "end", + id: "winner", + title: ` + Programming isn't about what you know; + it's about making the command line look cool!`, + titleColor: "bgCyanBright", + titleTypography: "bold", + border: false, + }); + + msg({ type: "M_BAR" }); + + await endPrompt({ + title: "Thanks for playing!\n", + titleColor: "passionGradient", + titleTypography: "bold", + }); + + process.exit(0); +} + +await main().catch((error) => errorHandler(error)); diff --git a/examples/other/task.ts b/examples/other/task.ts new file mode 100644 index 0000000..8b1c7ae --- /dev/null +++ b/examples/other/task.ts @@ -0,0 +1,155 @@ +import { + inputPrompt, + msg, + selectPrompt, + startPrompt, + advancedTaskPrompt, + endPrompt, +} from "~/main.js"; +import { prompt } from "~/mono/mono.js"; +import { colorize } from "~/utils/colorize.js"; +import { errorHandler } from "~/utils/errors.js"; +import { createAsciiArt } from "~/visual/ascii-art/ascii-art.js"; + +async function main() { + console.clear(); + await startPrompt({ + title: "Task Component Example", + titleColor: "passionGradient", + titleTypography: "bold", + }); + + msg({ + type: "M_GENERAL", + title: "Who Wants to Be a JS Mil?", + titleColor: "gradientGradient", + }); + + msg({ + type: "M_GENERAL", + symbol: "middle", + title: ` + ${colorize("HOW TO PLAY", "white", "bold")} + I am a process on your computer. + If you get any question wrong I will be ${colorize("killed", "red", "bold")} + So get all the questions right... + `, + }); + + const player_name = await inputPrompt({ + title: "What is your name?", + defaultValue: "Player", + }); + const playerName = player_name ?? "Player"; + + const answer = await selectPrompt({ + title: "JavaScript was created in 10 days then released on", + options: [ + { label: "May 23rd, 1995", value: "May 23rd, 1995" }, + { label: "Nov 24th, 1995", value: "Nov 24th, 1995" }, + { label: "Dec 4th, 1995", value: "Dec 4th, 1995" }, + { label: "Dec 17, 1996", value: "Dec 17, 1996" }, + ], + }); + + const firstResult = await advancedTaskPrompt.group( + { priority: "normal" }, + (create) => [ + create( + "Check answer", + { + priority: "normal", + displayType: "spinner", + spinnerType: "arc", + exitProcessOnError: true, + }, + async ({ setError }) => { + const isCorrect = answer === "Dec 4th, 1995"; + + if (!isCorrect) { + setError(new Error(`🫠 Game over, ${playerName}! You lose!`)); + return false; + } + + return `Nice work ${playerName}. That's a legit answer!`; + }, + ), + ], + ); + + if (firstResult[0].result) { + const answer2 = await selectPrompt({ + title: "Which company created JavaScript?", + options: [ + { label: "Microsoft", value: "Microsoft" }, + { label: "Netscape", value: "Netscape" }, + { label: "Oracle", value: "Oracle" }, + { label: "Google", value: "Google" }, + ], + }); + + const secondResult = await advancedTaskPrompt.group( + { priority: "normal" }, + (create) => [ + create( + "Validate answer", + { + priority: "normal", + displayType: "spinner", + spinnerType: "arc", + }, + async ({ setError }) => { + const isCorrect = answer2 === "Netscape"; + if (!isCorrect) { + setError( + new Error(`Wrong! Netscape created JavaScript in 1995.`), + ); + return false; + } + return "Correct! Netscape created JavaScript."; + }, + ), + ], + ); + + if (secondResult[0].result === false) { + msg({ + type: "M_GENERAL", + title: "Game Over! You got the first one but missed the second.", + }); + process.exit(1); + } + + const message = `Congrats !\n $ 2 , 0 0 0 , 0 0 0`; + + await createAsciiArt({ + message, + font: "Standard", + }); + + await prompt({ + type: "end", + id: "winner", + title: ` + Programming isn't about what you know; + it's about making the command line look cool!`, + titleColor: "bgCyanBright", + titleTypography: "bold", + border: false, + }); + } else { + msg({ type: "M_GENERAL", title: "Better luck next time!" }); + } + + msg({ type: "M_BAR" }); + + await endPrompt({ + title: "Thanks for playing!\n", + titleColor: "passionGradient", + titleTypography: "bold", + }); + + process.exit(0); +} + +await main().catch((error) => errorHandler(error)); diff --git a/examples/separate/columns/auto-resize.ts b/examples/other/temp/auto-resize.ts similarity index 100% rename from examples/separate/columns/auto-resize.ts rename to examples/other/temp/auto-resize.ts diff --git a/examples/separate/columns/lorem-ipsum.ts b/examples/other/temp/lorem-ipsum.ts similarity index 100% rename from examples/separate/columns/lorem-ipsum.ts rename to examples/other/temp/lorem-ipsum.ts diff --git a/examples/separate/resizer/auto-resize.ts b/examples/other/temp/resizer-tables.ts similarity index 100% rename from examples/separate/resizer/auto-resize.ts rename to examples/other/temp/resizer-tables.ts diff --git a/examples/separate/columns/responsive-table.ts b/examples/other/temp/responsive-table.ts similarity index 100% rename from examples/separate/columns/responsive-table.ts rename to examples/other/temp/responsive-table.ts diff --git a/examples/separate/columns/terminal-columns.ts b/examples/other/temp/terminal-columns.ts similarity index 100% rename from examples/separate/columns/terminal-columns.ts rename to examples/other/temp/terminal-columns.ts diff --git a/examples/separate/fallback/enquirer.ts b/examples/other/temp/wrapper.ts similarity index 91% rename from examples/separate/fallback/enquirer.ts rename to examples/other/temp/wrapper.ts index 6832eef..056a23a 100644 --- a/examples/separate/fallback/enquirer.ts +++ b/examples/other/temp/wrapper.ts @@ -3,7 +3,7 @@ import { EnquirerWrapper } from "~/fallback/enquirer.temp.js"; const longText = - "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you think about testing the very very very long text? Is something broken for you?"; + "Let's embark on a creative journey and build something completely new! Afterward, it's all yours to refine. What category best describes your project? What web technologies do you like? 42 is the answer to everything. What do you mind about testing the very very very long text? Is something broken for you?"; async function main() { const enq = new EnquirerWrapper(); diff --git a/examples/src/prompts.ts b/examples/src/prompts.ts index 7f6c6b0..614c1be 100644 --- a/examples/src/prompts.ts +++ b/examples/src/prompts.ts @@ -2,9 +2,9 @@ import { detect } from "detect-package-manager"; import { emojify } from "node-emoji"; import pc from "picocolors"; -import { anykeyPrompt, task } from "~/main.js"; +import { anykeyPrompt, spinnerTaskPrompt } from "~/main.js"; import { multiselectPrompt } from "~/main.js"; -import { progressbar } from "~/main.js"; +import { progressTaskPrompt } from "~/main.js"; import { animateText, confirmPrompt, @@ -456,7 +456,7 @@ export async function showConfirmPrompt(username: string) { if (spinner) { await showSpinner(); - await showProgressBar(); + await showProgressbar(); } // A return value is unnecessary for prompts when the result is not needed later. @@ -467,7 +467,7 @@ export async function showConfirmPrompt(username: string) { // components, as they don't return any values. export async function showSpinner() { - await task({ + await spinnerTaskPrompt({ initialMessage: "Some long-running task is in progress...", successMessage: "Hooray! The long-running task was a success!", errorMessage: "An error occurred while the long-running task!", @@ -481,8 +481,8 @@ export async function showSpinner() { }); } -export async function showProgressBar() { - await progressbar({ +export async function showProgressbar() { + await progressTaskPrompt({ total: 100, width: 10, format: diff --git a/jsr.jsonc b/jsr.jsonc index 47dbd36..4af89ed 100644 --- a/jsr.jsonc +++ b/jsr.jsonc @@ -1,6 +1,6 @@ { "name": "@reliverse/prompts", - "version": "1.4.2", + "version": "1.4.4", "author": "blefnk", "license": "MIT", "exports": "./dist-jsr/main.ts", diff --git a/package.json b/package.json index 881a0b8..c4c0a5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@reliverse/prompts", - "version": "1.4.2", + "version": "1.4.4", "author": "blefnk", "type": "module", "description": "@reliverse/prompts is a powerful library that enables seamless, typesafe, and resilient prompts for command-line applications. Crafted with simplicity and elegance, it provides developers with an intuitive and robust way to build interactive CLIs.", @@ -56,25 +56,32 @@ ], "license": "MIT", "dependencies": { + "@alcalzone/ansi-tokenize": "^0.1.3", "@figliolia/chalk-animation": "^1.0.4", "@sinclair/typebox": "^0.34.12", "ansi-diff-stream": "^1.2.1", "ansi-escapes": "^7.0.0", + "auto-bind": "^5.0.1", + "cli-boxes": "^4.0.1", "cli-resize": "^2.0.8", "cli-spinners": "^3.2.0", "cli-styles": "^1.0.0", "cli-truncate": "^4.0.0", "cli-width": "^4.1.0", + "code-excerpt": "^4.0.0", "colorette": "^2.0.20", + "decamelize": "^6.0.0", "defu": "^6.1.4", "detect-package-manager": "^3.0.2", "enquirer": "^2.4.1", + "es-toolkit": "^1.30.1", "external-editor": "^3.1.0", "figlet": "^1.8.0", "fs-extra": "^11.2.0", "get-pixels": "^3.3.3", "globby": "^14.0.2", "gradient-string": "^3.0.0", + "is-in-ci": "^1.0.0", "is-unicode-supported": "^2.1.0", "kleur": "^4.1.5", "log-update": "^6.1.0", @@ -84,20 +91,29 @@ "node-emoji": "^2.2.0", "nypm": "^0.4.1", "ora": "^8.1.1", + "p-map": "^7.0.3", + "patch-console": "^2.0.0", "pathe": "^1.1.2", "picocolors": "^1.1.1", + "plur": "^5.1.0", "precision": "^1.0.1", + "read-package-up": "^11.0.0", "scule": "^1.3.0", "seventh": "^0.9.2", "signal-exit": "^4.1.0", "sisteransi": "^1.0.5", + "stack-utils": "^2.0.6", "std-env": "^3.8.0", "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "terminal-size": "^4.0.0", "ts-regex-builder": "^1.8.2", + "valtio": "^2.1.2", + "widest-line": "^5.0.0", "window-size": "^1.1.1", - "wrap-ansi": "^9.0.0" + "wrap-ansi": "^9.0.0", + "yoga-wasm-web": "^0.3.3", + "zod": "^3.24.1" }, "devDependencies": { "@arethetypeswrong/cli": "^0.17.2", @@ -106,6 +122,7 @@ "@eslint/js": "^9.17.0", "@eslint/json": "^0.9.0", "@eslint/markdown": "^6.2.1", + "@faker-js/faker": "^9.3.0", "@stylistic/eslint-plugin": "^2.12.1", "@types/ansi-diff-stream": "^1.2.3", "@types/bun": "^1.1.14", @@ -121,12 +138,14 @@ "@types/window-size": "^1.1.4", "@types/wrap-ansi": "^8.1.0", "bumpp": "^9.9.1", + "delay": "^6.0.0", "eslint": "^9.17.0", "eslint-plugin-perfectionist": "^4.4.0", "execa": "^9.5.2", "jiti": "^2.4.2", "knip": "^5.41.1", "mock-stdin": "^1.0.0", + "p-queue": "^8.0.1", "printj": "^1.3.1", "sentencer": "^0.2.1", "strip-comments": "^2.0.1", diff --git a/publish.ts b/publish.ts index ff39964..11bd982 100644 --- a/publish.ts +++ b/publish.ts @@ -1,8 +1,9 @@ // 👉 usage example: `bun pub --bump=1.2.3` -import { defineCommand, errorHandler, runMain } from "@reliverse/prompts"; import { execa } from "execa"; +import { defineCommand, errorHandler, runMain } from "~/main.js"; + const main = defineCommand({ meta: { name: "pub", diff --git a/src/checkbox/index.ts b/src/checkbox/index.ts index 00c91b3..f027066 100644 --- a/src/checkbox/index.ts +++ b/src/checkbox/index.ts @@ -1,7 +1,7 @@ import ansiEscapes from "ansi-escapes"; import pc from "picocolors"; -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/confirm/confirm-main.ts b/src/confirm/confirm-main.ts index 7568982..c0a9c97 100644 --- a/src/confirm/confirm-main.ts +++ b/src/confirm/confirm-main.ts @@ -6,7 +6,8 @@ import type { ColorName, TypographyName } from "~/types/general.js"; import type { VariantName } from "~/utils/variants.js"; import { colorize } from "~/utils/colorize.js"; -import { bar, msg, msgUndoAll } from "~/utils/messages.js"; +import { bar, msg } from "~/utils/messages.js"; +import { completePrompt } from "~/utils/prompt-end.js"; import { deleteLastLine } from "~/utils/terminal.js"; export type ConfirmPromptOptions = { @@ -124,47 +125,6 @@ function renderPrompt(params: { return uiLineCount; } -/** - * Ends the prompt by optionally displaying an end message and running the action if confirmed. - * Preserves the last prompt state unless there's an endTitle. - */ -async function endPrompt( - endTitle: string, - endTitleColor: ColorName, - titleTypography: TypographyName, - titleVariant: VariantName | undefined, - border: boolean, - borderColor: ColorName, - action?: () => Promise, - value?: boolean, -): Promise { - if (action && value) { - await action(); - } - - if (endTitle) { - // Only clear previous lines if we need to show an end title - msgUndoAll(); - msg({ - type: "M_END", - title: endTitle, - titleColor: endTitleColor, - titleTypography, - ...(titleVariant ? { titleVariant } : {}), - border, - borderColor, - }); - } else { - // Add a bar between prompts when there's no end title - msg({ - type: "M_BAR", - borderColor, - }); - } - - return value ?? false; -} - /** * Prompts the user with a yes/no question, returning a boolean based on their input. */ @@ -206,6 +166,29 @@ export async function confirmPrompt( let lastUILineCount = 0; + function endPrompt(isCtrlC = false): void { + if (endTitle !== "") { + msg({ + type: "M_END", + title: endTitle, + titleColor: endTitleColor, + titleTypography, + ...(titleVariant ? { titleVariant } : {}), + border, + borderColor, + }); + } + rl.close(); + if (isCtrlC) { + process.exit(0); + } + } + + // Handle Ctrl+C + rl.on("SIGINT", () => { + endPrompt(true); + }); + try { while (true) { // Clear only the previous UI lines if this is a re-render @@ -264,7 +247,8 @@ export async function confirmPrompt( continue; } - return await endPrompt( + return await completePrompt( + false, endTitle, endTitleColor, titleTypography, diff --git a/src/confirm/index.ts b/src/confirm/index.ts index a2f3ab5..74837b1 100644 --- a/src/confirm/index.ts +++ b/src/confirm/index.ts @@ -1,4 +1,4 @@ -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/core/core.test.ts b/src/core/core.test.ts index 629b95b..51254f4 100644 --- a/src/core/core.test.ts +++ b/src/core/core.test.ts @@ -1,3 +1,5 @@ +import type { WriteStream } from "node:tty"; + import ansiEscapes from "ansi-escapes"; import { AsyncResource } from "node:async_hooks"; import { Stream } from "node:stream"; @@ -598,7 +600,7 @@ describe("createPrompt()", () => { process.on("warning", warningSpy); // We need to reuse the same stream to ensure it gets cleaned up properly. - const output = new WritableStream(); + const output = new WritableStream() as unknown as WriteStream; for (let i = 0; i < 15; i++) { const { answer, events } = await render( prompt, diff --git a/src/core/create-prompt.ts b/src/core/create-prompt.ts index 77f347b..064bf33 100644 --- a/src/core/create-prompt.ts +++ b/src/core/create-prompt.ts @@ -3,20 +3,21 @@ import { AsyncResource } from "node:async_hooks"; import * as readline from "node:readline"; import { onExit as onSignalExit } from "signal-exit"; -import { type Prompt, type Prettify } from "~/types/index.js"; +import { type Prompt, type PromptConfig } from "~/types/index.js"; import { type BetterReadline } from "~/types/index.js"; import { AbortPromptError, CancelPromptError, ExitPromptError, + NonInteractiveError, } from "./errors.js"; import { withHooks, effectScheduler } from "./hook-engine.js"; import { PromisePolyfill } from "./promise-polyfill.js"; import ScreenManager from "./screen-manager.js"; type ViewFunction = ( - config: Prettify, + config: Config, done: (value: Value) => void, ) => string | [string, string | undefined]; @@ -38,14 +39,39 @@ function getCallSites() { } export function createPrompt(view: ViewFunction) { - const callSites = getCallSites(); - const callerFilename = callSites[1]?.getFileName?.(); + const callerFilename = getCallSites()[0]?.getFileName() ?? "unknown"; - const prompt: Prompt = (config, context = {}) => { + const prompt: Prompt = ( + config, + context = {}, + ) => { // Default `input` to stdin - const { input = process.stdin, signal } = context; + const { input = process.stdin, signal, nonInteractive = false } = context; const cleanups = new Set<() => void>(); + // Check if terminal is interactive + if (nonInteractive || !("isTTY" in input && input.isTTY)) { + // In non-interactive mode, generate prompts.json with default values or placeholders + const promptsJson = { + type: "prompts", + message: + "Please fill this file and run the CLI again to continue with your terminal, which doesn't support interactivity (or use tty-supported terminal)", + prompts: [ + { + name: "value", + message: config.message || "Input required", + type: "input", + default: config.default || "", + }, + ], + }; + + console.log(JSON.stringify(promptsJson, null, 2)); + throw new NonInteractiveError( + "Terminal does not support interactivity. A prompts.json file has been generated.", + ); + } + // Add mute capabilities to the output const output = new MuteStream(); output.pipe(context.output ?? process.stdout); @@ -165,3 +191,11 @@ export function createPrompt(view: ViewFunction) { return prompt; } + +export type PromptOptions = { + analytics?: { + enabled?: boolean; + askConsent?: boolean; + dataCollection?: string[]; + }; +}; diff --git a/src/core/errors.ts b/src/core/errors.ts index a843e62..300d9f3 100644 --- a/src/core/errors.ts +++ b/src/core/errors.ts @@ -1,20 +1,29 @@ export class AbortPromptError extends Error { - override name = "AbortPromptError"; - override message = "Prompt was aborted"; - - constructor(options?: { cause?: unknown }) { - super(); - this.cause = options?.cause; + constructor(options?: ErrorOptions) { + super("Prompt aborted", options); + this.name = "AbortPromptError"; } } export class CancelPromptError extends Error { - override name = "CancelPromptError"; - override message = "Prompt was canceled"; + constructor() { + super("Prompt cancelled"); + this.name = "CancelPromptError"; + } } export class ExitPromptError extends Error { - override name = "ExitPromptError"; + constructor(message: string) { + super(message); + this.name = "ExitPromptError"; + } +} + +export class NonInteractiveError extends Error { + constructor(message: string) { + super(message); + this.name = "NonInteractiveError"; + } } export class HookError extends Error { diff --git a/src/core/make-theme.ts b/src/core/make-theme.ts index c17f893..a8e309b 100644 --- a/src/core/make-theme.ts +++ b/src/core/make-theme.ts @@ -1,4 +1,5 @@ -import type { Prettify, PartialDeep } from "~/types/index.js"; +import type { Prettify } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { defaultTheme, type Theme } from "./theme.js"; diff --git a/src/editor/index.ts b/src/editor/index.ts index 63c6897..d6406da 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -3,7 +3,8 @@ import type { IFileOptions } from "external-editor"; import { editAsync } from "external-editor"; import { AsyncResource } from "node:async_hooks"; -import type { PartialDeep, BetterReadline } from "~/types/index.js"; +import type { BetterReadline } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/expand/index.ts b/src/expand/index.ts index 46389a8..36e7f21 100644 --- a/src/expand/index.ts +++ b/src/expand/index.ts @@ -1,6 +1,6 @@ import pc from "picocolors"; -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/flags/main.ts b/src/flags/main.ts index 4a44aef..2c72e64 100644 --- a/src/flags/main.ts +++ b/src/flags/main.ts @@ -1,12 +1,20 @@ import type { ArgsDef, CommandDef } from "./types.js"; -import { CLIError } from "./_utils.js"; +import { NonInteractiveError } from "../core/errors.js"; +import { CLIError, resolveValue } from "./_utils.js"; import { resolveSubCommand, runCommand } from "./command.js"; import { showUsage as _showUsage } from "./usage.js"; +export type NonInteractiveAction = { + onNonInteractive: (promptsJson: any) => Promise | void; + promptsJson?: any; +}; + export type RunMainOptions = { rawArgs?: string[]; showUsage?: typeof _showUsage; + nonInteractive?: boolean; + nonInteractiveAction?: NonInteractiveAction; }; export async function runMain( @@ -15,7 +23,47 @@ export async function runMain( ) { const rawArgs = opts.rawArgs || process.argv.slice(2); const showUsage = opts.showUsage || _showUsage; + const nonInteractive = opts.nonInteractive || !process.stdin.isTTY; + const nonInteractiveAction = opts.nonInteractiveAction; + try { + // Check for non-interactive mode first + if ( + nonInteractive && + !rawArgs.includes("--help") && + !rawArgs.includes("-h") && + !rawArgs.includes("--version") + ) { + // Resolve command metadata + const meta = await resolveValue(cmd.meta || {}); + const args = await resolveValue(cmd.args || {}); + + // Generate prompts.json with command structure and defaults + const promptsJson = nonInteractiveAction?.promptsJson || { + type: "prompts", + message: + "Please fill this file and run the CLI again to continue with your terminal, which doesn't support interactivity (or use tty-supported terminal)", + command: { + name: meta.name || process.argv[1], + description: meta.description || "", + version: meta.version || "", + args: args, + }, + }; + + if (nonInteractiveAction?.onNonInteractive) { + // Execute custom non-interactive action if provided + await nonInteractiveAction.onNonInteractive(promptsJson); + process.exit(0); // Exit successfully after executing the action + } else { + // Default behavior: print JSON and throw error + console.log(JSON.stringify(promptsJson, null, 2)); + throw new NonInteractiveError( + "Terminal does not support interactivity. A prompts.json file has been generated.", + ); + } + } + if (rawArgs.includes("--help") || rawArgs.includes("-h")) { await showUsage(...(await resolveSubCommand(cmd, rawArgs))); process.exit(0); @@ -31,12 +79,16 @@ export async function runMain( } } catch (error: any) { const isCLIError = error instanceof CLIError; - if (!isCLIError) { + const isNonInteractiveError = error instanceof NonInteractiveError; + + if (!isCLIError && !isNonInteractiveError) { console.error(error, "\n"); } + if (isCLIError) { await showUsage(...(await resolveSubCommand(cmd, rawArgs))); } + console.error(error.message); process.exit(1); } diff --git a/src/flags/mod.ts b/src/flags/mod.ts index 6d96527..73f7b5d 100644 --- a/src/flags/mod.ts +++ b/src/flags/mod.ts @@ -3,6 +3,21 @@ export type { RunCommandOptions } from "./command.js"; export type { RunMainOptions } from "./main.js"; export { defineCommand, runCommand } from "./command.js"; -export { parseArgs } from "./args.js"; export { renderUsage, showUsage } from "./usage.js"; export { runMain, createMain } from "./main.js"; + +// TODO: implement global flags +export function parseArgs(_args: string[]) { + return { + // Support both long and short forms + // e.g., --help, -h + options: { + help: ["-h", "--help"], + version: ["-v", "--version"], + // Add more standard options + }, + // Support grouping of short options + // e.g., -abc equivalent to -a -b -c + allowGrouping: true, + }; +} diff --git a/src/input/index.ts b/src/input/index.ts index 346f84a..7be45af 100644 --- a/src/input/index.ts +++ b/src/input/index.ts @@ -1,4 +1,4 @@ -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/input/input-main.ts b/src/input/input-main.ts index b199333..38dcb8f 100644 --- a/src/input/input-main.ts +++ b/src/input/input-main.ts @@ -14,6 +14,7 @@ import type { SymbolName } from "~/utils/messages.js"; import type { VariantName } from "~/utils/variants.js"; import { msg, msgUndoAll, bar } from "~/utils/messages.js"; +import { completePrompt } from "~/utils/prompt-end.js"; import { deleteLastLine } from "~/utils/terminal.js"; export type InputPromptOptions = { @@ -187,20 +188,26 @@ export async function inputPrompt( const rl = readline.createInterface({ input, output }); // Graceful Ctrl+C handling: - rl.on("SIGINT", () => { - if (endTitle !== "") { - msgUndoAll(); - msg({ - type: "M_END", - title: endTitle, - titleColor: endTitleColor, - titleTypography, - border, - borderColor, - }); - } + async function endPrompt(isCtrlC = false) { + await completePrompt( + isCtrlC, + endTitle, + endTitleColor, + titleTypography, + titleVariant ? titleVariant : undefined, + border, + borderColor, + undefined, + false, + ); rl.close(); - process.exit(0); + if (isCtrlC) { + process.exit(0); + } + } + + rl.on("SIGINT", () => { + void endPrompt(true); }); let currentInput = hardcoded?.userInput || ""; @@ -282,19 +289,7 @@ export async function inputPrompt( // Check for Ctrl+C or stream closed if (answerInput === null) { - if (endTitle !== "") { - msgUndoAll(); - msg({ - type: "M_END", - title: endTitle, - titleColor: endTitleColor, - titleTypography, - border, - borderColor, - }); - } - rl.close(); - process.exit(0); + void endPrompt(true); } currentInput = answerInput.trim(); diff --git a/src/multiselect/multiselect-main.ts b/src/multiselect/multiselect-main.ts index b8df0b0..e5d2e7c 100644 --- a/src/multiselect/multiselect-main.ts +++ b/src/multiselect/multiselect-main.ts @@ -7,7 +7,8 @@ import type { ColorName, TypographyName } from "~/types/general.js"; import type { VariantName } from "~/utils/variants.js"; import { deleteLastLine } from "~/main.js"; -import { msg, msgUndoAll, symbols } from "~/utils/messages.js"; +import { msg, symbols } from "~/utils/messages.js"; +import { completePrompt } from "~/utils/prompt-end.js"; type SelectOption = { label: string; @@ -264,7 +265,7 @@ export async function multiselectPrompt( debug = false, terminalWidth: customTerminalWidth = 90, displayInstructions = false, - allowAllUnselected = true, + allowAllUnselected = false, } = params; let pointer = @@ -427,13 +428,28 @@ export async function multiselectPrompt( input.setRawMode(false); } rl.close(); - input.removeListener("keypress", onKeyPress); + input.removeListener("keypress", handleKeypress); if (isCtrlC) { process.exit(0); } } - function confirmSelection() { + async function endPrompt(isCtrlC = false) { + await completePrompt( + isCtrlC, + endTitle, + endTitleColor, + titleTypography, + titleVariant ? titleVariant : undefined, + border, + borderColor, + undefined, + false, + ); + cleanup(isCtrlC); + } + + async function confirmSelection() { if (allowAllUnselected || selectedOptions.size > 0) { const selectedValues = Array.from(selectedOptions) .filter((idx) => { @@ -450,36 +466,29 @@ export async function multiselectPrompt( resolve(selectedValues); deleteLastLine(); - msg({ type: "M_BAR", titleColor }); - - // Don't clear the final state + await completePrompt( + false, + endTitle, + endTitleColor, + titleTypography, + titleVariant ? titleVariant : undefined, + border, + borderColor, + undefined, + true, + ); } else { + deleteLastLine(); errorMessage = "You must select at least one option."; renderOptions(); } } - function endPrompt(isCtrlC = false) { - // Don't clear anything unless there's an end title - if (endTitle !== "") { - msgUndoAll(); - msg({ - type: "M_END", - title: endTitle, - titleColor: endTitleColor, - ...(titleTypography ? { titleTypography } : {}), - ...(titleVariant ? { titleVariant } : {}), - border, - borderColor, - }); - } - cleanup(isCtrlC); - } - - function onKeyPress(_str: string, key: readline.Key) { + function handleKeypress(_str: string, key: readline.Key): void { if (allDisabled) { if (key.name === "c" && key.ctrl) { - endPrompt(true); + void endPrompt(true); + return; } return; } @@ -518,12 +527,12 @@ export async function multiselectPrompt( } case "return": - confirmSelection(); + void confirmSelection(); break; case "c": if (key.ctrl) { - endPrompt(true); + void endPrompt(true); } break; @@ -535,6 +544,6 @@ export async function multiselectPrompt( } } - input.on("keypress", onKeyPress); + input.on("keypress", handleKeypress); }); } diff --git a/src/number/index.ts b/src/number/index.ts index a666021..54effce 100644 --- a/src/number/index.ts +++ b/src/number/index.ts @@ -1,4 +1,4 @@ -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/number/number-main.ts b/src/number/number-main.ts index e53329e..497cc05 100644 --- a/src/number/number-main.ts +++ b/src/number/number-main.ts @@ -4,7 +4,7 @@ import readline from "node:readline/promises"; import type { ColorName, TypographyName } from "~/types/general.js"; -import { msg, msgUndoAll, bar, type FmtMsgOptions } from "~/utils/messages.js"; +import { msg, bar, type FmtMsgOptions } from "~/utils/messages.js"; import { deleteLastLine, deleteLastLines } from "~/utils/terminal.js"; type VariantName = FmtMsgOptions["titleVariant"]; @@ -136,7 +136,6 @@ export async function numberPrompt(opts: NumberPromptOptions): Promise { // Graceful Ctrl+C handling: rl.on("SIGINT", () => { if (endTitle !== "") { - msgUndoAll(); msg({ type: "M_END", title: endTitle, @@ -230,7 +229,6 @@ export async function numberPrompt(opts: NumberPromptOptions): Promise { // Check for Ctrl+C or stream closed if (answerInput === null) { if (endTitle !== "") { - msgUndoAll(); msg({ type: "M_END", title: endTitle, diff --git a/src/password/index.ts b/src/password/index.ts index de479b2..3020b64 100644 --- a/src/password/index.ts +++ b/src/password/index.ts @@ -1,6 +1,6 @@ import ansiEscapes from "ansi-escapes"; -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/progressbar/ProgressBar.ts b/src/progressbar/ProgressBar.ts deleted file mode 100644 index 37553e1..0000000 --- a/src/progressbar/ProgressBar.ts +++ /dev/null @@ -1,97 +0,0 @@ -import pc from "picocolors"; - -export type ProgressBarOptions = { - total: number; // Total units of work to complete - width?: number; // Width of the progress bar - completeChar?: string; // Character to represent completed progress - incompleteChar?: string; // Character to represent incomplete progress - format?: string; // Display format of the progress bar - colorize?: boolean; // Whether to colorize the progress bar -}; - -export class ProgressBar { - private total: number; - private current: number; - private width: number; - private completeChar: string; - private incompleteChar: string; - private startTime: number; - private format: string; - private colorize: boolean; - - constructor(options: ProgressBarOptions) { - if (options.total <= 0) { - throw new Error("Total must be a positive number"); - } - - this.total = options.total; - this.current = 0; - this.width = options.width || 40; - this.completeChar = options.completeChar || "█"; - this.incompleteChar = options.incompleteChar || "░"; - this.startTime = Date.now(); - this.format = - options.format || "Progress: [:bar] :percent% | Elapsed: :elapsed s"; - this.colorize = options.colorize || false; - } - - /** - * Update the progress bar to a specific value. - * @param value - The current progress value. - */ - update(value: number) { - const newValue = Math.min(value, this.total); - if (newValue !== this.current) { - this.current = newValue; - this.render(); - } - } - - /** - * Increment the progress bar by a specific amount. - * @param amount - The amount to increment. - */ - increment(amount = 1) { - this.update(this.current + amount); - } - - /** - * Render the progress bar. - */ - private render() { - const percent = this.current / this.total; - const filledLength = Math.round(this.width * percent); - const emptyLength = this.width - filledLength; - - let bar = - this.completeChar.repeat(filledLength) + - this.incompleteChar.repeat(emptyLength); - - if (this.colorize) { - bar = - pc.green(this.completeChar.repeat(filledLength)) + - pc.red(this.incompleteChar.repeat(emptyLength)); - } - - const percentage = (percent * 100).toFixed(2); - const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(2); - const eta = - percent > 0 - ? ((Date.now() - this.startTime) / percent / 1000).toFixed(2) - : "N/A"; - - const output = this.format - .replace(":bar", bar) - .replace(":percent", percentage) - .replace(":elapsed", elapsed) - .replace(":eta", eta); - - process.stdout.clearLine(0); - process.stdout.cursorTo(0); - process.stdout.write(pc.green("◆") + " " + output); - - if (this.current >= this.total) { - process.stdout.write("\n"); - } - } -} diff --git a/src/progressbar/index.ts b/src/progressbar/index.ts deleted file mode 100644 index f225583..0000000 --- a/src/progressbar/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { progressbar } from "./helper.js"; -export type { ProgressBarOptions } from "./ProgressBar.js"; diff --git a/src/prompts/index.ts b/src/prompts/index.ts index 27760f5..183f084 100644 --- a/src/prompts/index.ts +++ b/src/prompts/index.ts @@ -1,3 +1,7 @@ +export { NonInteractiveError } from "~/core/errors.js"; +export function isTerminalInteractive(input = process.stdin): boolean { + return Boolean(input.isTTY); +} export type { ColorName } from "~/types/general.js"; export type { ChoiceOptions } from "~/types/general.js"; export type { PromptOptions } from "~/types/general.js"; @@ -19,6 +23,8 @@ export { export { colorize } from "~/utils/colorize.js"; export { fmt, msg } from "~/utils/messages.js"; export { errorHandler } from "~/utils/errors.js"; +export { defineCommand } from "~/flags/command.js"; +export { runMain } from "~/flags/main.js"; export { colorMap } from "~/utils/mapping.js"; export { animateText } from "~/visual/animate/animate.js"; export { createAsciiArt } from "~/visual/ascii-art/ascii-art.js"; @@ -36,10 +42,9 @@ export { nextStepsPrompt } from "~/next-steps/next-steps.js"; export { numberPrompt } from "~/number/number-main.js"; export { passwordPrompt } from "~/password/password-main.js"; export { endPrompt } from "~/st-end/end.js"; -export { progressbar } from "~/progressbar/index.js"; +export * from "~/task/index.js"; export { promptsDisplayResults } from "~/results/results.js"; export { prompt } from "~/mono/mono.js"; -export { task } from "~/task/index.js"; export { default as block } from "~/block/block.js"; export { default as checkbox, Separator } from "~/checkbox/index.js"; export { default as expand } from "~/expand/index.js"; diff --git a/src/prompts/prompt.ts b/src/prompts/prompt.ts index 7f18350..4696899 100644 --- a/src/prompts/prompt.ts +++ b/src/prompts/prompt.ts @@ -9,6 +9,7 @@ import wrap from "wrap-ansi"; import type { State } from "~/types/general.js"; +import { NonInteractiveError } from "~/core/errors.js"; import { getTerminalWidth } from "~/core/utils.js"; function diffLines(a: string, b: string): number[] { @@ -56,6 +57,8 @@ export type PromptOptions = { input?: Readable; output?: Writable; debug?: boolean; + nonInteractive?: boolean; + message?: string; }; export default class Prompt { @@ -77,6 +80,7 @@ export default class Prompt { input = stdin, output = stdout, initialValue = "", + nonInteractive = false, ...opts }: PromptOptions, trackValue = true, @@ -91,6 +95,29 @@ export default class Prompt { this.input = input; this.output = output; + // Check for non-interactive mode + if (nonInteractive || !(this.input as typeof stdin).isTTY) { + // Generate prompts.json with default values or placeholders + const promptsJson = { + type: "prompts", + message: + "Please fill this file and run the CLI again to continue with your terminal, which doesn't support interactivity (or use tty-supported terminal)", + prompts: [ + { + name: "value", + message: opts.message || "Input required", + type: "input", + default: initialValue || "", + }, + ], + }; + + console.log(JSON.stringify(promptsJson, null, 2)); + throw new NonInteractiveError( + "Terminal does not support interactivity. A prompts.json file has been generated.", + ); + } + // Ensure `this.value` is always initialized, either from initialValue or as an empty string this.value = initialValue ?? ""; } diff --git a/src/rawlist/index.ts b/src/rawlist/index.ts index 0ce07f3..a65bb9e 100644 --- a/src/rawlist/index.ts +++ b/src/rawlist/index.ts @@ -1,6 +1,6 @@ import pc from "picocolors"; -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/search/index.ts b/src/search/index.ts index bcda58d..3447dfa 100644 --- a/src/search/index.ts +++ b/src/search/index.ts @@ -1,6 +1,6 @@ import pc from "picocolors"; -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/select/index.ts b/src/select/index.ts index 33f17e7..f46f651 100644 --- a/src/select/index.ts +++ b/src/select/index.ts @@ -1,7 +1,7 @@ import ansiEscapes from "ansi-escapes"; import pc from "picocolors"; -import type { PartialDeep } from "~/types/index.js"; +import type { PartialDeep } from "~/types/utils.js"; import { createPrompt, diff --git a/src/select/select-main.ts b/src/select/select-main.ts index 59a8c07..672e7a3 100644 --- a/src/select/select-main.ts +++ b/src/select/select-main.ts @@ -7,7 +7,8 @@ import type { ColorName, TypographyName } from "~/types/general.js"; import type { VariantName } from "~/utils/variants.js"; import { deleteLastLine } from "~/main.js"; -import { msg, msgUndoAll, symbols } from "~/utils/messages.js"; +import { msg, symbols } from "~/utils/messages.js"; +import { completePrompt } from "~/utils/prompt-end.js"; type SelectOption = { label: string; @@ -257,7 +258,7 @@ export async function selectPrompt( contentTypography = "italic", border = true, endTitle = "", - endTitleColor = "dim", + endTitleColor = "retroGradient", maxItems, debug = false, terminalWidth: customTerminalWidth = 90, @@ -350,10 +351,11 @@ export async function selectPrompt( }); return new Promise((resolve) => { - function onKeyPress(_str: string, key: readline.Key) { + function handleKeypress(_str: string, key: readline.Key): void { if (allDisabled) { if (key.name === "c" && key.ctrl) { - endPrompt(true); + void endPrompt(true); + return; } return; } @@ -363,9 +365,9 @@ export async function selectPrompt( } else if (key.name === "down" || key.name === "j") { moveSelectionDown(); } else if (key.name === "return") { - confirmSelection(); + void confirmSelection(); } else if (key.name === "c" && key.ctrl) { - endPrompt(true); + void endPrompt(true); } } @@ -393,7 +395,7 @@ export async function selectPrompt( renderOptions(); } - function confirmSelection() { + async function confirmSelection() { const option = options[selectedIndex]; if (!option || !isSelectOption(option)) { errorMessage = "This option is not selectable."; @@ -417,25 +419,31 @@ export async function selectPrompt( resolve(option.value); deleteLastLine(); - msg({ type: "M_BAR", borderColor }); - - // We don't clear the final state + await completePrompt( + false, + endTitle, + endTitleColor, + titleTypography, + titleVariant ? titleVariant : undefined, + border, + borderColor, + undefined, + true, + ); } - function endPrompt(isCtrlC = false) { - // Don't clear anything unless there's an end title - if (endTitle !== "") { - msgUndoAll(); - msg({ - type: "M_END", - title: endTitle, - titleColor: endTitleColor, - titleTypography, - ...(titleVariant ? { titleVariant } : {}), - border, - borderColor, - }); - } + async function endPrompt(isCtrlC = false) { + await completePrompt( + isCtrlC, + endTitle, + endTitleColor, + titleTypography, + titleVariant ? titleVariant : undefined, + border, + borderColor, + undefined, + false, + ); cleanup(isCtrlC); } @@ -444,13 +452,12 @@ export async function selectPrompt( input.setRawMode(false); } rl.close(); - input.removeListener("keypress", onKeyPress); - + input.removeListener("keypress", handleKeypress); if (isCtrlC) { process.exit(0); } } - input.on("keypress", onKeyPress); + input.on("keypress", handleKeypress); }); } diff --git a/src/progressbar/helper.ts b/src/task/helper.ts similarity index 73% rename from src/progressbar/helper.ts rename to src/task/helper.ts index 7ec93dd..2349349 100644 --- a/src/progressbar/helper.ts +++ b/src/task/helper.ts @@ -1,8 +1,8 @@ import { msg } from "~/utils/messages.js"; -import type { ProgressBarOptions } from "./ProgressBar.js"; +import type { ProgressBarOptions } from "./types.js"; -import { ProgressBar } from "./ProgressBar.js"; +import { progressTaskPrompt } from "./progress.js"; /** * Options for the progressbar helper function. @@ -43,31 +43,32 @@ export async function progressbar( const iterations = Math.ceil(total / increment) + 1; const delay = desiredTotalTime / iterations; - const progressBar = new ProgressBar({ + const progressBar = await progressTaskPrompt({ total, ...progressBarOptions, }); try { for (let i = 0; i <= total; i += increment) { - progressBar.update(i); + await progressBar.update(i); await sleep(delay); } - // Ensure the progress bar completes if not already if (total % increment !== 0) { - progressBar.update(total); + await progressBar.update(total); } + + msg({ + type: "M_MIDDLE", + title: "", + borderColor: "dim", + }); } catch (error) { - console.error("Progress bar encountered an error:", error); + const errorMessage = + error instanceof Error ? error.message : "Progress bar error"; + console.error("Progress bar encountered an error:", errorMessage); + throw new Error(errorMessage); } - - // New line - msg({ - type: "M_MIDDLE", - title: "", - borderColor: "dim", - }); } /** diff --git a/src/task/index.ts b/src/task/index.ts index f14c4a4..e8ef1c0 100644 --- a/src/task/index.ts +++ b/src/task/index.ts @@ -1,159 +1,5 @@ -import { type SpinnerName } from "cli-spinners"; -import process from "node:process"; -import ora from "ora"; -import pc from "picocolors"; -import { cursor, erase } from "sisteransi"; - -import { msg } from "~/utils/messages.js"; - -type SimpleSpinnerType = "default" | "dottedCircle" | "boxSpinner"; -type OraSpinnerType = Extract; -type OraAllowedSpinners = "dots" | "bouncingBar" | "arc"; - -type TaskOptions = { - initialMessage: string; - successMessage?: string; - errorMessage?: string; - delay?: number; - spinnerSolution: T; - spinnerType?: T extends "simple" ? SimpleSpinnerType : OraSpinnerType; - action: (updateMessage: (message: string) => void) => Promise; -}; - -export async function task( - options: TaskOptions, -): Promise { - const { - initialMessage, - successMessage = "Task completed successfully.", - errorMessage = "An error occurred during the task.", - delay = 100, - spinnerSolution, - spinnerType, - action, - } = options; - - let message = initialMessage; - let interval: NodeJS.Timer | null = null; - let frameIndex = 0; - - if (spinnerSolution === "ora") { - const oraSpinner = ora({ - text: initialMessage, - spinner: spinnerType as OraSpinnerType, - }); - - try { - oraSpinner.start(); - - await action((newMessage: string) => { - message = newMessage; - oraSpinner.text = newMessage; - }); - - oraSpinner.stop(); - - msg({ - type: "M_INFO", - title: successMessage, - titleColor: "cyan", - }); - } catch (error) { - oraSpinner.stopAndPersist({ - symbol: pc.red("✖"), - text: errorMessage, - }); - - msg({ - type: "M_ERROR", - title: - error instanceof Error ? error.message : "An unknown error occurred.", - titleColor: "red", - }); - - process.exit(1); - } - } else { - const simpleSpinners = { - default: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"], - dottedCircle: ["○", "◔", "◑", "◕", "●"], - boxSpinner: ["▖", "▘", "▝", "▗"], - }; - - const frames = - spinnerType && spinnerType in simpleSpinners - ? simpleSpinners[spinnerType as SimpleSpinnerType] - : simpleSpinners.default; - - const handleInput = (data: Buffer) => { - const key = data.toString(); - if (key === "\r" || key === "\n") { - return; - } - }; - - try { - if ( - process.stdin.isTTY && - typeof process.stdin.setRawMode === "function" - ) { - process.stdin.setRawMode(true); - process.stdin.resume(); - process.stdin.on("data", handleInput); - } - - interval = setInterval(() => { - const frame = pc.magenta(frames[frameIndex]); - process.stdout.write( - `${cursor.move(-999, 0)}${erase.line}${frame} ${pc.cyan(message)}`, - ); - frameIndex = (frameIndex + 1) % frames.length; - }, delay); - - await action((newMessage: string) => { - message = newMessage; - }); - - clearInterval(interval); - interval = null; - - process.stdout.write( - `\r${erase.line}${pc.green("✔")} ${successMessage}\n`, - ); - - msg({ - type: "M_INFO", - title: successMessage, - titleColor: "cyan", - }); - } catch (error) { - if (interval) { - clearInterval(interval); - } - - process.stdout.write( - `\r${erase.line}${pc.red("✖")} ${ - error instanceof Error ? errorMessage : "An unknown error occurred." - }\n`, - ); - - msg({ - type: "M_ERROR", - title: - error instanceof Error ? error.message : "An unknown error occurred.", - titleColor: "red", - }); - - process.exit(1); - } finally { - if ( - process.stdin.isTTY && - typeof process.stdin.setRawMode === "function" - ) { - process.stdin.setRawMode(false); - process.stdin.pause(); - process.stdin.removeListener("data", handleInput); - } - } - } -} +export type { ProgressBarOptions } from "./types.js"; +export type { TaskAPI, TaskGroupAPI } from "./task.js"; +export { progressTaskPrompt } from "./progress.js"; +export { spinnerTaskPrompt } from "./spinner.js"; +export { default as advancedTaskPrompt } from "./task.js"; diff --git a/src/task/progress.ts b/src/task/progress.ts new file mode 100644 index 0000000..422dac9 --- /dev/null +++ b/src/task/progress.ts @@ -0,0 +1,79 @@ +import pc from "picocolors"; +import { cursor, erase } from "sisteransi"; + +import type { ProgressBar, ProgressBarOptions } from "./types.js"; + +export async function progressTaskPrompt( + options: ProgressBarOptions, +): Promise { + if (options.total <= 0) { + throw new Error("Total must be a positive number"); + } + + const state = { + total: options.total, + current: 0, + width: options.width ?? 40, + completeChar: options.completeChar ?? "█", + incompleteChar: options.incompleteChar ?? "░", + startTime: Date.now(), + format: + options.format ?? "Progress: [:bar] :percent% | Elapsed: :elapsed s", + colorize: options.colorize ?? false, + }; + + const getElapsedTime = () => { + return ((Date.now() - state.startTime) / 1000).toFixed(2); + }; + + const getPercentage = () => { + return ((state.current / state.total) * 100).toFixed(2); + }; + + const getBar = () => { + const percent = state.current / state.total; + const filledLength = Math.round(state.width * percent); + const emptyLength = state.width - filledLength; + + const filled = state.completeChar.repeat(filledLength); + const empty = state.incompleteChar.repeat(emptyLength); + + return state.colorize ? pc.green(filled) + pc.red(empty) : filled + empty; + }; + + const render = async () => { + const bar = getBar(); + const percentage = getPercentage(); + const elapsed = getElapsedTime(); + + const output = state.format + .replace(":bar", bar) + .replace(":percent", percentage) + .replace(":elapsed", elapsed); + + process.stdout.write(cursor.move(-999, 0) + erase.line); + process.stdout.write(pc.green("◆") + " " + output); + + if (state.current >= state.total) { + process.stdout.write("\n"); + } + }; + + const update = async (value: number) => { + const newValue = Math.min(value, state.total); + if (newValue !== state.current) { + state.current = newValue; + await render(); + } + }; + + const increment = async (amount = 1) => { + await update(state.current + amount); + }; + + return { + update, + increment, + render, + }; +} diff --git a/src/task/spinner.ts b/src/task/spinner.ts new file mode 100644 index 0000000..8b7eac3 --- /dev/null +++ b/src/task/spinner.ts @@ -0,0 +1,159 @@ +import { type SpinnerName } from "cli-spinners"; +import process from "node:process"; +import ora from "ora"; +import pc from "picocolors"; +import { cursor, erase } from "sisteransi"; + +import { msg } from "~/utils/messages.js"; + +type SimpleSpinnerType = "default" | "dottedCircle" | "boxSpinner"; +type OraSpinnerType = Extract; +type OraAllowedSpinners = "dots" | "bouncingBar" | "arc"; + +type TaskOptions = { + initialMessage: string; + successMessage?: string; + errorMessage?: string; + delay?: number; + spinnerSolution: T; + spinnerType?: T extends "simple" ? SimpleSpinnerType : OraSpinnerType; + action: (updateMessage: (message: string) => void) => Promise; +}; + +export async function spinnerTaskPrompt( + options: TaskOptions, +): Promise { + const { + initialMessage, + successMessage = "Task completed successfully.", + errorMessage = "An error occurred during the task.", + delay = 100, + spinnerSolution, + spinnerType, + action, + } = options; + + let message = initialMessage; + let interval: NodeJS.Timer | null = null; + let frameIndex = 0; + + if (spinnerSolution === "ora") { + const oraSpinner = ora({ + text: initialMessage, + spinner: spinnerType as OraSpinnerType, + }); + + try { + oraSpinner.start(); + + await action((newMessage: string) => { + message = newMessage; + oraSpinner.text = newMessage; + }); + + oraSpinner.stop(); + + msg({ + type: "M_INFO", + title: successMessage, + titleColor: "cyan", + }); + } catch (error) { + oraSpinner.stopAndPersist({ + symbol: pc.red("✖"), + text: errorMessage, + }); + + msg({ + type: "M_ERROR", + title: + error instanceof Error ? error.message : "An unknown error occurred.", + titleColor: "red", + }); + + process.exit(1); + } + } else { + const simpleSpinners = { + default: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"], + dottedCircle: ["○", "◔", "◑", "◕", "●"], + boxSpinner: ["▖", "▘", "▝", "▗"], + }; + + const frames = + spinnerType && spinnerType in simpleSpinners + ? simpleSpinners[spinnerType as SimpleSpinnerType] + : simpleSpinners.default; + + const handleInput = (data: Buffer) => { + const key = data.toString(); + if (key === "\r" || key === "\n") { + return; + } + }; + + try { + if ( + process.stdin.isTTY && + typeof process.stdin.setRawMode === "function" + ) { + process.stdin.setRawMode(true); + process.stdin.resume(); + process.stdin.on("data", handleInput); + } + + interval = setInterval(() => { + const frame = pc.magenta(frames[frameIndex]); + process.stdout.write( + `${cursor.move(-999, 0)}${erase.line}${frame} ${pc.cyan(message)}`, + ); + frameIndex = (frameIndex + 1) % frames.length; + }, delay); + + await action((newMessage: string) => { + message = newMessage; + }); + + clearInterval(interval); + interval = null; + + process.stdout.write( + `\r${erase.line}${pc.green("✔")} ${successMessage}\n`, + ); + + msg({ + type: "M_INFO", + title: successMessage, + titleColor: "cyan", + }); + } catch (error) { + if (interval) { + clearInterval(interval); + } + + process.stdout.write( + `\r${erase.line}${pc.red("✖")} ${ + error instanceof Error ? errorMessage : "An unknown error occurred." + }\n`, + ); + + msg({ + type: "M_ERROR", + title: + error instanceof Error ? error.message : "An unknown error occurred.", + titleColor: "red", + }); + + process.exit(1); + } finally { + if ( + process.stdin.isTTY && + typeof process.stdin.setRawMode === "function" + ) { + process.stdin.setRawMode(false); + process.stdin.pause(); + process.stdin.removeListener("data", handleInput); + } + } + } +} diff --git a/src/task/task.ts b/src/task/task.ts new file mode 100644 index 0000000..468a0b3 --- /dev/null +++ b/src/task/task.ts @@ -0,0 +1,733 @@ +import type { Options } from "p-map"; + +import process from "node:process"; +import ora from "ora"; +import pMap from "p-map"; +import pc from "picocolors"; +import { cursor, erase } from "sisteransi"; +import { proxy, subscribe } from "valtio"; + +import type { ProgressBar } from "~/task/types.js"; + +import { msg } from "~/utils/messages.js"; + +import { progressTaskPrompt } from "./progress.js"; + +type SimpleSpinnerType = "default" | "dottedCircle" | "boxSpinner"; + +type State = + | "pending" + | "loading" + | "error" + | "warning" + | "success" + | "cancelled"; +type Priority = "low" | "normal" | "high" | "critical"; + +export type TaskProgress = { + current: number; + total: number; + message?: string; +}; + +export type TaskObject = { + id: string; + title: string; + state: State; + children: TaskObject[]; + status?: string; + output?: string; + error?: Error; + priority: Priority; + progress?: TaskProgress; + progressBar?: ProgressBar; + startTime?: number; + endTime?: number; + duration?: number; + cancelToken?: AbortController; +}; + +export type TaskList = TaskObject[] & { + isRoot?: boolean; +}; + +export type TaskInnerAPI = { + task: Task; + setTitle(title: string): void; + setStatus(status?: string): void; + setWarning(warning?: Error | string): void; + setError(error?: Error | string): void; + setOutput(output: string | { message: string }): void; + setProgress(progress: TaskProgress): void; + updateProgress(current: number, total?: number, message?: string): void; + cancel(): void; + isCancelled(): boolean; +}; + +export type TaskFunction = (innerApi: TaskInnerAPI) => Promise; + +export const runSymbol: unique symbol = Symbol("run"); + +export type RegisteredTask = { + [runSymbol]: () => Promise; + task: TaskObject; + clear: () => void; + cancel: () => void; +}; + +export type TaskAPI = { + result: Result; + state: State; + clear: () => void; + cancel: () => void; + progress?: TaskProgress; + duration?: number; +}; + +export type Task = (( + title: string, + options: { priority: Priority } & Partial, + taskFunction: TaskFunction, +) => Promise>) & { group: TaskGroup }; + +export type TaskGroupAPI = Results & { + clear(): void; + cancel(): void; +}; + +export type CreateTask = ( + title: string, + options: { priority: Priority } & Partial, + taskFunction: TaskFunction, +) => RegisteredTask; + +type TaskGroup = ( + options: Options & { priority?: Priority }, + createTasks: (taskCreator: CreateTask) => [...T], +) => Promise< + TaskGroupAPI< + { + [K in keyof T]: T[K] extends RegisteredTask ? TaskAPI : never; + }[number][] + > +>; + +type SpinnerType = + // Simple spinners + | "default" + | "dottedCircle" + | "boxSpinner" + // Ora spinners + | "dots" + | "bouncingBar" + | "arc"; + +type TaskDisplayType = "spinner" | "progress"; + +export type TaskOptions = { + displayType?: TaskDisplayType; + verificationSteps?: number; + stepDelay?: number; + initialDelay?: number; + exitProcessOnError?: boolean; + spinnerType?: SpinnerType; +}; + +type SpinnerTaskOptions = { + initialMessage: string; + errorMessage?: string; + delay?: number; + spinnerType?: SpinnerType; + action: (updateMessage: (message: string) => void) => Promise; +}; + +// Utility functions +function generateTaskId(): string { + return Math.random().toString(36).substring(2, 15); +} + +function arrayAdd(array: T[], element: T) { + const index = array.push(element) - 1; + return array[index]; +} + +function arrayRemove(array: T[], element: T) { + const index = array.indexOf(element); + if (index > -1) { + array.splice(index, 1); + } +} + +function registerTask( + taskList: TaskList, + taskTitle: string, + taskFunction: TaskFunction, + priority: Priority = "normal", + options: TaskOptions = {}, +): RegisteredTask { + const { + displayType = "spinner", + verificationSteps = 0, + stepDelay = 400, + initialDelay = 0, + exitProcessOnError = true, + spinnerType = "default", + } = options; + + const cancelToken = new AbortController(); + const task = arrayAdd(taskList, { + id: generateTaskId(), + title: taskTitle, + state: "pending", + children: [], + priority, + cancelToken: undefined, + }); + + task.cancelToken = cancelToken; + + // Subscribe to state changes for timing information + subscribe(task, () => { + if (task.state === "loading" && !task.startTime) { + task.startTime = Date.now(); + } else if ( + ["success", "error", "cancelled"].includes(task.state) && + task.startTime && + !task.endTime + ) { + task.endTime = Date.now(); + task.duration = task.endTime - task.startTime; + } + }); + + // Set up spinner + const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; + let frameIndex = 0; + let interval: NodeJS.Timer | null = null; + + // Function to render the current state + const render = async () => { + process.stdout.write(cursor.move(-999, 0) + erase.line); + + if (displayType === "spinner") { + if ( + spinnerType === "dots" || + spinnerType === "bouncingBar" || + spinnerType === "arc" + ) { + // Use ora for these spinner types + const oraSpinner = ora({ + text: task.title + (task.status ? ` - ${task.status}` : ""), + spinner: spinnerType, + }); + oraSpinner.start(); + } else { + // Use simple spinners for the rest + const simpleSpinners = { + default: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"], + dottedCircle: ["○", "", "◑", "◕", "●"], + boxSpinner: ["▖", "▘", "▝", "▗"], + }; + const frames = spinnerType + ? simpleSpinners[spinnerType] + : simpleSpinners.default; + const currentFrame = pc.magenta(frames[frameIndex]); + process.stdout.write(`${currentFrame} ${pc.cyan(task.title)}`); + if (task.status) { + process.stdout.write(` - ${task.status}`); + } + } + } else { + // Render progress bar using progressTaskPrompt + if (task.progress) { + const { current, total, message } = task.progress; + if (!task.progressBar) { + task.progressBar = await progressTaskPrompt({ + total, + width: 20, + completeChar: "█", + incompleteChar: "░", + format: `:bar :percent% ${message || ""}`, + colorize: true, + }); + } + await task.progressBar.update(current); + } + } + }; + + const clearLine = () => { + if (interval) { + clearInterval(interval); + interval = null; + } + const statusIcon = + task.state === "success" + ? "✅" + : task.state === "error" || task.state === "cancelled" + ? "❌" + : ""; + + // Clear current line + process.stdout.write(cursor.move(-999, 0) + erase.line); + + // Only write final status if we have a state change + if (task.state !== "loading") { + // Write status with proper styling + if (task.state === "success") { + process.stdout.write( + `${statusIcon} ${pc.cyan(task.title)}${task.status ? ` - ${pc.greenBright(task.status)}` : ""}\n`, + ); + } else if (task.state === "error" || task.state === "cancelled") { + process.stdout.write( + `${statusIcon} ${pc.cyan(task.title)}${task.status ? ` - ${pc.red(task.status)}` : ""}\n`, + ); + if (task.error?.message) { + process.stdout.write(` ${pc.red(task.error.message)}\n`); + } + } else { + process.stdout.write( + `${statusIcon} ${pc.cyan(task.title)}${task.status ? ` - ${task.status}` : ""}\n`, + ); + } + } + }; + + // Start spinner when task starts + subscribe(task, () => { + if (task.state === "loading" && !interval) { + interval = setInterval(() => { + frameIndex = (frameIndex + 1) % frames.length; + void render(); + }, 80); + } else if (task.state !== "loading") { + clearLine(); + } + }); + + return { + task, + async [runSymbol]() { + const api = createTaskInnerApi(task); + task.state = "loading"; + + try { + if (cancelToken.signal.aborted) { + throw new Error("Task was cancelled before starting"); + } + + // Add automated verification steps + api.setStatus("Checking..."); + await new Promise((resolve) => setTimeout(resolve, initialDelay)); + + for (let i = 0; i < verificationSteps; i++) { + api.setStatus(`Verifying... (${i + 1}/${verificationSteps})`); + await new Promise((resolve) => setTimeout(resolve, stepDelay)); + } + + const taskResult = await taskFunction(api); + + if (cancelToken.signal.aborted) { + throw new Error("Task was cancelled during execution"); + } + + // If taskResult is a string, use it as the final status + if (typeof taskResult === "string") { + api.setStatus(taskResult); + } + + if (task.state === "loading") { + task.state = "success"; + } + return taskResult; + } catch (error) { + if (cancelToken.signal.aborted) { + task.state = "cancelled"; + } else if (error instanceof Error) { + api.setError(error); + } else { + api.setError(new Error(String(error))); + } + if (exitProcessOnError) { + process.exit(1); + } + throw error; + } + }, + clear() { + clearLine(); + arrayRemove(taskList, task); + }, + cancel() { + clearLine(); + cancelToken.abort(); + task.state = "cancelled"; + }, + }; +} + +// Create and export the root task list and default task function +const rootTaskList = proxy([]); + +// Add a task state manager +const taskStateManager = new Map(); + +function advancedTaskPrompt(taskList: TaskList): Task { + const task = (async ( + title: string, + options: { priority: Priority } & Partial, + taskFunction: TaskFunction, + ) => { + const { priority, ...taskOptions } = options; + const registeredTask = registerTask( + taskList, + title, + taskFunction, + priority, + taskOptions, + ); + + try { + taskStateManager.set(registeredTask.task.id, true); + const result = await registeredTask[runSymbol](); + taskStateManager.delete(registeredTask.task.id); + + return { + result, + get state() { + return registeredTask.task.state; + }, + get progress() { + return registeredTask.task.progress; + }, + get duration() { + return registeredTask.task.duration; + }, + clear: registeredTask.clear, + cancel: registeredTask.cancel, + }; + } catch (error) { + taskStateManager.delete(registeredTask.task.id); + if (registeredTask.task.cancelToken?.signal.aborted) { + return { + result: undefined, + state: "cancelled" as const, + clear: registeredTask.clear, + cancel: registeredTask.cancel, + }; + } + throw error; + } + }) as Task; + + task.group = async ( + options: Options & { priority?: Priority }, + createTasks: (taskCreator: CreateTask) => [...T], + ): Promise< + TaskGroupAPI< + { + [K in keyof T]: T[K] extends RegisteredTask + ? TaskAPI + : never; + }[number][] + > + > => { + const { + priority = "normal", + concurrency = 1, + stopOnError = true, + signal, + } = options; + const tasksQueue = createTasks((title, options, taskFunction) => { + const { priority: taskPriority = priority, ...taskOptions } = options; + return registerTask( + taskList, + title, + taskFunction, + taskPriority, + taskOptions, + ); + }); + + // Sort tasks by priority + const sortedTasks = [...tasksQueue].sort((a, b) => { + const priorityOrder = { critical: 3, high: 2, normal: 1, low: 0 }; + return priorityOrder[b.task.priority] - priorityOrder[a.task.priority]; + }); + + // Execute tasks concurrently using p-map + const results = (await pMap( + sortedTasks, + async (taskApi) => { + try { + taskStateManager.set(taskApi.task.id, true); + const result = await taskApi[runSymbol](); + taskStateManager.delete(taskApi.task.id); + + return { + result, + get state() { + return taskApi.task.state; + }, + get progress() { + return taskApi.task.progress; + }, + get duration() { + return taskApi.task.duration; + }, + clear: taskApi.clear, + cancel: taskApi.cancel, + }; + } catch (error) { + taskStateManager.delete(taskApi.task.id); + if (taskApi.task.cancelToken?.signal.aborted) { + return { + result: undefined, + state: "cancelled" as const, + clear: taskApi.clear, + cancel: taskApi.cancel, + }; + } + throw error; + } + }, + { + concurrency, + stopOnError, + signal, + }, + )) as unknown as { + [K in keyof T]: T[K] extends RegisteredTask ? TaskAPI : never; + }[number][]; + + return Object.assign(results, { + clear() { + for (const taskApi of tasksQueue) { + taskApi.clear(); + } + }, + cancel() { + for (const taskApi of tasksQueue) { + taskApi.cancel(); + } + }, + }); + }; + + return task; +} + +// Task management functionality +const createTaskInnerApi = (taskState: TaskObject): TaskInnerAPI => { + const api: TaskInnerAPI = { + task: advancedTaskPrompt(taskState.children), + setTitle(title) { + taskState.title = title; + }, + setStatus(status) { + taskState.status = status; + }, + setOutput(output) { + taskState.output = + typeof output === "string" + ? output + : "message" in output + ? output.message + : ""; + }, + setWarning(warning) { + taskState.state = "warning"; + if (warning !== undefined) { + api.setOutput(warning); + if (warning instanceof Error) { + taskState.error = warning; + } + } + }, + setError(error) { + taskState.state = "error"; + if (error !== undefined) { + api.setOutput(error); + if (error instanceof Error) { + taskState.error = error; + } + } + }, + setProgress(progress) { + taskState.progress = progress; + }, + updateProgress(current: number, total?: number, message?: string) { + const currentProgress = taskState.progress || { current: 0, total: 100 }; + taskState.progress = { + current, + total: total ?? currentProgress.total, + message: message ?? currentProgress.message, + }; + }, + cancel() { + if (taskState.cancelToken) { + taskState.cancelToken.abort(); + taskState.state = "cancelled"; + } + }, + isCancelled() { + return taskState.cancelToken?.signal.aborted || false; + }, + }; + return api; +}; + +// Update spinnerTask to use the new SpinnerType +export async function spinnerTask(options: SpinnerTaskOptions): Promise { + const { + initialMessage, + errorMessage = "An error occurred during the task.", + delay = 100, + spinnerType = "default", + action, + } = options; + + let message = initialMessage; + let interval: NodeJS.Timer | null = null; + let frameIndex = 0; + + // Use ora for its spinner types + if ( + spinnerType === "dots" || + spinnerType === "bouncingBar" || + spinnerType === "arc" + ) { + const oraSpinner = ora({ + text: initialMessage, + spinner: spinnerType, + }); + + try { + oraSpinner.start(); + + await action((newMessage: string) => { + message = newMessage; + oraSpinner.text = newMessage; + }); + + oraSpinner.stop(); + } catch (error) { + oraSpinner.stopAndPersist({ + symbol: pc.red("✖"), + text: errorMessage, + }); + + msg({ + type: "M_ERROR", + title: + error instanceof Error ? error.message : "An unknown error occurred.", + titleColor: "red", + }); + + process.exit(1); + } + } else { + // Use simple spinners + const simpleSpinners = { + default: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"], + dottedCircle: ["○", "", "◑", "◕", "●"], + boxSpinner: ["▖", "▘", "▝", "▗"], + }; + + const frames = + spinnerType && spinnerType in simpleSpinners + ? simpleSpinners[spinnerType as SimpleSpinnerType] + : simpleSpinners.default; + + const handleInput = (data: Buffer) => { + const key = data.toString(); + if (key === "\r" || key === "\n") { + return; + } + }; + + try { + if ( + process.stdin.isTTY && + typeof process.stdin.setRawMode === "function" + ) { + process.stdin.setRawMode(true); + process.stdin.resume(); + process.stdin.on("data", handleInput); + } + + interval = setInterval(() => { + const frame = pc.magenta(frames[frameIndex]); + process.stdout.write( + `${cursor.move(-999, 0)}${erase.line}${frame} ${pc.cyan(message)}`, + ); + frameIndex = (frameIndex + 1) % frames.length; + }, delay); + + await action((newMessage: string) => { + message = newMessage; + }); + + clearInterval(interval); + interval = null; + } catch (error) { + if (interval) { + clearInterval(interval); + } + + process.stdout.write( + `\r${erase.line}${pc.red("✖")} ${ + error instanceof Error ? errorMessage : "An unknown error occurred." + }\n`, + ); + + msg({ + type: "M_ERROR", + title: + error instanceof Error ? error.message : "An unknown error occurred.", + titleColor: "red", + }); + + process.exit(1); + } finally { + if ( + process.stdin.isTTY && + typeof process.stdin.setRawMode === "function" + ) { + process.stdin.setRawMode(false); + process.stdin.pause(); + process.stdin.removeListener("data", handleInput); + } + } + } +} + +// Export a function to get task statistics +export function getTaskStats(taskList: TaskList = rootTaskList) { + const stats = { + total: 0, + pending: 0, + loading: 0, + success: 0, + error: 0, + warning: 0, + cancelled: 0, + averageDuration: 0, + }; + + function processTask(task: TaskObject) { + stats.total++; + stats[task.state]++; + if (task.duration) { + stats.averageDuration = + (stats.averageDuration * (stats.total - 1) + task.duration) / + stats.total; + } + task.children.forEach(processTask); + } + + taskList.forEach(processTask); + return stats; +} + +export default advancedTaskPrompt(rootTaskList); diff --git a/src/task/types.ts b/src/task/types.ts new file mode 100644 index 0000000..f611457 --- /dev/null +++ b/src/task/types.ts @@ -0,0 +1,16 @@ +export type ProgressBarOptions = { + total: number; + width?: number; + completeChar?: string; + incompleteChar?: string; + format?: string; + colorize?: boolean; + increment?: number; + desiredTotalTime?: number; +}; + +export type ProgressBar = { + update: (value: number) => Promise; + increment: (amount?: number) => Promise; + render: () => Promise; +}; diff --git a/src/toggle/index.ts b/src/toggle/index.ts index 8540266..f2bf88e 100644 --- a/src/toggle/index.ts +++ b/src/toggle/index.ts @@ -6,7 +6,8 @@ import type { ColorName, TypographyName } from "~/types/general.js"; import type { VariantName } from "~/utils/variants.js"; import { deleteLastLine } from "~/main.js"; -import { msg, msgUndoAll } from "~/utils/messages.js"; +import { msg } from "~/utils/messages.js"; +import { completePrompt } from "~/utils/prompt-end.js"; export type TogglePromptParams = { title: string; @@ -218,7 +219,33 @@ export async function togglePrompt( }); return new Promise((resolve) => { - function onKeyPress(_str: string, key: readline.Key) { + function cleanup(isCtrlC = false) { + if (typeof input.setRawMode === "function") { + input.setRawMode(false); + } + rl.close(); + input.removeListener("keypress", handleKeypress); + if (isCtrlC) { + process.exit(0); + } + } + + function endPrompt(isCtrlC = false) { + if (endTitle !== "") { + msg({ + type: "M_END", + title: endTitle, + titleColor: endTitleColor, + titleTypography, + ...(titleVariant ? { titleVariant } : {}), + border, + borderColor, + }); + } + cleanup(isCtrlC); + } + + function handleKeypress(_str: string, key: readline.Key): void { if (key.name === "left" || key.name === "h") { selectedIndex = (selectedIndex - 1 + options.length) % options.length; errorMessage = ""; @@ -236,54 +263,26 @@ export async function togglePrompt( cleanup(); // Return boolean: first option = true, second option = false const booleanValue = selectedIndex === 0; - - // Only clear and show end title if one is provided - if (endTitle !== "") { - msgUndoAll(); - msg({ - type: "M_END", - title: endTitle, - titleColor: endTitleColor, - titleTypography, - ...(titleVariant ? { titleVariant } : {}), - border, - borderColor, - }); - } + void completePrompt( + false, + endTitle, + endTitleColor, + titleTypography, + titleVariant ? titleVariant : undefined, + border, + borderColor, + undefined, + booleanValue, + ); resolve(booleanValue); - deleteLastLine(); msg({ type: "M_BAR", borderColor }); } } else if (key.name === "c" && key.ctrl) { - // Only clear and show end title if one is provided - if (endTitle !== "") { - msgUndoAll(); - msg({ - type: "M_END", - title: endTitle, - titleColor: endTitleColor, - titleTypography, - ...(titleVariant ? { titleVariant } : {}), - border, - borderColor, - }); - } - cleanup(true); - } - } - - function cleanup(isCtrlC = false) { - if (typeof input.setRawMode === "function") { - input.setRawMode(false); - } - rl.close(); - input.removeListener("keypress", onKeyPress); - if (isCtrlC) { - process.exit(0); + endPrompt(true); } } - input.on("keypress", onKeyPress); + input.on("keypress", handleKeypress); }); } diff --git a/src/types/index.ts b/src/types/index.ts index 0bb597a..ed08696 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,2 +1,42 @@ -export * from "./readline.js"; -export * from "./utils.js"; +import type MuteStream from "mute-stream"; +import type { ReadStream } from "node:fs"; +import type { Interface as ReadLine } from "node:readline"; +import type { Writable } from "node:stream"; +import type { ReadableStream } from "node:stream/web"; + +export type BetterReadline = { + input: ReadStream & { fd: 0 }; + output: MuteStream; + line: string; + cursor: number; + clearLine(dir: number): void; +} & ReadLine; + +export type Context = { + input?: (ReadStream & { fd: 0 }) | ReadableStream | MuteStream; + output?: NodeJS.WriteStream | Writable; + signal?: AbortSignal; + clearPromptOnDone?: boolean; + nonInteractive?: boolean; +}; + +export type PromptConfig = { + message?: string; + default?: string | number | boolean; + theme?: Theme; + [key: string]: any; +}; + +export type Prompt< + Value = unknown, + Config extends PromptConfig = PromptConfig, +> = ( + config: Prettify, + context?: Context, +) => Promise & { cancel: () => void }; + +export type Prettify = { + [K in keyof T]: T[K]; +} & {}; + +export type State = "initial" | "active" | "loading" | "done" | "error"; diff --git a/src/utils/component.ts b/src/utils/component.ts index 07212e7..5ffefa3 100644 --- a/src/utils/component.ts +++ b/src/utils/component.ts @@ -25,7 +25,7 @@ const S_STEP_CANCEL = s("■", "x"); const S_STEP_ERROR = s("▲", "x"); const S_STEP_SUBMIT = s("◇", "o"); -const S_BAR_START = s("┌", "T"); +const S_BAR_START = s("╭", "T"); const S_BAR = s("│", "|"); const S_BAR_END = s("└", "—"); diff --git a/src/utils/messages.ts b/src/utils/messages.ts index d8591db..969f610 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -17,7 +17,7 @@ import { isValidVariant, } from "~/utils/variants.js"; -import { getTerminalWidth } from "../core/utils.js"; +import { getExactTerminalWidth, getTerminalWidth } from "../core/utils.js"; /** * Known symbol names that will have IntelliSense support @@ -75,14 +75,15 @@ const u = (c: string, fallback: string) => (unicode ? c : fallback); export const symbols = { pointer: u("👉", ">"), - start: u("╭", "T"), + start: u("╭", "*"), middle: u("│", "|"), end: u("╰", "*"), line: u("─", "—"), - corner_top_right: u("����", "T"), + corner_top_right: u("╭", "*"), step_active: u("◆", "♦"), step_error: u("🗴", "x"), info: u("ℹ", "i"), + success: u("✅", "✓"), } as const; /** @@ -199,17 +200,18 @@ export function fmt(opts: FmtMsgOptions): { text: string; lineCount: number } { ? colorMap[opts.borderColor](symbols.end + symbols.line) : symbols.end + symbols.line; + const lineLength = + opts.horizontalLineLength === 0 + ? getExactTerminalWidth() - 3 + : (opts.horizontalLineLength ?? getExactTerminalWidth() - 3); + const suffixStartLine = opts.borderColor - ? colorMap[opts.borderColor]( - `${symbols.line.repeat(opts.horizontalLineLength ?? 23)}⊱`, - ) - : `${symbols.line.repeat(opts.horizontalLineLength ?? 23)}⊱`; + ? colorMap[opts.borderColor](`${symbols.line.repeat(lineLength)}⊱`) + : `${symbols.line.repeat(lineLength)}⊱`; const suffixEndLine = opts.borderColor - ? colorMap[opts.borderColor]( - `${symbols.line.repeat(opts.horizontalLineLength ?? 23)}⊱`, - ) - : `${symbols.line.repeat(opts.horizontalLineLength ?? 23)}⊱`; + ? colorMap[opts.borderColor](`${symbols.line.repeat(lineLength)}⊱`) + : `${symbols.line.repeat(lineLength)}⊱`; const MSG_CONFIGS: Record = { M_NULL: { @@ -453,8 +455,10 @@ export function fmt(opts: FmtMsgOptions): { text: string; lineCount: number } { } // For M_END with border, format the title line if (opts.type === "M_END" && opts.border && index === 0) { - // Title line with info symbol - return `${pc.green(symbols.info)} ${line}`; + // Use middle bar if title is empty, otherwise use info icon + return !opts.title + ? `${borderWithSpace}${line}` + : `${pc.green(symbols.info)} ${line}`; } // Skip if line already has a bar or is empty if (!line.trim() || line.includes(symbols.middle)) { @@ -468,7 +472,7 @@ export function fmt(opts: FmtMsgOptions): { text: string; lineCount: number } { }); if (opts.type === "M_END" && opts.border) { - lines.push(`${prefixEndLine}${suffixEndLine}`); + lines.push(`${prefixEndLine}${suffixEndLine}\n`); } const finalText = lines.join("\n"); diff --git a/src/utils/platforms.ts b/src/utils/platforms.ts index e2c4698..00f81a9 100644 --- a/src/utils/platforms.ts +++ b/src/utils/platforms.ts @@ -99,7 +99,7 @@ export const pmv = await getNpmVersion(pm); // export const pkg = packageJson; export const pkg = { name: "@reliverse/prompts", - version: "1.4.2", + version: "1.4.4", description: "@reliverse/prompts is a powerful library that enables seamless, typesafe, and resilient prompts for command-line applications. Crafted with simplicity and elegance, it provides developers with an intuitive and robust way to build interactive CLIs.", }; diff --git a/src/utils/prompt-end.ts b/src/utils/prompt-end.ts new file mode 100644 index 0000000..0331ab1 --- /dev/null +++ b/src/utils/prompt-end.ts @@ -0,0 +1,43 @@ +import type { ColorName, TypographyName } from "~/types/general.js"; +import type { VariantName } from "~/utils/variants.js"; + +import { msg } from "~/utils/messages.js"; + +/** + * Ends the prompt by optionally displaying an end message and running the action if confirmed. + * Preserves the last prompt state unless there's an endTitle. + */ +export async function completePrompt( + isCtrlC: boolean, + endTitle: string, + endTitleColor: ColorName, + titleTypography: TypographyName, + titleVariant: VariantName | undefined, + border: boolean, + borderColor: ColorName, + action?: () => Promise, + value?: boolean, +): Promise { + if (action && value) { + await action(); + } + + if (isCtrlC) { + msg({ + type: "M_END", + title: endTitle, + titleColor: endTitleColor, + titleTypography, + ...(titleVariant ? { titleVariant } : {}), + border, + borderColor, + }); + } else { + msg({ + type: "M_BAR", + borderColor, + }); + } + + return value ?? false; +} diff --git a/src/utils/prompt-tmp.ts b/src/utils/prompt-tmp.ts index 5921bcb..44856b7 100644 --- a/src/utils/prompt-tmp.ts +++ b/src/utils/prompt-tmp.ts @@ -94,8 +94,8 @@ export function createPrompt( const _render = () => renderFn.call(self); function prompt() { - const sink = new WriteStream(0); - sink._write = (_chunk, _encoding, done) => { + const stream = new WriteStream(0); + stream._write = (_chunk, _encoding, done) => { if (_track) { value = _rl.line.replace(/\t/g, ""); _cursor = _rl.cursor; @@ -103,11 +103,11 @@ export function createPrompt( } done(); }; - _input.pipe(sink); + _input.pipe(stream); _rl = readline.createInterface({ input: _input, - output: sink, + output: stream, tabSize: 2, prompt: "", escapeCodeTimeout: 50, diff --git a/src/utils/prompt-two.ts b/src/utils/prompt-two.ts index 5921bcb..f36fcbd 100644 --- a/src/utils/prompt-two.ts +++ b/src/utils/prompt-two.ts @@ -68,10 +68,17 @@ export function createPrompt( render: renderFn, input = stdin, output = stdout, + debug = process.env["DEBUG"] === "true", ...opts }: PromptOptions, trackValue = true, ) { + if (debug) { + console.debug("Terminal info:", { + isTTY: process.stdout.isTTY, + columns: process.stdout.columns, + }); + } const _input = input; const _output = output; let _rl!: ReadLine; @@ -94,8 +101,8 @@ export function createPrompt( const _render = () => renderFn.call(self); function prompt() { - const sink = new WriteStream(0); - sink._write = (_chunk, _encoding, done) => { + const stream = new WriteStream(0); + stream._write = (_chunk, _encoding, done) => { if (_track) { value = _rl.line.replace(/\t/g, ""); _cursor = _rl.cursor; @@ -103,11 +110,11 @@ export function createPrompt( } done(); }; - _input.pipe(sink); + _input.pipe(stream); _rl = readline.createInterface({ input: _input, - output: sink, + output: stream, tabSize: 2, prompt: "", escapeCodeTimeout: 50, diff --git a/tsconfig.json b/tsconfig.json index fedc71a..892c98d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,11 +7,11 @@ "#/*": ["./addons/*"], "@/*": ["./examples/*"] }, - "target": "ES2022", + "target": "ES2023", "module": "NodeNext", "moduleDetection": "force", "moduleResolution": "nodenext", - "lib": ["DOM", "DOM.Iterable", "ES2022"], + "lib": ["DOM", "DOM.Iterable", "ES2023"], "resolveJsonModule": true, "verbatimModuleSyntax": true, "isolatedModules": true,