Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/kind-yaks-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@clack/prompts": patch
"@clack/core": patch
---

Add missing nullish checks around values.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
[*.{yml,json,yaml}]
indent_style = space
indent_size = 2
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dev": "pnpm --filter @example/changesets run start",
"format": "biome check --write",
"lint": "biome lint --write --unsafe",
"types": "biome lint --write --unsafe",
"types": "tsc --noEmit",
"deps": "pnpm exec knip --production",
"test": "pnpm --color -r run test",
"pretest": "pnpm run build"
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/prompts/multi-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ export default class MultiSelectPrompt<T extends { value: any }> extends Prompt<
}

private toggleInvert() {
const notSelected = this.options.filter((v) => !this.value.includes(v.value));
const value = this.value;
if (!value) {
return;
}
const notSelected = this.options.filter((v) => !value.includes(v.value));
this.value = notSelected.map((v) => v.value);
}

Expand Down
3 changes: 2 additions & 1 deletion packages/core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"extends": "../../tsconfig.json"
"extends": "../../tsconfig.json",
"include": ["src"]
}
8 changes: 5 additions & 3 deletions packages/prompts/src/note.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import process from 'node:process';
import type { Writable } from 'node:stream';
import { stripVTControlCharacters as strip } from 'node:util';
import { getColumns } from '@clack/core';
import { wrapAnsi } from 'fast-wrap-ansi';
import color from 'picocolors';
import {
Expand All @@ -13,13 +14,14 @@ import {
S_STEP_SUBMIT,
} from './common.js';

type FormatFn = (line: string) => string;
export interface NoteOptions extends CommonOptions {
format?: (line: string) => string;
format?: FormatFn;
}

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

const wrapWithFormat = (message: string, width: number, format: NoteOptions['format']): string => {
const wrapWithFormat = (message: string, width: number, format: FormatFn): string => {
const wrapMsg = wrapAnsi(message, width).split('\n');
const maxWidthNormal = wrapMsg.reduce((sum, ln) => Math.max(strip(ln).length, sum), 0);
const maxWidthFormat = wrapMsg
Expand All @@ -32,7 +34,7 @@ const wrapWithFormat = (message: string, width: number, format: NoteOptions['for
export const note = (message = '', title = '', opts?: NoteOptions) => {
const output: Writable = opts?.output ?? process.stdout;
const format = opts?.format ?? defaultNoteFormatter;
const wrapMsg = wrapWithFormat(message, output.columns - 6, format);
const wrapMsg = wrapWithFormat(message, getColumns(output) - 6, format);
const lines = ['', ...wrapMsg.split('\n').map(format), ''];
const titleLen = strip(title).length;
const len =
Expand Down
232 changes: 112 additions & 120 deletions packages/prompts/test/__snapshots__/note.test.ts.snap

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions packages/prompts/test/note.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ describe.each(['true', 'false'])('note (isCI = %s)', (isCI) => {
});

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

test("don't overflow with formatter", () => {
const input = `${'test string '.repeat(32)}\n`.repeat(4).trim();
prompts.note(input, 'title', {
const message = `${'test string '.repeat(32)}\n`.repeat(4).trim();
prompts.note(message, 'title', {
format: (line) => colors.red(`* ${colors.cyan(line)} *`),
input,
output: Object.assign(output, { columns: 75 }),
Expand Down
2 changes: 1 addition & 1 deletion packages/prompts/test/password.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ describe.each(['true', 'false'])('password (isCI = %s)', (isCI) => {
const result = prompts.password({
message: 'foo',
validate: (value) => {
if (value.length < 2) {
if (!value || value.length < 2) {
return 'Password must be at least 2 characters';
}

Expand Down
3 changes: 2 additions & 1 deletion packages/prompts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"extends": "../../tsconfig.json"
"extends": "../../tsconfig.json",
"include": ["src"]
}
7 changes: 5 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
"verbatimModuleSyntax": true,
"lib": ["ES2022"],
"paths": {
"@clack/core": ["./packages/core/src"]
"@clack/core": ["./packages/core/src/index.ts"],
"@clack/prompts": ["./packages/prompts/src/index.ts"]
}
},
"include": ["packages"]
"include": [
"packages/*/src/**/*"
]
}
Loading