@candraadi93/validator-core
v0.1.0
Published
Decorator-based validation library for Angular Reactive Forms. Define validation rules directly inside **TypeScript model classes** using decorators — similar to DTO validation in NestJS.
Readme
@candra-dev/validator-core
Decorator-based validation library for Angular Reactive Forms.
Define validation rules directly inside TypeScript model classes using decorators — similar to DTO validation in NestJS.
This library allows you to keep validation rules centralized, consistent, reusable, and highly scalable for enterprise applications.
✨ Features
- ✔ Decorator-based validation (@Required, @MinLength, @Regex, @Custom, ...)
- ✔ Centralized rules in model classes (similar to NestJS DTO)
- ✔ Works with Angular Reactive Forms
- ✔ Custom error message provider (injectable)
- ✔ Minimal, zero dependencies (except reflect-metadata)
- ✔ Fully tree-shakeable Angular library
- ✔ Supports dynamic + custom validation logic
📦 Installation
Install from NPM:
npm install @candra-dev/validator-core reflect-metadata
Add to main.ts (or polyfills.ts):
import 'reflect-metadata';
import { ValidatorCoreModule } from '@candra-dev/validator-core';
@NgModule({
imports: [
ValidatorCoreModule.forRoot()
]
})
export class AppModule {}
🧭 Step-by-Step Guide
⭐ Step 1 — Create a Model Class With Decorators
// src/app/models/login.model.ts
import { Required, MinLength } from '@candra-dev/validator-core';
export class LoginModel {
@Required()
username!: string;
@Required()
@MinLength(6)
password!: string;
}
⭐ Step 2 — Build a Reactive Form Using the Model
// src/app/login/login.component.ts
import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { buildValidator } from '@candra-dev/validator-core';
import { LoginModel } from '../models/login.model';
@Component({
selector: 'app-login',
templateUrl: './login.component.html'
})
export class LoginComponent {
form = this.fb.group({
username: [''],
password: ['']
}, {
validators: buildValidator(LoginModel)
});
constructor(private fb: FormBuilder) {}
submit() {
console.log(this.form.value);
}
}
⭐ Step 3 — Display Errors in Template
<form [formGroup]="form" (ngSubmit)="submit()">
<input formControlName="username" placeholder="Username" />
<div *ngIf="form.errors?.username?.required">
Username is required.
</div>
<input formControlName="password" placeholder="Password" />
<div *ngIf="form.errors?.password?.minLength">
Password must be at least 6 characters.
</div>
<button type="submit">Login</button>
</form>
🧠 Built-in Decorators
| Decorator | Description |
| ------------------- | ----------------------- |
| `@Required()` | Cannot be empty |
| `@MinLength(n)` | Minimum length |
| `@MaxLength(n)` | Maximum length |
| `@Regex(/pattern/)` | Must match pattern |
| `@Custom(fn)` | Custom validation logic |
🔥 Custom Validator Example
import { Required, Custom } from '@candra-dev/validator-core';
export class RegisterModel {
@Required()
password!: string;
@Required()
@Custom((value, obj) => value === obj.password)
confirmPassword!: string;
}
🎨 Custom Error Messages (Optional)
You can override all default messages.
1️⃣ Create your own provider
// src/app/services/my-error-messages.ts
import { IErrorMessageProvider } from '@candra-dev/validator-core';
export class MyErrorMessages implements IErrorMessageProvider {
getMessage(key: string, ctx?: any): string {
switch (key) {
case 'required':
return 'Wajib diisi!';
case 'minLength':
return `Minimal ${ctx?.min} karakter`;
default:
return 'Data tidak valid.';
}
}
}
2️⃣ Register it in AppModule
ValidatorCoreModule.forRoot({
useClass: MyErrorMessages
})
Done — now your custom messages apply globally.
🔧 Full Decorator Example
export class ProductModel {
@Required()
name!: string;
@MinLength(3)
@MaxLength(50)
description!: string;
@Regex(/^[0-9]+$/)
price!: string;
@Custom((value, all) => value <= all.maxStock)
quantity!: number;
maxStock = 100;
}
⚙ API Reference
buildValidator(ModelClass)
Creates an Angular validator that reads metadata from model decorators.
form = fb.group({ ... }, { validators: buildValidator(MyModel) });
Decorators
@Required()
@MinLength(n)
@MaxLength(n)
@Regex(/pattern/)
@Custom(fn)
Injection Token
ERROR_MESSAGE_PROVIDER
📄 License
MIT License © 2025 Candra