diff --git a/.changeset/kind-yaks-clean.md b/.changeset/kind-yaks-clean.md new file mode 100644 index 00000000..ded1c4d4 --- /dev/null +++ b/.changeset/kind-yaks-clean.md @@ -0,0 +1,6 @@ +--- +"@clack/prompts": patch +"@clack/core": patch +--- + +Add missing nullish checks around values. diff --git a/.editorconfig b/.editorconfig index 1c6314a3..49e78aff 100644 --- a/.editorconfig +++ b/.editorconfig @@ -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 diff --git a/package.json b/package.json index fec0f955..b902cead 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/packages/core/src/prompts/multi-select.ts b/packages/core/src/prompts/multi-select.ts index b38e3357..2781910e 100644 --- a/packages/core/src/prompts/multi-select.ts +++ b/packages/core/src/prompts/multi-select.ts @@ -21,7 +21,11 @@ export default class MultiSelectPrompt 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); } diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 4082f16a..596e2cf7 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "../../tsconfig.json" + "extends": "../../tsconfig.json", + "include": ["src"] } diff --git a/packages/prompts/src/note.ts b/packages/prompts/src/note.ts index 2d6e2b53..3628d462 100644 --- a/packages/prompts/src/note.ts +++ b/packages/prompts/src/note.ts @@ -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 { @@ -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 @@ -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 = diff --git a/packages/prompts/test/__snapshots__/note.test.ts.snap b/packages/prompts/test/__snapshots__/note.test.ts.snap index 7135875d..b1f95e1c 100644 --- a/packages/prompts/test/__snapshots__/note.test.ts.snap +++ b/packages/prompts/test/__snapshots__/note.test.ts.snap @@ -3,34 +3,34 @@ exports[`note (isCI = false) > don't overflow 1`] = ` [ "│ -◇ title ──────────────────────────────────────────────────────────────╮ -│ │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ │ -├──────────────────────────────────────────────────────────────────────╯ +◇ title ───────────────────────────────────────────────────────────────────╮ +│ │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ │ +├───────────────────────────────────────────────────────────────────────────╯ ", ] `; @@ -38,38 +38,34 @@ exports[`note (isCI = false) > don't overflow 1`] = ` exports[`note (isCI = false) > don't overflow with formatter 1`] = ` [ "│ -◇ title ────────────────────────────────────────────────────────────────╮ -│ │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ │ -├────────────────────────────────────────────────────────────────────────╯ +◇ title ──────────────────────────────────────────────────────────────────╮ +│ │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ │ +├──────────────────────────────────────────────────────────────────────────╯ ", ] `; @@ -130,34 +126,34 @@ exports[`note (isCI = false) > renders message with title 1`] = ` exports[`note (isCI = true) > don't overflow 1`] = ` [ "│ -◇ title ──────────────────────────────────────────────────────────────╮ -│ │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string test string │ -│ test string test string test string test string test string test │ -│ string test string test string test string test string │ -│ │ -├──────────────────────────────────────────────────────────────────────╯ +◇ title ───────────────────────────────────────────────────────────────────╮ +│ │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string test string test string test string test string │ +│ test string test string │ +│ │ +├───────────────────────────────────────────────────────────────────────────╯ ", ] `; @@ -165,38 +161,34 @@ exports[`note (isCI = true) > don't overflow 1`] = ` exports[`note (isCI = true) > don't overflow with formatter 1`] = ` [ "│ -◇ title ────────────────────────────────────────────────────────────────╮ -│ │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ * test string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string test string test string test string test * │ -│ * string test string * │ -│ │ -├────────────────────────────────────────────────────────────────────────╯ +◇ title ──────────────────────────────────────────────────────────────────╮ +│ │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string test string * │ +│ * test string test string test string test string test string test * │ +│ * string test string test string test string test string * │ +│ │ +├──────────────────────────────────────────────────────────────────────────╯ ", ] `; diff --git a/packages/prompts/test/note.test.ts b/packages/prompts/test/note.test.ts index d68cbada..85ca4ebe 100644 --- a/packages/prompts/test/note.test.ts +++ b/packages/prompts/test/note.test.ts @@ -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 }), }); @@ -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 }), diff --git a/packages/prompts/test/password.test.ts b/packages/prompts/test/password.test.ts index 3d118f83..4db940ec 100644 --- a/packages/prompts/test/password.test.ts +++ b/packages/prompts/test/password.test.ts @@ -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'; } diff --git a/packages/prompts/tsconfig.json b/packages/prompts/tsconfig.json index 4082f16a..596e2cf7 100644 --- a/packages/prompts/tsconfig.json +++ b/packages/prompts/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "../../tsconfig.json" + "extends": "../../tsconfig.json", + "include": ["src"] } diff --git a/tsconfig.json b/tsconfig.json index 50008170..966a093a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -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/**/*" + ] }