go-dev 0.4.0 → 0.4.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "go-dev",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "main": "src/index.js",
5
5
  "bin": {
6
6
  "go-dev": "bin/go-dev"
package/src/config.js CHANGED
@@ -1,7 +1,6 @@
1
1
  const Joi = require('joi');
2
2
  const yaml = require('js-yaml');
3
3
  const fs = require('fs');
4
- const path = require('path');
5
4
 
6
5
  const dependencyEntrySchema = Joi.alternatives().try(
7
6
  Joi.string(),
@@ -1,9 +1,9 @@
1
- const detectLatestColor = require("./detect-last-color");
1
+ const detectLastFormatting = require("./terminal-formatting/detect-last-formatting");
2
2
 
3
- function prefixLines(text, prefix, latestColor) {
3
+ function prefixLines(text, prefix, latestFormatting) {
4
4
  let prefixedText = text.split('\n').map(line => {
5
- latestColor = detectLatestColor(line, latestColor);
6
- return `${prefix} ${latestColor}${line}${latestColor !== '' ? '\x1b[0m' : ''}`;
5
+ latestFormatting = detectLastFormatting(line, latestFormatting);
6
+ return `${prefix} ${latestFormatting}${line}${latestFormatting !== '' ? '\x1b[0m' : ''}`;
7
7
  }).join('\n');
8
8
 
9
9
  if (prefixedText.endsWith(`${prefix} `)) {
@@ -14,7 +14,7 @@ function prefixLines(text, prefix, latestColor) {
14
14
  }
15
15
  prefixedText = prefixedText.replace(/\x1b\[(?:2J|3J|H)|\x1bc|\x1b\[2K|\x1b\[K/gi, '');
16
16
 
17
- return { prefixedText, latestColor };
17
+ return { prefixedText, lastFormatting: latestFormatting };
18
18
  }
19
19
 
20
20
  module.exports = prefixLines;
@@ -1,6 +1,8 @@
1
- const { spawn, spawnSync } = require('child_process');
1
+ const { spawn, spawnSync, execSync } = require('child_process');
2
2
  const prefixLines = require("./prefix-lines");
3
3
 
4
+ const isWindows = process.platform === 'win32';
5
+
4
6
  class ProcessManager {
5
7
  constructor() {
6
8
  this.managedProcesses = new Set();
@@ -119,15 +121,15 @@ class ProcessManager {
119
121
  });
120
122
  processReference.process = startedProcess;
121
123
 
122
- let latestColor = '';
124
+ let lastFormatting = '';
123
125
  startedProcess.stdout.on('data', (data) => {
124
- const result = prefixLines(data.toString(), prefix, latestColor);
125
- latestColor = result.latestColor;
126
+ const result = prefixLines(data.toString(), prefix, lastFormatting);
127
+ lastFormatting = result.lastFormatting;
126
128
  process.stdout.write(result.prefixedText);
127
129
  });
128
130
  startedProcess.stderr.on('data', (data) => {
129
- const result = prefixLines(data.toString(), prefix, latestColor);
130
- latestColor = result.latestColor;
131
+ const result = prefixLines(data.toString(), prefix, lastFormatting);
132
+ lastFormatting = result.lastFormatting;
131
133
  process.stderr.write(result.prefixedText);
132
134
  });
133
135
 
@@ -176,47 +178,65 @@ class ProcessManager {
176
178
  return processReference;
177
179
  }
178
180
 
179
- killProcess(process) {
180
- if (process.killed || process.exitCode != null) {
181
- return;
181
+ /**
182
+ * Kills a single child process.
183
+ * On Windows, uses taskkill to kill the entire process tree.
184
+ * @param {ChildProcess} childProcess - The process to kill.
185
+ * @returns {Promise<void>}
186
+ */
187
+ killProcess(childProcess) {
188
+ if (childProcess.killed || childProcess.exitCode != null) {
189
+ return Promise.resolve();
182
190
  }
183
191
 
184
- this.managedProcesses.delete(process);
192
+ this.managedProcesses.delete(childProcess);
185
193
 
186
- return new Promise((resolve, reject) => {
194
+ if (isWindows) {
195
+ try {
196
+ execSync(`taskkill /T /F /PID ${childProcess.pid}`, { stdio: 'ignore' });
197
+ } catch {
198
+ // Process may have already been terminated by Ctrl+C signal propagation - this is OK
199
+ }
200
+ return Promise.resolve();
201
+ }
202
+
203
+ // On Unix, use SIGTERM with timeout fallback to SIGKILL
204
+ return new Promise((resolve) => {
187
205
  let exited = false;
206
+ let timeoutId = null;
207
+
188
208
  const onExit = () => {
189
209
  exited = true;
210
+ if (timeoutId) {
211
+ clearTimeout(timeoutId);
212
+ timeoutId = null;
213
+ }
190
214
  resolve();
191
215
  };
192
- process.on('exit', onExit);
216
+ childProcess.on('exit', onExit);
193
217
 
194
- setTimeout(() => {
218
+ timeoutId = setTimeout(() => {
195
219
  if (exited) {
196
220
  return;
197
221
  }
198
222
 
199
- console.error(`[ProcessManager] Timeout reached for process interruption ${process.pid}`);
223
+ console.error(`[ProcessManager] Timeout reached for process interruption ${childProcess.pid}`);
200
224
  try {
201
- process.kill('SIGKILL');
225
+ childProcess.kill('SIGKILL');
202
226
  } catch (e) {
203
- console.error(`[ProcessManager] Error force killing process ${process.pid}: ${e.message}`);
204
- reject(e);
227
+ console.error(`[ProcessManager] Error force killing process ${childProcess.pid}: ${e.message}`);
205
228
  }
229
+ resolve();
206
230
  }, 500);
207
231
 
208
232
  try {
209
- process.kill('SIGTERM');
210
- return;
211
- } catch (e) {
212
- console.error(`[ProcessManager] Error signaling process ${process.pid}: ${e.message}`);
213
- }
214
-
215
- try {
216
- process.kill('SIGKILL');
233
+ childProcess.kill('SIGTERM');
217
234
  } catch (e) {
218
- console.error(`[ProcessManager] Error force killing process ${process.pid}: ${e.message}`);
219
- reject(e);
235
+ console.error(`[ProcessManager] Error signaling process ${childProcess.pid}: ${e.message}`);
236
+ if (timeoutId) {
237
+ clearTimeout(timeoutId);
238
+ }
239
+ resolve();
220
240
  }
221
241
  });
222
242
  }
@@ -229,41 +249,54 @@ class ProcessManager {
229
249
  console.log('[ProcessManager] Cleanup of managed processes already in progress, skipping.');
230
250
  return;
231
251
  }
232
- for (let index = this.managedProcesses.length - 1; index >= 0; index--) {
233
- const process = this.managedProcesses[index];
234
- if (process.killed || process.exitCode != null) {
235
- this.managedProcesses.splice(index, 1);
236
- }
237
- }
238
252
 
239
253
  this.cleanupInProgress = true;
240
254
 
241
255
  console.log('\n[ProcessManager] Initiating cleanup of managed processes...');
242
256
 
243
- for (const proc of [...this.managedProcesses]) {
257
+ // Filter out already-dead processes
258
+ const processesToKill = [...this.managedProcesses].filter(proc => {
244
259
  if (proc.killed || proc.exitCode != null) {
245
- continue;
260
+ this.managedProcesses.delete(proc);
261
+ return false;
246
262
  }
247
-
263
+ return true;
264
+ });
265
+
266
+ for (const proc of processesToKill) {
248
267
  console.log(`[ProcessManager] Killing managed process PID: ${proc.pid}`);
249
268
  try {
250
- proc.kill('SIGTERM');
269
+ if (isWindows) {
270
+ // On Windows, use taskkill to kill the entire process tree
271
+ try {
272
+ execSync(`taskkill /T /F /PID ${proc.pid}`, { stdio: 'ignore' });
273
+ } catch {
274
+ // Process may have already been terminated - this is OK
275
+ }
276
+ } else {
277
+ proc.kill('SIGTERM');
278
+ }
251
279
  } catch (e) {
252
280
  console.error(`[ProcessManager] Error killing process ${proc.pid}: ${e.message}`);
253
281
  }
254
282
  }
255
- await new Promise(resolve => setTimeout(resolve, 500));
256
-
257
- for (const proc of [...this.managedProcesses]) {
258
- if (proc.killed || proc.exitCode != null) {
259
- continue;
260
- }
283
+
284
+ // On Unix, wait for processes to exit gracefully before using SIGKILL
285
+ if (processesToKill.length > 0 && !isWindows) {
286
+ await new Promise(resolve => setTimeout(resolve, 500));
287
+
288
+ for (const proc of [...this.managedProcesses]) {
289
+ if (proc.killed || proc.exitCode != null) {
290
+ this.managedProcesses.delete(proc);
291
+ continue;
292
+ }
261
293
 
262
- console.warn(`[ProcessManager] Process ${proc.pid} did not exit gracefully, forcing kill.`);
263
- try {
264
- proc.kill('SIGKILL');
265
- } catch (e) {
266
- console.error(`[ProcessManager] Error forcing kill for process ${proc.pid}: ${e.message}`);
294
+ console.warn(`[ProcessManager] Process ${proc.pid} did not exit gracefully, forcing kill.`);
295
+ try {
296
+ proc.kill('SIGKILL');
297
+ } catch (e) {
298
+ console.error(`[ProcessManager] Error forcing kill for process ${proc.pid}: ${e.message}`);
299
+ }
267
300
  }
268
301
  }
269
302
 
@@ -0,0 +1,223 @@
1
+ const {
2
+ RESET_ALL,
3
+ RESET_FOREGROUND,
4
+ RESET_BACKGROUND,
5
+
6
+ SET_BOLD,
7
+ SET_DIM,
8
+ SET_ITALIC,
9
+ SET_UNDERLINE,
10
+ SET_SLOW_BLINK,
11
+ SET_RAPID_BLINK,
12
+ SET_REVERSE,
13
+ SET_HIDE,
14
+ SET_STRIKETHROUGH,
15
+ SET_DOUBLE_UNDERLINE,
16
+
17
+ RESET_BOLD_DIM,
18
+ RESET_ITALIC,
19
+ RESET_UNDERLINE,
20
+ RESET_BLINK,
21
+ RESET_REVERSE,
22
+ RESET_HIDE,
23
+ RESET_STRIKETHROUGH,
24
+
25
+ SET_FG_BLACK,
26
+ SET_FG_RED,
27
+ SET_FG_GREEN,
28
+ SET_FG_YELLOW,
29
+ SET_FG_BLUE,
30
+ SET_FG_MAGENTA,
31
+ SET_FG_CYAN,
32
+ SET_FG_WHITE,
33
+
34
+ SET_BG_BLACK,
35
+ SET_BG_RED,
36
+ SET_BG_GREEN,
37
+ SET_BG_YELLOW,
38
+ SET_BG_BLUE,
39
+ SET_BG_MAGENTA,
40
+ SET_BG_CYAN,
41
+ SET_BG_WHITE,
42
+
43
+ SET_FG_BRIGHT_BLACK,
44
+ SET_FG_BRIGHT_RED,
45
+ SET_FG_BRIGHT_GREEN,
46
+ SET_FG_BRIGHT_YELLOW,
47
+ SET_FG_BRIGHT_BLUE,
48
+ SET_FG_BRIGHT_MAGENTA,
49
+ SET_FG_BRIGHT_CYAN,
50
+ SET_FG_BRIGHT_WHITE,
51
+
52
+ SET_BG_BRIGHT_BLACK,
53
+ SET_BG_BRIGHT_RED,
54
+ SET_BG_BRIGHT_GREEN,
55
+ SET_BG_BRIGHT_YELLOW,
56
+ SET_BG_BRIGHT_BLUE,
57
+ SET_BG_BRIGHT_MAGENTA,
58
+ SET_BG_BRIGHT_CYAN,
59
+ SET_BG_BRIGHT_WHITE,
60
+
61
+ SET_FG_COLOR,
62
+ SET_BG_COLOR,
63
+
64
+ COLOR_MODE_256,
65
+ COLOR_MODE_RGB,
66
+
67
+ FOREGROUND_INDEX,
68
+ BACKGROUND_INDEX,
69
+ BOLD_DIM_INDEX,
70
+ ITALIC_INDEX,
71
+ UNDERLINE_INDEX,
72
+ BLINK_INDEX,
73
+ REVERSE_INDEX,
74
+ HIDE_INDEX,
75
+ STRIKETHROUGH_INDEX,
76
+ } = require("./constants");
77
+
78
+ function applyFormattingCodes(currentCodes, codes) {
79
+ for (let i = 0; i < codes.length; i++) {
80
+ const code = codes[i];
81
+ switch (code) {
82
+ case RESET_ALL: {
83
+ currentCodes.splice(0);
84
+ break;
85
+ }
86
+ case RESET_FOREGROUND: {
87
+ currentCodes[FOREGROUND_INDEX] = undefined;
88
+ break;
89
+ }
90
+ case RESET_BACKGROUND: {
91
+ currentCodes[BACKGROUND_INDEX] = undefined;
92
+ break;
93
+ }
94
+ case RESET_BOLD_DIM: {
95
+ currentCodes[BOLD_DIM_INDEX] = undefined;
96
+ break;
97
+ }
98
+ case RESET_ITALIC: {
99
+ currentCodes[ITALIC_INDEX] = undefined;
100
+ break;
101
+ }
102
+ case RESET_UNDERLINE: {
103
+ currentCodes[UNDERLINE_INDEX] = undefined;
104
+ break;
105
+ }
106
+ case RESET_BLINK: {
107
+ currentCodes[BLINK_INDEX] = undefined;
108
+ break;
109
+ }
110
+ case RESET_REVERSE: {
111
+ currentCodes[REVERSE_INDEX] = undefined;
112
+ break;
113
+ }
114
+ case RESET_HIDE: {
115
+ currentCodes[HIDE_INDEX] = undefined;
116
+ break;
117
+ }
118
+ case RESET_STRIKETHROUGH: {
119
+ currentCodes[STRIKETHROUGH_INDEX] = undefined;
120
+ break;
121
+ }
122
+ case SET_FG_BLACK:
123
+ case SET_FG_RED:
124
+ case SET_FG_GREEN:
125
+ case SET_FG_YELLOW:
126
+ case SET_FG_BLUE:
127
+ case SET_FG_MAGENTA:
128
+ case SET_FG_CYAN:
129
+ case SET_FG_WHITE:
130
+ case SET_FG_BRIGHT_BLACK:
131
+ case SET_FG_BRIGHT_RED:
132
+ case SET_FG_BRIGHT_GREEN:
133
+ case SET_FG_BRIGHT_YELLOW:
134
+ case SET_FG_BRIGHT_BLUE:
135
+ case SET_FG_BRIGHT_MAGENTA:
136
+ case SET_FG_BRIGHT_CYAN:
137
+ case SET_FG_BRIGHT_WHITE:
138
+ case SET_FG_COLOR: {
139
+ if (code === SET_FG_COLOR) {
140
+ const nextCode = codes[i + 1];
141
+ let finalCode = `${code};${nextCode}`;
142
+ if (nextCode === COLOR_MODE_256) {
143
+ finalCode = `${finalCode};${codes[i + 2]}`;
144
+ i += 2;
145
+ } else {
146
+ finalCode = `${finalCode};${codes[i + 2]};${codes[i + 3]};${codes[i + 4]}`;
147
+ i += 4;
148
+ }
149
+ currentCodes[FOREGROUND_INDEX] = finalCode;
150
+ } else {
151
+ currentCodes[FOREGROUND_INDEX] = code;
152
+ }
153
+ break;
154
+ }
155
+ case SET_BG_BLACK:
156
+ case SET_BG_RED:
157
+ case SET_BG_GREEN:
158
+ case SET_BG_YELLOW:
159
+ case SET_BG_BLUE:
160
+ case SET_BG_MAGENTA:
161
+ case SET_BG_CYAN:
162
+ case SET_BG_WHITE:
163
+ case SET_BG_BRIGHT_BLACK:
164
+ case SET_BG_BRIGHT_RED:
165
+ case SET_BG_BRIGHT_GREEN:
166
+ case SET_BG_BRIGHT_YELLOW:
167
+ case SET_BG_BRIGHT_BLUE:
168
+ case SET_BG_BRIGHT_MAGENTA:
169
+ case SET_BG_BRIGHT_CYAN:
170
+ case SET_BG_BRIGHT_WHITE:
171
+ case SET_BG_COLOR: {
172
+ if (code === SET_BG_COLOR) {
173
+ const nextCode = codes[i + 1];
174
+ let finalCode = `${code};${nextCode}`;
175
+ if (nextCode === COLOR_MODE_256) {
176
+ finalCode = `${finalCode};${codes[i + 2]}`;
177
+ i += 2;
178
+ } else {
179
+ finalCode = `${finalCode};${codes[i + 2]};${codes[i + 3]};${codes[i + 4]}`;
180
+ i += 4;
181
+ }
182
+ currentCodes[BACKGROUND_INDEX] = finalCode;
183
+ } else {
184
+ currentCodes[BACKGROUND_INDEX] = code;
185
+ }
186
+ break;
187
+ }
188
+ case SET_BOLD:
189
+ case SET_DIM: {
190
+ currentCodes[BOLD_DIM_INDEX] = code;
191
+ break;
192
+ }
193
+ case SET_ITALIC: {
194
+ currentCodes[ITALIC_INDEX] = code;
195
+ break;
196
+ }
197
+ case SET_UNDERLINE:
198
+ case SET_DOUBLE_UNDERLINE: {
199
+ currentCodes[UNDERLINE_INDEX] = code;
200
+ break;
201
+ }
202
+ case SET_SLOW_BLINK:
203
+ case SET_RAPID_BLINK: {
204
+ currentCodes[BLINK_INDEX] = code;
205
+ break;
206
+ }
207
+ case SET_REVERSE: {
208
+ currentCodes[REVERSE_INDEX] = code;
209
+ break;
210
+ }
211
+ case SET_HIDE: {
212
+ currentCodes[HIDE_INDEX] = code;
213
+ break;
214
+ }
215
+ case SET_STRIKETHROUGH: {
216
+ currentCodes[STRIKETHROUGH_INDEX] = code;
217
+ break;
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ module.exports = applyFormattingCodes;
@@ -0,0 +1,151 @@
1
+ const RESET_ALL = "0";
2
+ const RESET_FOREGROUND = "39";
3
+ const RESET_BACKGROUND = "49";
4
+
5
+ const SET_BOLD = "1";
6
+ const SET_DIM = "2";
7
+ const SET_ITALIC = "3";
8
+ const SET_UNDERLINE = "4";
9
+ const SET_SLOW_BLINK = "5";
10
+ const SET_RAPID_BLINK = "6";
11
+ const SET_REVERSE = "7";
12
+ const SET_HIDE = "8";
13
+ const SET_STRIKETHROUGH = "9";
14
+ const SET_DOUBLE_UNDERLINE = "21";
15
+
16
+ const RESET_BOLD_DIM = "22";
17
+ const RESET_ITALIC = "23";
18
+ const RESET_UNDERLINE = "24";
19
+ const RESET_BLINK = "25";
20
+ const RESET_REVERSE = "27";
21
+ const RESET_HIDE = "28";
22
+ const RESET_STRIKETHROUGH = "29";
23
+
24
+ const SET_FG_BLACK = "30";
25
+ const SET_FG_RED = "31";
26
+ const SET_FG_GREEN = "32";
27
+ const SET_FG_YELLOW = "33";
28
+ const SET_FG_BLUE = "34";
29
+ const SET_FG_MAGENTA = "35";
30
+ const SET_FG_CYAN = "36";
31
+ const SET_FG_WHITE = "37";
32
+
33
+ const SET_BG_BLACK = "40";
34
+ const SET_BG_RED = "41";
35
+ const SET_BG_GREEN = "42";
36
+ const SET_BG_YELLOW = "43";
37
+ const SET_BG_BLUE = "44";
38
+ const SET_BG_MAGENTA = "45";
39
+ const SET_BG_CYAN = "46";
40
+ const SET_BG_WHITE = "47";
41
+
42
+ const SET_FG_BRIGHT_BLACK = "90";
43
+ const SET_FG_BRIGHT_RED = "91";
44
+ const SET_FG_BRIGHT_GREEN = "92";
45
+ const SET_FG_BRIGHT_YELLOW = "93";
46
+ const SET_FG_BRIGHT_BLUE = "94";
47
+ const SET_FG_BRIGHT_MAGENTA = "95";
48
+ const SET_FG_BRIGHT_CYAN = "96";
49
+ const SET_FG_BRIGHT_WHITE = "97";
50
+
51
+ const SET_BG_BRIGHT_BLACK = "100";
52
+ const SET_BG_BRIGHT_RED = "101";
53
+ const SET_BG_BRIGHT_GREEN = "102";
54
+ const SET_BG_BRIGHT_YELLOW = "103";
55
+ const SET_BG_BRIGHT_BLUE = "104";
56
+ const SET_BG_BRIGHT_MAGENTA = "105";
57
+ const SET_BG_BRIGHT_CYAN = "106";
58
+ const SET_BG_BRIGHT_WHITE = "107";
59
+
60
+ const SET_FG_COLOR = "38";
61
+ const SET_BG_COLOR = "48";
62
+
63
+ const COLOR_MODE_256 = "5";
64
+ const COLOR_MODE_RGB = "2";
65
+
66
+ const FOREGROUND_INDEX = 0;
67
+ const BACKGROUND_INDEX = 1;
68
+ const BOLD_DIM_INDEX = 2;
69
+ const ITALIC_INDEX = 3;
70
+ const UNDERLINE_INDEX = 4;
71
+ const BLINK_INDEX = 5;
72
+ const REVERSE_INDEX = 6;
73
+ const HIDE_INDEX = 7;
74
+ const STRIKETHROUGH_INDEX = 8;
75
+
76
+ module.exports = {
77
+ RESET_ALL,
78
+ RESET_FOREGROUND,
79
+ RESET_BACKGROUND,
80
+
81
+ SET_BOLD,
82
+ SET_DIM,
83
+ SET_ITALIC,
84
+ SET_UNDERLINE,
85
+ SET_SLOW_BLINK,
86
+ SET_RAPID_BLINK,
87
+ SET_REVERSE,
88
+ SET_HIDE,
89
+ SET_STRIKETHROUGH,
90
+ SET_DOUBLE_UNDERLINE,
91
+
92
+ RESET_BOLD_DIM,
93
+ RESET_ITALIC,
94
+ RESET_UNDERLINE,
95
+ RESET_BLINK,
96
+ RESET_REVERSE,
97
+ RESET_HIDE,
98
+ RESET_STRIKETHROUGH,
99
+
100
+ SET_FG_BLACK,
101
+ SET_FG_RED,
102
+ SET_FG_GREEN,
103
+ SET_FG_YELLOW,
104
+ SET_FG_BLUE,
105
+ SET_FG_MAGENTA,
106
+ SET_FG_CYAN,
107
+ SET_FG_WHITE,
108
+
109
+ SET_BG_BLACK,
110
+ SET_BG_RED,
111
+ SET_BG_GREEN,
112
+ SET_BG_YELLOW,
113
+ SET_BG_BLUE,
114
+ SET_BG_MAGENTA,
115
+ SET_BG_CYAN,
116
+ SET_BG_WHITE,
117
+
118
+ SET_FG_BRIGHT_BLACK,
119
+ SET_FG_BRIGHT_RED,
120
+ SET_FG_BRIGHT_GREEN,
121
+ SET_FG_BRIGHT_YELLOW,
122
+ SET_FG_BRIGHT_BLUE,
123
+ SET_FG_BRIGHT_MAGENTA,
124
+ SET_FG_BRIGHT_CYAN,
125
+ SET_FG_BRIGHT_WHITE,
126
+
127
+ SET_BG_BRIGHT_BLACK,
128
+ SET_BG_BRIGHT_RED,
129
+ SET_BG_BRIGHT_GREEN,
130
+ SET_BG_BRIGHT_YELLOW,
131
+ SET_BG_BRIGHT_BLUE,
132
+ SET_BG_BRIGHT_MAGENTA,
133
+ SET_BG_BRIGHT_CYAN,
134
+ SET_BG_BRIGHT_WHITE,
135
+
136
+ SET_FG_COLOR,
137
+ SET_BG_COLOR,
138
+
139
+ COLOR_MODE_256,
140
+ COLOR_MODE_RGB,
141
+
142
+ FOREGROUND_INDEX,
143
+ BACKGROUND_INDEX,
144
+ BOLD_DIM_INDEX,
145
+ ITALIC_INDEX,
146
+ UNDERLINE_INDEX,
147
+ BLINK_INDEX,
148
+ REVERSE_INDEX,
149
+ HIDE_INDEX,
150
+ STRIKETHROUGH_INDEX,
151
+ };
@@ -0,0 +1,10 @@
1
+ const extractFormattingCodes = require("./extract-formatting-codes");
2
+
3
+ function detectLastFormatting(text, latestFormatting) {
4
+ const currentFormattingCodes = extractFormattingCodes(latestFormatting);
5
+ const latestFormattingCodes = extractFormattingCodes(text, currentFormattingCodes);
6
+
7
+ return latestFormattingCodes.filter(code => code != null).map(code => `\x1b[${code}m`).join("");
8
+ }
9
+
10
+ module.exports = detectLastFormatting;
@@ -0,0 +1,26 @@
1
+ const applyFormattingCodes = require("./apply-formatting-codes");
2
+
3
+ function extractFormattingCodes(text, currentFormattingCodes = []) {
4
+ const colorRegex = /\x1b\[[0-9;]*m/g;
5
+ const matches = text.match(colorRegex);
6
+ if (matches == null || matches.length <= 0) {
7
+ return [];
8
+ }
9
+
10
+ for (const match of matches) {
11
+ const formattingCodes = match.slice(2, -1).split(";");
12
+ if (
13
+ formattingCodes.length === 1 &&
14
+ formattingCodes[0] === ""
15
+ ) {
16
+ currentFormattingCodes.splice(0);
17
+ continue;
18
+ }
19
+
20
+ applyFormattingCodes(currentFormattingCodes, formattingCodes);
21
+ }
22
+
23
+ return currentFormattingCodes;
24
+ }
25
+
26
+ module.exports = extractFormattingCodes;
@@ -1,20 +0,0 @@
1
- function detectLatestColor(text, latestColor) {
2
- const colorRegex = /\x1b\[[0-9;]*m/g;
3
- const matches = text.match(colorRegex);
4
-
5
- if (matches == null || matches.length <= 0) {
6
- return latestColor;
7
- }
8
-
9
- for (const match of matches) {
10
- if (match === '\x1b[0m' || match === '\x1b[m') {
11
- latestColor = '';
12
- } else if (!latestColor.includes(match)) {
13
- latestColor += match;
14
- }
15
- }
16
-
17
- return latestColor;
18
- }
19
-
20
- module.exports = detectLatestColor;