aurelia / aurelia/validation

Add alternative to fluent rule API that enables creating rules from data

Open
#363 9 comments 0 reactions 0 assignees View on GitHub
awaiting-feedback enhancement
Dominant language
TypeScript
Stars
129
Forks
125
PR merge metrics
No merged PRs in 30d

Description

**Use Case**
Looping over a set of model properties to apply validation rules to each.

**Problem**
Currently, three different object classes are used in this scenario. This adds complexity to coding in TypeScript. Consider the following code:

```
let ruleSetter: FluentRules | FluentRuleCustomizer = null;

for (let property of formSchema.properties) {

if (this.requiresValidation(property, formSchema)) {

/**
* ... then first we will call ensure.displayName, returning FluentRules,
* and second will call at least one method that will return FluentRuleCustomizer.
* Thus each time we reach here ruleSetter will be a FluentRuleCustomizer (except the first time, when it is null),
* whereupon we will immediately convert it into a FluentRules and then again to a FluentRuleCustomizer.
*/
if (ruleSetter === null) {
ruleSetter = ValidationRules
.ensure(property.name)
.displayName(property.description);

// at this point, ruleSetter is a FluentRules

} else {
/**
* At this point we know it is a FluentRuleCustomizer because some rule was applied to it,
* but here it will again become a FluentRules.
*/
ruleSetter = (ruleSetter as FluentRuleCustomizer)
.ensure(property.name)
.displayName(property.description);
}

// these will set ruleSetter to a FluentRuleCustomizer
ruleSetter = ruleSetter.required());

ruleSetter = ruleSetter
.minLength(property.minLength)
.withMessage(`${property.description} must contain at least ${property.minLength} characters`));

.
.
.
}
```

**Request**
1. Create an interface `IFluentRules` (or whatever you want to name it) that includes all of the methods used here, or that might be used, including `ensure`, `displayName`, `minLength`, `required`, etc.......
2. Instead of using `ValidationRules`, use a new factory method to create an empty FluentRules that implements `IFluentRules`.
3. redefine all the methods in `IFluentRules` to return an `IFluentRules`

The resulting code would look like this:

```
let ruleSetter: IFluentRules= ValidationRules.create();

for (let property of formSchema.properties) {

if (this.requiresValidation(property, formSchema)) {

ruleSetter
.ensure(property.name)
.displayName(property.description);

// these will set ruleSetter to a FluentRuleCustomizer
ruleSetter = ruleSetter.required();

ruleSetter = ruleSetter
.minLength(property.minLength)
.withMessage(`${property.description} must contain at least ${property.minLength} characters`));
}
```

Contributor guide

Open the contributing guide

Research direction

Start by reading the existing FluentRules, FluentRuleCustomizer, and ValidationRules APIs named in the issue, then trace how their methods currently change return types. Done means a new IFluentRules-style interface and factory support the requested chained calls while allowing rules to be built from looped data without switching between the two existing classes.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
developer-experience
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.