Skip to content

Commit 2dd8f3d

Browse files
committed
fix: add missing null checks around values
Also uses `getColumns` for note wrapping and changes the `types` script to run `tsc` so we can catch these errors in CI in future.
1 parent 3280bc0 commit 2dd8f3d

File tree

15 files changed

+165
-141
lines changed

15 files changed

+165
-141
lines changed

.changeset/kind-yaks-clean.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@clack/prompts": patch
3+
"@clack/core": patch
4+
---
5+
6+
Add missing nullish checks around values.

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ charset = utf-8
77
trim_trailing_whitespace = true
88
insert_final_newline = true
99

10-
[*.yml]
10+
[*.{yml,json,yaml}]
1111
indent_style = space
1212
indent_size = 2

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"dev": "pnpm --filter @example/changesets run start",
1010
"format": "biome check --write",
1111
"lint": "biome lint --write --unsafe",
12-
"types": "biome lint --write --unsafe",
12+
"types": "pnpm -r run typecheck",
1313
"deps": "pnpm exec knip --production",
1414
"test": "pnpm --color -r run test",
1515
"pretest": "pnpm run build"
@@ -20,7 +20,7 @@
2020
"@types/node": "^24.1.0",
2121
"jsr": "^0.13.4",
2222
"knip": "^5.62.0",
23-
"typescript": "^5.8.3",
23+
"typescript": "catalog:",
2424
"unbuild": "^3.6.0"
2525
},
2626
"packageManager": "pnpm@9.14.2",

packages/core/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,16 @@
5050
"scripts": {
5151
"build": "unbuild",
5252
"prepack": "pnpm build",
53-
"test": "vitest run"
53+
"test": "vitest run",
54+
"typecheck": "tsc --noEmit"
5455
},
5556
"dependencies": {
5657
"picocolors": "^1.0.0",
5758
"sisteransi": "^1.0.5"
5859
},
5960
"devDependencies": {
6061
"vitest": "^3.2.4",
61-
"fast-wrap-ansi": "^0.1.3"
62+
"fast-wrap-ansi": "^0.1.3",
63+
"typescript": "catalog:"
6264
}
6365
}

packages/core/src/prompts/multi-select.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ export default class MultiSelectPrompt<T extends { value: any }> extends Prompt<
2121
}
2222

2323
private toggleInvert() {
24-
const notSelected = this.options.filter((v) => !this.value.includes(v.value));
24+
const value = this.value;
25+
if (!value) {
26+
return;
27+
}
28+
const notSelected = this.options.filter((v) => !value.includes(v.value));
2529
this.value = notSelected.map((v) => v.value);
2630
}
2731

packages/core/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"extends": "../../tsconfig.json"
2+
"extends": "../../tsconfig.json",
3+
"include": ["src"]
34
}

packages/prompts/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
"scripts": {
5151
"build": "unbuild",
5252
"prepack": "pnpm build",
53-
"test": "FORCE_COLOR=1 vitest run"
53+
"test": "FORCE_COLOR=1 vitest run",
54+
"typecheck": "tsc --noEmit"
5455
},
5556
"dependencies": {
5657
"@clack/core": "workspace:*",
@@ -62,6 +63,7 @@
6263
"memfs": "^4.17.2",
6364
"vitest": "^3.2.4",
6465
"vitest-ansi-serializer": "^0.1.2",
65-
"fast-wrap-ansi": "^0.1.3"
66+
"fast-wrap-ansi": "^0.1.3",
67+
"typescript": "catalog:"
6668
}
6769
}

packages/prompts/src/note.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import process from 'node:process';
22
import type { Writable } from 'node:stream';
33
import { stripVTControlCharacters as strip } from 'node:util';
4+
import { getColumns } from '@clack/core';
45
import { wrapAnsi } from 'fast-wrap-ansi';
56
import color from 'picocolors';
67
import {
@@ -13,13 +14,14 @@ import {
1314
S_STEP_SUBMIT,
1415
} from './common.js';
1516

17+
type FormatFn = (line: string) => string;
1618
export interface NoteOptions extends CommonOptions {
17-
format?: (line: string) => string;
19+
format?: FormatFn;
1820
}
1921

2022
const defaultNoteFormatter = (line: string): string => color.dim(line);
2123

22-
const wrapWithFormat = (message: string, width: number, format: NoteOptions['format']): string => {
24+
const wrapWithFormat = (message: string, width: number, format: FormatFn): string => {
2325
const wrapMsg = wrapAnsi(message, width).split('\n');
2426
const maxWidthNormal = wrapMsg.reduce((sum, ln) => Math.max(strip(ln).length, sum), 0);
2527
const maxWidthFormat = wrapMsg
@@ -32,7 +34,7 @@ const wrapWithFormat = (message: string, width: number, format: NoteOptions['for
3234
export const note = (message = '', title = '', opts?: NoteOptions) => {
3335
const output: Writable = opts?.output ?? process.stdout;
3436
const format = opts?.format ?? defaultNoteFormatter;
35-
const wrapMsg = wrapWithFormat(message, output.columns - 6, format);
37+
const wrapMsg = wrapWithFormat(message, getColumns(output) - 6, format);
3638
const lines = ['', ...wrapMsg.split('\n').map(format), ''];
3739
const titleLen = strip(title).length;
3840
const len =

packages/prompts/test/__snapshots__/note.test.ts.snap

Lines changed: 112 additions & 120 deletions
Large diffs are not rendered by default.

packages/prompts/test/note.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ describe.each(['true', 'false'])('note (isCI = %s)', (isCI) => {
6565
});
6666

6767
test("don't overflow", () => {
68-
const input = `${'test string '.repeat(32)}\n`.repeat(4).trim();
69-
prompts.note(input, 'title', {
68+
const message = `${'test string '.repeat(32)}\n`.repeat(4).trim();
69+
prompts.note(message, 'title', {
7070
input,
7171
output: Object.assign(output, { columns: 75 }),
7272
});
@@ -75,8 +75,8 @@ describe.each(['true', 'false'])('note (isCI = %s)', (isCI) => {
7575
});
7676

7777
test("don't overflow with formatter", () => {
78-
const input = `${'test string '.repeat(32)}\n`.repeat(4).trim();
79-
prompts.note(input, 'title', {
78+
const message = `${'test string '.repeat(32)}\n`.repeat(4).trim();
79+
prompts.note(message, 'title', {
8080
format: (line) => colors.red(`* ${colors.cyan(line)} *`),
8181
input,
8282
output: Object.assign(output, { columns: 75 }),

0 commit comments

Comments
 (0)