Skip to content

Commit 7cf29a7

Browse files
committed
Validate some options better
Fixes #252
1 parent 4496362 commit 7cf29a7

2 files changed

Lines changed: 72 additions & 3 deletions

File tree

index.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const SYNCHRONIZED_OUTPUT_DISABLE = '\u001B[?2026l';
1717
// Global state for concurrent spinner detection
1818
const activeHooksPerStream = new Map(); // Stream → ora instance
1919

20+
const validColors = new Set(['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'gray']);
21+
2022
class Ora {
2123
#linesToClear = 0;
2224
#frameIndex = -1;
@@ -30,7 +32,7 @@ class Ora {
3032
#drainHandler;
3133
#deferRenderTimer;
3234
#isDiscardingStdin = false;
33-
color;
35+
#color;
3436

3537
// Helper to execute writes while preventing hook recursion
3638
#internalWrite(fn) {
@@ -141,6 +143,10 @@ class Ora {
141143
this.#options.isSilent = false;
142144
}
143145

146+
if (this.#options.interval !== undefined && !(Number.isInteger(this.#options.interval) && this.#options.interval > 0)) {
147+
throw new Error('The `interval` option must be a positive integer');
148+
}
149+
144150
// Set *after* `this.#stream`.
145151
// Store original interval before spinner setter clears it
146152
const userInterval = this.#options.interval;
@@ -286,6 +292,18 @@ class Ora {
286292
return count;
287293
}
288294

295+
get color() {
296+
return this.#color;
297+
}
298+
299+
set color(value) {
300+
if (value !== undefined && value !== false && !validColors.has(value)) {
301+
throw new Error('The `color` option must be a valid color or `false` to disable');
302+
}
303+
304+
this.#color = value;
305+
}
306+
289307
get isEnabled() {
290308
return this.#options.isEnabled && !this.#options.isSilent;
291309
}
@@ -321,8 +339,8 @@ class Ora {
321339
const {frames} = this.#spinner;
322340
let frame = frames[this.#frameIndex];
323341

324-
if (this.color) {
325-
frame = chalk[this.color](frame);
342+
if (this.#color) {
343+
frame = chalk[this.#color](frame);
326344
}
327345

328346
const fullPrefixText = this.#getFullPrefixText(this.#options.prefixText, ' ');

test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,57 @@ test('interval validation works correctly', () => {
15671567
assert.strictEqual(spinner2.interval, 150);
15681568
});
15691569

1570+
test('interval rejects negative values', () => {
1571+
assert.throws(() => {
1572+
ora({interval: -100});
1573+
}, {message: /positive integer/});
1574+
});
1575+
1576+
test('interval rejects non-integer values', () => {
1577+
assert.throws(() => {
1578+
ora({interval: 1.5});
1579+
}, {message: /positive integer/});
1580+
});
1581+
1582+
test('interval rejects zero', () => {
1583+
assert.throws(() => {
1584+
ora({interval: 0});
1585+
}, {message: /positive integer/});
1586+
});
1587+
1588+
test('color rejects invalid color names', () => {
1589+
assert.throws(() => {
1590+
ora({color: 'invalid'});
1591+
}, {message: /valid color/});
1592+
});
1593+
1594+
test('color rejects non-string non-false values', () => {
1595+
assert.throws(() => {
1596+
ora({color: 123});
1597+
}, {message: /valid color/});
1598+
});
1599+
1600+
test('color accepts false to disable', () => {
1601+
const spinner = ora({color: false, isEnabled: false});
1602+
assert.strictEqual(spinner.color, false);
1603+
});
1604+
1605+
test('color accepts valid color names', () => {
1606+
const spinner = ora({color: 'red', isEnabled: false});
1607+
assert.strictEqual(spinner.color, 'red');
1608+
});
1609+
1610+
test('color accepts undefined', () => {
1611+
const spinner = ora({color: undefined, isEnabled: false});
1612+
assert.strictEqual(spinner.color, undefined);
1613+
});
1614+
1615+
test('color setter accepts undefined', () => {
1616+
const spinner = ora({color: 'green', isEnabled: false});
1617+
spinner.color = undefined;
1618+
assert.strictEqual(spinner.color, undefined);
1619+
});
1620+
15701621
test('text setter handles falsy values correctly', () => {
15711622
const spinner = ora({color: false});
15721623
spinner.text = null;

0 commit comments

Comments
 (0)