@hermiforge-decorix/angular-reactive
v0.4.0
Published
Angular Reactive Forms adapter for Decorix metadata.
Maintainers
Readme
@hermiforge-decorix/angular-reactive

Angular Reactive Forms adapter for Decorix metadata.
Full usage guide:
docs/(narrative walkthrough beyond this package's API reference).
Install
pnpm add @hermiforge-decorix/core @hermiforge-decorix/angular-reactive @angular/core @angular/formsPeer dependencies: @angular/[email protected], @angular/[email protected].
For runtime validate support, also install a validator adapter such as Zod:
pnpm add @hermiforge-decorix/zod zodDecorated Class
import {Email, Label, MinLength, Model, Required} from '@hermiforge-decorix/core';
import {toReactiveFormConfig} from '@hermiforge-decorix/angular-reactive';
@Model('SignupDto')
class SignupDto {
@Required('Name is required')
@MinLength(2, 'Name is too short')
@Label('Name')
name!: string;
@Required('Email is required')
@Email('Invalid email')
email!: string;
}
const config = toReactiveFormConfig(SignupDto, {
initialValue: {name: 'Ada'}
});
// Default mode: Angular ValidatorFn[] ready for Reactive Forms.
const nameValidators = config.fields[0]?.validators;TModel is inferred straight from SignupDto, independently of TValidationMode (the 'angular' | 'descriptors' | 'both' output mode) — config.validate/validateAsync are already typed ValidationResult<SignupDto>, no separate form-values type or cast needed.
Builder Model
import {model, stringField} from '@hermiforge-decorix/core';
import {createZodValidatorAdapter} from '@hermiforge-decorix/zod';
import {toReactiveFormConfig} from '@hermiforge-decorix/angular-reactive';
const SignupDto = model('SignupDto', {
name: stringField().required('Name is required').minLength(2, 'Name is too short').label('Name'),
email: stringField().required('Email is required').email('Invalid email')
});
const config = toReactiveFormConfig(SignupDto, {
validator: createZodValidatorAdapter()
});
const result = config.validate?.({name: 'Ada', email: '[email protected]'});Validation Modes
toReactiveFormConfig() generates Angular-compatible ValidatorFn[] by default. The generated validators use Angular error keys such as required, minlength, maxlength, email, pattern, min, and max; Decorix messages are included in the error payload when available.
const angularConfig = toReactiveFormConfig(SignupDto);
angularConfig.fields[0]?.validators; // ValidatorFn[]Use validationMode: 'descriptors' when you need the framework-neutral Decorix constraint descriptors that older versions exposed in validators.
const descriptorConfig = toReactiveFormConfig(SignupDto, {
validationMode: 'descriptors'
});
descriptorConfig.fields[0]?.validators; // {kind, value?, message?}[]Use validationMode: 'both' during migration when Angular should receive ValidatorFn[] while your integration still needs descriptors.
const bothConfig = toReactiveFormConfig(SignupDto, {
validationMode: 'both'
});
bothConfig.fields[0]?.validators; // ValidatorFn[]
bothConfig.fields[0]?.validatorDescriptors; // {kind, value?, message?}[]Async Validators
Async constraints cannot run inside Angular's synchronous ValidatorFn, so they
are emitted as asyncValidators: AsyncValidatorFn[] on the field config. The form
config also exposes validateAsync for full model validation resolving async and
cross-field constraints.
const config = toReactiveFormConfig(SignupDto);
config.fields[0]?.asyncValidators; // AsyncValidatorFn[] for async constraints
await config.validateAsync?.({name: 'Ada', email: '[email protected]'});Runtime Validation
Angular validators do not require a Decorix ValidatorAdapter. options.validator and registerZodValidator() only control the optional config.validate/config.validateAsync functions, which perform full model validation through the selected runtime validator adapter.
License
LGPL-3.0-or-later — see the repository LICENSE.
