Add alternative to fluent rule API that enables creating rules from data
- 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
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