Skip to content

feat: add async validation - #583

Open
43081j wants to merge 2 commits into
mainfrom
jg/async-validators
Open

feat: add async validation#583
43081j wants to merge 2 commits into
mainfrom
jg/async-validators

Conversation

@43081j

@43081j 43081j commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

This adds the ability to have async validation to all prompts.

For now, only the text prompt will render a validating message.

Every other prompt needs its own individual follow-up PR to add support for rendering the new validating state. They will all accept an async validator but will not show a message while validating right now.

Closes #92

Type of change

  • Bug fix
  • Feature
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • I have added a changeset

AI-generated code disclosure

  • This PR includes AI-generated code

This adds the ability to have async validation to all prompts.

**For now, only the text prompt will render a validating message.**

Every other prompt needs its own individual follow-up PR to add support
for rendering the new `validating` state. They will all accept an async
validator but will not show a message while validating right now.
@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9d8c67a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@clack/prompts Minor
@clack/core Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

commit: 9d8c67a

Comment thread packages/core/src/utils/validation.ts Outdated
@43081j
43081j marked this pull request as ready for review July 24, 2026 14:48
@43081j
43081j requested a review from dreyfus92 July 24, 2026 14:49

@dreyfus92 dreyfus92 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome job james, left a few comments 👀

}

private onKeypress(char: string | undefined, key: Key) {
private async onKeypress(char: string | undefined, key: Key) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is now async but the emitter doesn't await it, so input keeps flowing while a validation is in flight. so i feel like there are 2 problems maybe i'm overthinking u tell me:

  • press return twice fast and you get 2 concurrent validations. the first one can resolve, emit submit, close the prompt and then second resolves and tries to render/emit on a finalizad prompt. state gets tangled.
  • the user can keep typing while validating, mutating value mid-flight. then the error or submit applies to a stale value, and the rendered dimmed input won't match what was validated.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch!

we may be able to just return early when we're validating, i.e. ignore all key presses during validation

) {
this.state = 'validating';
this.render();
problem = await problemResult;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the async validator throws (network error, w/e), this will throw inside an un-awaited async handler. that's an unhandled promise rejection, which kills the process in node. probably it might be better to do a try/catch? so that routes the thrown error into this.error / state = 'error' instead. also maybe would be worth a test case too.

Comment on lines +246 to +248
problemResult !== undefined &&
typeof problemResult !== 'string' &&
!(problemResult instanceof Error)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
problemResult !== undefined &&
typeof problemResult !== 'string' &&
!(problemResult instanceof Error)
problemResult instanceof Promise

wouldn't be a more clean approach for the check to be set this way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Async validation

3 participants