From 8f1285404f08643886363fc151818a9fbd630239 Mon Sep 17 00:00:00 2001
From: Jan Nanista <jan.jakub.nanista@gmail.com>
Date: Fri, 8 Dec 2023 14:23:58 -0800
Subject: [PATCH] chore: Ask user whether they want to continue

---
 packages/io-utils/README.md            | 16 ++++++++++++++++
 packages/io-utils/package.json         |  1 +
 packages/io-utils/src/index.ts         |  1 +
 packages/io-utils/src/stdio/index.ts   |  1 +
 packages/io-utils/src/stdio/prompts.ts | 18 ++++++++++++++++++
 5 files changed, 37 insertions(+)
 create mode 100644 packages/io-utils/src/stdio/index.ts
 create mode 100644 packages/io-utils/src/stdio/prompts.ts

diff --git a/packages/io-utils/README.md b/packages/io-utils/README.md
index 11a8fdc68..e1cbe1c75 100644
--- a/packages/io-utils/README.md
+++ b/packages/io-utils/README.md
@@ -45,3 +45,19 @@ Returns `true` if specified filesystem `path` points to a file, `false` otherwis
 #### isReadable(path)
 
 Returns `true` if specified filesystem `path` can be read by the current user, `false` otherwise. Does not throw if `path` does not exist on the filesystem, instead returns `false`
+
+### Standdard input/output utilities
+
+#### promptToContinue([message, defaultValue])
+
+Asks the user whether they want to continue and reads the input from the CLI standard input. By default the question displayed is `Do you want to continue?` and the default response is `yes`
+
+```typescript
+const goahead = await promptToContinue();
+
+// To ask a different question
+const goahead = await promptToContinue("Are you sure?");
+
+// To default the response to false, good for important and unsafe decisions
+const goahead = await promptToContinue("Are you sure?", false);
+```
diff --git a/packages/io-utils/package.json b/packages/io-utils/package.json
index 6423fb388..cb2598d77 100644
--- a/packages/io-utils/package.json
+++ b/packages/io-utils/package.json
@@ -33,6 +33,7 @@
     "@types/jest": "^29.5.10",
     "fast-check": "^3.14.0",
     "jest": "^29.7.0",
+    "prompts": "^2.4.2",
     "ts-jest": "^29.1.1",
     "ts-node": "^10.9.1",
     "tslib": "~2.6.2",
diff --git a/packages/io-utils/src/index.ts b/packages/io-utils/src/index.ts
index b0899e4ef..0f39ca5b6 100644
--- a/packages/io-utils/src/index.ts
+++ b/packages/io-utils/src/index.ts
@@ -1 +1,2 @@
 export * from './filesystem'
+export * from './stdio'
diff --git a/packages/io-utils/src/stdio/index.ts b/packages/io-utils/src/stdio/index.ts
new file mode 100644
index 000000000..ba85b76eb
--- /dev/null
+++ b/packages/io-utils/src/stdio/index.ts
@@ -0,0 +1 @@
+export * from './prompts'
diff --git a/packages/io-utils/src/stdio/prompts.ts b/packages/io-utils/src/stdio/prompts.ts
new file mode 100644
index 000000000..3e323a896
--- /dev/null
+++ b/packages/io-utils/src/stdio/prompts.ts
@@ -0,0 +1,18 @@
+import assert from 'assert'
+import prompts from 'prompts'
+
+export const promptToContinue = async (
+    message: string = 'Do you want to continue?',
+    defaultValue = true
+): Promise<boolean> => {
+    const { value } = await prompts({
+        type: 'confirm',
+        name: 'value',
+        message,
+        initial: defaultValue,
+    })
+
+    assert(typeof value === 'boolean', `Invariant error: Expected a boolean response, got ${value}`)
+
+    return value
+}