Skip to content

Instantly share code, notes, and snippets.

@its-monotype
Created July 30, 2022 20:15
Show Gist options
  • Save its-monotype/7d3f8d3a5745628a3581b3e7a85385a3 to your computer and use it in GitHub Desktop.
Save its-monotype/7d3f8d3a5745628a3581b3e7a85385a3 to your computer and use it in GitHub Desktop.
NestJS ParseIntSlugPipe. Useful when you need to get slug or id from param.
import {
ArgumentMetadata,
HttpStatus,
Injectable,
Optional,
PipeTransform
} from '@nestjs/common';
import {
ErrorHttpStatusCode,
HttpErrorByCode
} from '@nestjs/common/utils/http-error-by-code.util';
import { isString } from 'class-validator';
export interface ParseIntSlugPipeOptions {
errorHttpStatusCode?: ErrorHttpStatusCode;
exceptionFactory?: (error: string) => any;
}
@Injectable()
export class ParseIntSlugPipe implements PipeTransform<string> {
protected static slugRegExp = /^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/;
protected exceptionFactory: (error: string) => any;
constructor(@Optional() options?: ParseIntSlugPipeOptions) {
options = options || {};
const { exceptionFactory, errorHttpStatusCode = HttpStatus.BAD_REQUEST } =
options;
this.exceptionFactory =
exceptionFactory ||
(error => new HttpErrorByCode[errorHttpStatusCode](error));
}
async transform(
value: string,
metadata: ArgumentMetadata
): Promise<number | string> {
if (this.isNumeric(value)) {
return parseInt(value, 10);
} else if (this.isSlug(value)) {
return value;
} else {
throw this.exceptionFactory(
'Validation failed (numeric string or slug string is expected)'
);
}
}
protected isNumeric(value: string): boolean {
return (
['string', 'number'].includes(typeof value) &&
/^-?\d+$/.test(value) &&
isFinite(value as any)
);
}
protected isSlug(str: unknown) {
if (!isString(str)) {
throw this.exceptionFactory('The value passed as Slug is not a string');
}
const pattern = ParseIntSlugPipe.slugRegExp;
return pattern?.test(str);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment