From ee11098d7a2f130ef50376389bb542b40e3fecb2 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 17 May 2022 08:59:33 -0400 Subject: [PATCH] Fix changes to InputValidator to resolve accidental breaking changes Signed-off-by: Sebastian Malton --- .../components/input/input_validators.ts | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/renderer/components/input/input_validators.ts b/src/renderer/components/input/input_validators.ts index a9844bfcd8..362248fa17 100644 --- a/src/renderer/components/input/input_validators.ts +++ b/src/renderer/components/input/input_validators.ts @@ -11,7 +11,24 @@ import { TypedRegEx } from "typed-regex"; export class AsyncInputValidationError extends Error { } -export type InputValidator = { +export type InputValidationResult = + IsAsync extends true + ? Promise + : boolean; + +export type InputValidation = ( + RequireProps extends true + ? (value: string, props: InputProps) => InputValidationResult + : (value: string, props?: InputProps) => InputValidationResult +); + +export type SyncValidationMessageBuilder = ( + RequireProps extends true + ? (value: string, props: InputProps) => ReactNode + : (value: string, props?: InputProps) => ReactNode +); + +export type InputValidator = { /** * Filters itself based on the input props */ @@ -19,8 +36,8 @@ export type InputValidator = { } & ( IsAsync extends false ? { - validate: (value: string, props: InputProps) => boolean; - message: ReactNode | ((value: string, props: InputProps) => ReactNode | string); + validate: InputValidation; + message: ReactNode | SyncValidationMessageBuilder; debounce?: undefined; } : { @@ -29,13 +46,23 @@ export type InputValidator = { * * This function MUST reject with an instance of {@link AsyncInputValidationError} */ - validate: (value: string, props: InputProps) => Promise; + validate: InputValidation; message?: undefined; debounce: number; } ); -export function inputValidator(validator: InputValidator): InputValidator { +export function asyncInputValidator(validator: InputValidator): InputValidator; +export function asyncInputValidator(validator: InputValidator): InputValidator; + +export function asyncInputValidator(validator: InputValidator): InputValidator { + return validator; +} + +export function inputValidator(validator: InputValidator): InputValidator; +export function inputValidator(validator: InputValidator): InputValidator; + +export function inputValidator(validator: InputValidator): InputValidator { return validator; } @@ -51,7 +78,7 @@ export const isEmail = inputValidator({ validate: value => !!value.match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/), }); -export const isNumber = inputValidator({ +export const isNumber = inputValidator({ condition: ({ type }) => type === "number", message(value, { min, max }) { const minMax: string = [ @@ -100,7 +127,7 @@ export const isExtensionNameInstall = inputValidator({ validate: value => isExtensionNameInstallRegex.isMatch(value), }); -export const isPath = inputValidator({ +export const isPath = asyncInputValidator({ debounce: 100, condition: ({ type }) => type === "text", validate: async value => { @@ -112,14 +139,14 @@ export const isPath = inputValidator({ }, }); -export const minLength = inputValidator({ +export const minLength = inputValidator({ condition: ({ minLength }) => !!minLength, message: (value, { minLength }) => `Minimum length is ${minLength}`, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion validate: (value, { minLength }) => value.length >= minLength!, }); -export const maxLength = inputValidator({ +export const maxLength = inputValidator({ condition: ({ maxLength }) => !!maxLength, message: (value, { maxLength }) => `Maximum length is ${maxLength}`, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion