Skip to content

Instantly share code, notes, and snippets.

@Bastianowicz
Last active November 15, 2021 17:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bastianowicz/c787b97d3ecf6e8a2e388fff9905c80c to your computer and use it in GitHub Desktop.
Save Bastianowicz/c787b97d3ecf6e8a2e388fff9905c80c to your computer and use it in GitHub Desktop.
Nestjs Decorator to mark Models properties as sortable and Validtor to check if given properties are sortable
@Get()
async get(
@Req() req: Request,
@Query() orderQueryParams?: OrderQueryParam<IItemResponse>
): Promise<{ items: IItemResponse[] }> {
// your code here...
}
export class OrderQueryParam<T extends {}> {
@IsOptional()
@IsString()
@IsAlphanumeric()
@IsSortable(ItemResponse)
orderBy: keyof T | undefined;
@IsBoolean()
@IsOptional()
@Transform(params => params.value === "true" ? true : params.value === "false" ? false : undefined)
asc: boolean | undefined;
}
export class ResponseItem {
unsortable: anyType;
@Sortable
creationDate: number;
@Sortable
name: string;
}
import {registerDecorator, ValidationArguments, ValidationOptions} from "class-validator";
export const sortableFields = "sortableFields";
/**
* Decorator to define which Properties can be used to order result list
* @param target
* @param key
*/
export function Sortable(target: {}, key: string): void {
target[sortableFields] = target[sortableFields] !== undefined
? [...target[sortableFields], key]
: [key];
}
/**
* Check if a property is valid as order argument
* @param ModelConstructor What model shall the property be validated against?
* Use @Sortable to define sortable properties
* @param validationOptions
* @constructor
*/
export function IsSortable(
ModelConstructor: new (...any) => {}, validationOptions?: ValidationOptions
): (object: Object, propertyName: string) => void {
return (object: Object, propertyName: string): void => {
registerDecorator({
name: "isSortable",
target: object.constructor,
propertyName: propertyName,
constraints: [ModelConstructor],
options: validationOptions,
validator: {
defaultMessage() {
return "orderBy=$value is not allowed!";
},
validate(value: unknown, args: ValidationArguments) {
const [constructor] = args.constraints;
return typeof value === "string"
&& typeof constructor === "function"
&& constructor.prototype.sortableFields !== undefined
&& constructor.prototype.sortableFields.includes(value);
}
}
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment