Skip to content

Commit

Permalink
started to make TypeScript types from the application domain explicit…
Browse files Browse the repository at this point in the history
…, might be useful in the future, improves readability already now
  • Loading branch information
JohannesMeierSE committed Dec 8, 2024
1 parent 0e8f26e commit 5389732
Showing 1 changed file with 22 additions and 22 deletions.
44 changes: 22 additions & 22 deletions packages/typir/src/services/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ export function isValidationProblem(problem: unknown): problem is ValidationProb

export type ValidationRule<T = unknown> = (domainElement: T, typir: TypirServices) => ValidationProblem[];

export interface ValidationRuleWithBeforeAfter {
beforeValidation(domainRoot: unknown, typir: TypirServices): ValidationProblem[]
validation: ValidationRule
afterValidation(domainRoot: unknown, typir: TypirServices): ValidationProblem[]
export interface ValidationRuleWithBeforeAfter<ElementType = unknown, RootType = ElementType> {
beforeValidation(domainRoot: RootType, typir: TypirServices): ValidationProblem[];
validation: ValidationRule<ElementType>;
afterValidation(domainRoot: RootType, typir: TypirServices): ValidationProblem[];
}

/** Annotate types after the validation with additional information in order to ease the creation of usefull messages. */
Expand Down Expand Up @@ -142,41 +142,41 @@ export class DefaultValidationConstraints implements ValidationConstraints {
}


export interface ValidationCollector {
validateBefore(domainRoot: unknown): ValidationProblem[];
validate(domainElement: unknown): ValidationProblem[];
validateAfter(domainRoot: unknown): ValidationProblem[];
export interface ValidationCollector<ElementType = unknown, RootType = ElementType> {
validateBefore(domainRoot: RootType): ValidationProblem[];
validate(domainElement: ElementType): ValidationProblem[];
validateAfter(domainRoot: RootType): ValidationProblem[];

/**
* Registers a validation rule.
* @param rule a new validation rule
* @param boundToType an optional type, if the new validation rule is dedicated for exactly this type.
* If the given type is removed from the type system, this rule will be automatically removed as well.
*/
addValidationRule(rule: ValidationRule, boundToType?: Type): void;
removeValidationRule(rule: ValidationRule, boundToType?: Type): void;
addValidationRule(rule: ValidationRule<ElementType>, boundToType?: Type): void;
removeValidationRule(rule: ValidationRule<ElementType>, boundToType?: Type): void;

/**
* Registers a validation rule which will be called once before and once after the whole validation.
* @param rule a new validation rule
* @param boundToType an optional type, if the new validation rule is dedicated for exactly this type.
* If the given type is removed from the type system, this rule will be automatically removed as well.
*/
addValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter, boundToType?: Type): void;
removeValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter, boundToType?: Type): void;
addValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter<ElementType, RootType>, boundToType?: Type): void;
removeValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter<ElementType, RootType>, boundToType?: Type): void;
}

export class DefaultValidationCollector implements ValidationCollector, TypeGraphListener {
export class DefaultValidationCollector<ElementType = unknown, RootType = ElementType> implements ValidationCollector<ElementType, RootType>, TypeGraphListener {
protected readonly services: TypirServices;
protected readonly validationRules: Map<string, ValidationRule[]> = new Map(); // type identifier (otherwise '') -> validation rules
protected readonly validationRulesBeforeAfter: Map<string, ValidationRuleWithBeforeAfter[]> = new Map(); // type identifier (otherwise '') -> validation rules
protected readonly validationRules: Map<string, Array<ValidationRule<ElementType>>> = new Map(); // type identifier (otherwise '') -> validation rules
protected readonly validationRulesBeforeAfter: Map<string, Array<ValidationRuleWithBeforeAfter<ElementType, RootType>>> = new Map(); // type identifier (otherwise '') -> validation rules

constructor(services: TypirServices) {
this.services = services;
this.services.graph.addListener(this);
}

validateBefore(domainRoot: unknown): ValidationProblem[] {
validateBefore(domainRoot: RootType): ValidationProblem[] {
const problems: ValidationProblem[] = [];
for (const rules of this.validationRulesBeforeAfter.values()) {
for (const rule of rules) {
Expand All @@ -186,7 +186,7 @@ export class DefaultValidationCollector implements ValidationCollector, TypeGrap
return problems;
}

validate(domainElement: unknown): ValidationProblem[] {
validate(domainElement: ElementType): ValidationProblem[] {
const problems: ValidationProblem[] = [];
for (const rules of this.validationRules.values()) {
for (const rule of rules) {
Expand All @@ -201,7 +201,7 @@ export class DefaultValidationCollector implements ValidationCollector, TypeGrap
return problems;
}

validateAfter(domainRoot: unknown): ValidationProblem[] {
validateAfter(domainRoot: RootType): ValidationProblem[] {
const problems: ValidationProblem[] = [];
for (const rules of this.validationRulesBeforeAfter.values()) {
for (const rule of rules) {
Expand All @@ -211,7 +211,7 @@ export class DefaultValidationCollector implements ValidationCollector, TypeGrap
return problems;
}

addValidationRule(rule: ValidationRule, boundToType?: Type): void {
addValidationRule(rule: ValidationRule<ElementType>, boundToType?: Type): void {
const key = this.getBoundToTypeKey(boundToType);
let rules = this.validationRules.get(key);
if (!rules) {
Expand All @@ -221,7 +221,7 @@ export class DefaultValidationCollector implements ValidationCollector, TypeGrap
rules.push(rule);
}

removeValidationRule(rule: ValidationRule, boundToType?: Type): void {
removeValidationRule(rule: ValidationRule<ElementType>, boundToType?: Type): void {
const key = this.getBoundToTypeKey(boundToType);
const rules = this.validationRules.get(key);
if (rules) {
Expand All @@ -232,7 +232,7 @@ export class DefaultValidationCollector implements ValidationCollector, TypeGrap
}
}

addValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter, boundToType?: Type): void {
addValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter<ElementType, RootType>, boundToType?: Type): void {
const key = this.getBoundToTypeKey(boundToType);
let rules = this.validationRulesBeforeAfter.get(key);
if (!rules) {
Expand All @@ -242,7 +242,7 @@ export class DefaultValidationCollector implements ValidationCollector, TypeGrap
rules.push(rule);
}

removeValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter, boundToType?: Type): void {
removeValidationRuleWithBeforeAndAfter(rule: ValidationRuleWithBeforeAfter<ElementType, RootType>, boundToType?: Type): void {
const key = this.getBoundToTypeKey(boundToType);
const rules = this.validationRulesBeforeAfter.get(key);
if (rules) {
Expand Down

0 comments on commit 5389732

Please sign in to comment.