@smythos/sre 1.7.7 → 1.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,5 @@
1
+ import * as readlineSync from 'readline-sync';
2
+
1
3
  /**
2
4
  * This function parses the command line arguments and returns an object with the parsed values.
3
5
  * The expected format is --file ./path/to/file.txt or --settings key1=value1 key2=value2
@@ -66,3 +68,162 @@ export function getMainArgs(argv?: Array<string>): Array<string> {
66
68
 
67
69
  return result;
68
70
  }
71
+
72
+ export const colors = {
73
+ reset: '\x1b[0m',
74
+ bright: '\x1b[1m',
75
+ dim: '\x1b[2m',
76
+ underscore: '\x1b[4m',
77
+ blink: '\x1b[5m',
78
+ reverse: '\x1b[7m',
79
+ hidden: '\x1b[8m',
80
+
81
+ black: '\x1b[30m',
82
+ red: '\x1b[31m',
83
+ green: '\x1b[32m',
84
+ orange: '\x1b[33m',
85
+ yellow: '\x1b[33m',
86
+ blue: '\x1b[34m',
87
+ magenta: '\x1b[35m',
88
+ cyan: '\x1b[36m',
89
+ white: '\x1b[37m',
90
+
91
+ bgBlack: '\x1b[40m',
92
+ bgRed: '\x1b[41m',
93
+ bgGreen: '\x1b[42m',
94
+ bgYellow: '\x1b[43m',
95
+ bgBlue: '\x1b[44m',
96
+ bgMagenta: '\x1b[45m',
97
+ bgCyan: '\x1b[46m',
98
+ bgWhite: '\x1b[47m',
99
+ };
100
+
101
+ /**
102
+ * Prompt the user for a yes/no question synchronously.
103
+ * Returns true for Yes, false for No.
104
+ * Keeps asking until a valid response is entered.
105
+ *
106
+ * @param {string} question - The question to ask (no need to add "(Y/N)").
107
+ * @returns {boolean} - True for yes, false for no.
108
+ */
109
+ export function askYesNo(question) {
110
+ while (true) {
111
+ const answer = readlineSync.question(`${question} (Y/N): `).trim().toLowerCase();
112
+
113
+ if (['y', 'yes'].includes(answer)) return true;
114
+ if (['n', 'no'].includes(answer)) return false;
115
+
116
+ console.log('Please enter Y or N.');
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Prompt the user synchronously for values to populate a JSON object.
122
+ * @param {string} message - Introductory message shown once at the start.
123
+ * @param {Object} prompts - Object where keys are config keys and values are question labels.
124
+ * @returns {Object} - A new object containing the entered values (empty if skipped).
125
+ */
126
+ import fs from 'fs';
127
+ import { stdin, stdout } from 'process';
128
+
129
+ export function askForValues(message, prompts, options = {}) {
130
+ console.log(message);
131
+
132
+ const result = {};
133
+
134
+ // Save original terminal mode
135
+ const wasRaw = stdin.isRaw;
136
+
137
+ for (const [key, label] of Object.entries(prompts)) {
138
+ stdout.write(`${label} `);
139
+
140
+ // Set terminal to raw mode to capture Ctrl+C
141
+ stdin.setRawMode(true);
142
+ stdin.resume();
143
+
144
+ let value = '';
145
+ let cancelled = false;
146
+
147
+ const promptLength = (label as string).length + 1;
148
+
149
+ while (true) {
150
+ const buffer = Buffer.alloc(1);
151
+ const bytesRead = fs.readSync(stdin.fd, buffer, 0, 1, null);
152
+
153
+ if (bytesRead === 0) break;
154
+
155
+ const char = buffer.toString('utf8');
156
+ const code = buffer[0];
157
+
158
+ // ✅ Check for Ctrl+C (code 3)
159
+ if (code === 3) {
160
+ cancelled = true;
161
+ break;
162
+ }
163
+
164
+ // Check for Enter (code 13 or 10)
165
+ if (code === 13 || code === 10) {
166
+ stdout.write('\n');
167
+ break;
168
+ }
169
+
170
+ // Check for Backspace (code 127 or 8)
171
+ if (code === 127 || code === 8) {
172
+ if (value.length > 0) {
173
+ const oldValue = value;
174
+ value = value.slice(0, -1);
175
+
176
+ // ✅ Calculate lines needed for old and new values
177
+ const terminalWidth = stdout.columns || 80;
178
+ const oldTotalLength = promptLength + oldValue.length;
179
+ const newTotalLength = promptLength + value.length;
180
+ const oldLines = Math.ceil(oldTotalLength / terminalWidth);
181
+ const newLines = Math.ceil(newTotalLength / terminalWidth);
182
+
183
+ // Move to start of first line
184
+ for (let i = 1; i < oldLines; i++) {
185
+ stdout.write('\x1b[1A'); // Move up
186
+ }
187
+ stdout.write('\r'); // Go to start of line
188
+
189
+ // Clear all old lines
190
+ for (let i = 0; i < oldLines; i++) {
191
+ stdout.write('\x1b[K'); // Clear line
192
+ if (i < oldLines - 1) {
193
+ stdout.write('\n'); // Move to next line to clear it
194
+ }
195
+ }
196
+
197
+ // Move back to start
198
+ for (let i = 1; i < oldLines; i++) {
199
+ stdout.write('\x1b[1A');
200
+ }
201
+ stdout.write('\r');
202
+
203
+ // Redraw prompt and new value
204
+ stdout.write(`${label} ${value}`);
205
+ }
206
+ continue;
207
+ }
208
+
209
+ // Regular character
210
+ if (code >= 32 && code <= 126) {
211
+ value += char;
212
+ stdout.write(char);
213
+ }
214
+ }
215
+
216
+ // Restore terminal mode
217
+ stdin.setRawMode(wasRaw);
218
+ stdin.pause();
219
+
220
+ if (cancelled) {
221
+ console.log('\n❌ Operation cancelled by user.');
222
+ process.exit(130);
223
+ }
224
+
225
+ if (value.trim()) result[key] = value.trim();
226
+ }
227
+
228
+ return result;
229
+ }