add constraint
This commit is contained in:
parent
116b92fe98
commit
764fe06c50
69
src/modules/core/constraints/data.exist.constraint.ts
Normal file
69
src/modules/core/constraints/data.exist.constraint.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import {
|
||||||
|
ValidationArguments,
|
||||||
|
ValidatorConstraint,
|
||||||
|
ValidatorConstraintInterface,
|
||||||
|
ValidationOptions,
|
||||||
|
registerDecorator,
|
||||||
|
} from 'class-validator';
|
||||||
|
import { ObjectType, Repository, DataSource } from 'typeorm';
|
||||||
|
|
||||||
|
type Condition = {
|
||||||
|
entity: ObjectType<any>;
|
||||||
|
map?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
@ValidatorConstraint({ name: 'dataExist', async: true })
|
||||||
|
@Injectable()
|
||||||
|
export class DataExistConstraint implements ValidatorConstraintInterface {
|
||||||
|
constructor(private dataSource: DataSource) {}
|
||||||
|
|
||||||
|
async validate(value: any, validationArguments?: ValidationArguments) {
|
||||||
|
let repo: Repository<any>;
|
||||||
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let map = 'id';
|
||||||
|
if ('entity' in validationArguments.constraints[0]) {
|
||||||
|
map = validationArguments.constraints[0].map ?? 'id';
|
||||||
|
repo = this.dataSource.getRepository(validationArguments.constraints[0].entitiy);
|
||||||
|
} else {
|
||||||
|
repo = this.dataSource.getRepository(validationArguments.constraints[0]);
|
||||||
|
}
|
||||||
|
const item = await repo.findOne({ where: { [map]: value } });
|
||||||
|
return !!item;
|
||||||
|
}
|
||||||
|
defaultMessage?(validationArguments?: ValidationArguments): string {
|
||||||
|
if (!validationArguments.constraints[0]) {
|
||||||
|
return 'Model not been specified!';
|
||||||
|
}
|
||||||
|
return `All instance of ${validationArguments.constraints[0].name} must been exists in databse!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function IsDataExist(
|
||||||
|
entity: ObjectType<any>,
|
||||||
|
validationOptions?: ValidationOptions,
|
||||||
|
): (object: RecordAny, propertyName: string) => void;
|
||||||
|
|
||||||
|
function IsDataExist(
|
||||||
|
condition: Condition,
|
||||||
|
validationOptions?: ValidationOptions,
|
||||||
|
): (object: RecordAny, propertyName: string) => void;
|
||||||
|
|
||||||
|
function IsDataExist(
|
||||||
|
condition: Condition | ObjectType<any>,
|
||||||
|
validationOptions?: ValidationOptions,
|
||||||
|
): (object: RecordAny, propertyName: string) => void {
|
||||||
|
return (object: RecordAny, propertyName: string) => {
|
||||||
|
registerDecorator({
|
||||||
|
target: object.constructor,
|
||||||
|
propertyName,
|
||||||
|
options: validationOptions,
|
||||||
|
constraints: [condition],
|
||||||
|
validator: DataExistConstraint,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { IsDataExist };
|
68
src/modules/core/constraints/unique.constraint.ts
Normal file
68
src/modules/core/constraints/unique.constraint.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import {
|
||||||
|
registerDecorator,
|
||||||
|
ValidationArguments,
|
||||||
|
ValidatorConstraint,
|
||||||
|
ValidatorConstraintInterface,
|
||||||
|
ValidationOptions,
|
||||||
|
} from 'class-validator';
|
||||||
|
import { isNil, merge } from 'lodash';
|
||||||
|
import { DataSource, ObjectType } from 'typeorm';
|
||||||
|
|
||||||
|
type Condition = {
|
||||||
|
entity: ObjectType<any>;
|
||||||
|
property?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@ValidatorConstraint({ name: 'dataUnique', async: true })
|
||||||
|
export class UniqueConstraint implements ValidatorConstraintInterface {
|
||||||
|
constructor(private dataSource: DataSource) {}
|
||||||
|
|
||||||
|
async validate(value: any, validationArguments?: ValidationArguments): Promise<boolean> {
|
||||||
|
const config: Omit<Condition, 'entity'> = { property: validationArguments.property };
|
||||||
|
const condition = ('entity' in validationArguments.constraints[0]
|
||||||
|
? merge(config, validationArguments.constraints[0])
|
||||||
|
: {
|
||||||
|
...config,
|
||||||
|
entity: validationArguments.constraints[0],
|
||||||
|
}) as unknown as Required<Condition>;
|
||||||
|
if (!condition.entity) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const repo = this.dataSource.getRepository(condition.entity);
|
||||||
|
return isNil(
|
||||||
|
await repo.findOne({ where: { [condition.property]: value }, withDeleted: true }),
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultMessage?(validationArguments?: ValidationArguments): string {
|
||||||
|
const { entity, property } = validationArguments.constraints[0];
|
||||||
|
const queryProperty = property ?? validationArguments.property;
|
||||||
|
if (!(validationArguments.object as any).getManager) {
|
||||||
|
return 'getManager function not been found!';
|
||||||
|
}
|
||||||
|
if (!entity) {
|
||||||
|
return 'Model not been specified!';
|
||||||
|
}
|
||||||
|
return `${queryProperty} of ${entity.name} must been unique!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function IsUnique(
|
||||||
|
params: ObjectType<any> | Condition,
|
||||||
|
validationOptions: ValidationOptions,
|
||||||
|
) {
|
||||||
|
return (object: RecordAny, propertyName: string) => {
|
||||||
|
registerDecorator({
|
||||||
|
target: object.constructor,
|
||||||
|
propertyName,
|
||||||
|
options: validationOptions,
|
||||||
|
constraints: [params],
|
||||||
|
validator: UniqueConstraint,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user