✨ feat: add 30 validation decorators, @ValidateIf and @Allow
Rounds out the validator set with the rules an application actually reaches for,
all following the existing decorator style and honouring each/message options.
- equality and presence: @Equals, @NotEquals, @IsEmpty, @IsEnum, @IsInstance
- strings: @Length, @IsAlpha, @IsAlphanumeric, @IsNumberString, @IsLowercase,
@IsUppercase, @Contains, @NotContains, @StartsWith, @EndsWith
- formats: @IsUUID, @IsJSON, @IsDateString, @IsSemVer, @IsHexColor, @IsIP
- numbers: @IsDivisibleBy, @IsPort, @IsLatitude, @IsLongitude, @IsBigInt
- dates: @MinDate, @MaxDate
- arrays: @ArrayUnique, @ArrayContains, @ArrayNotContains
@ValidateIf(o => ...) makes a property's rules conditional on the rest of the
object, and @Allow() declares a property that needs no rules of its own so it
survives unknownKeys: 'strip'.
Two details worth noting. @IsEnum filters the reverse mapping a numeric enum
compiles to, so 'Low' is not accepted as a value of enum { Low, High }.
@MinDate/@MaxDate accept a thunk, so "not in the past" is evaluated per
validation instead of being frozen when the class was declared.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK
This commit is contained in:
@@ -365,6 +365,12 @@ async function validateInternal(obj: any, ancestors: Set<any>): Promise<Validati
|
||||
constraints: {}
|
||||
};
|
||||
|
||||
// Handle @ValidateIf — a false condition takes the property out of validation entirely.
|
||||
const condition = metadataStorage.getMetadata(METADATA_KEYS.CONDITION, target, key);
|
||||
if (condition && !condition(obj)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle IsOptional
|
||||
const isOptional = metadataStorage.getMetadata(METADATA_KEYS.IS_OPTIONAL, target, key);
|
||||
const isNullOrUndefined = value === null || value === undefined;
|
||||
|
||||
Reference in New Issue
Block a user