@vytches/ddd-validation 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/LLMGUIDE.md +207 -0
- package/README.md +1562 -0
- package/dist/adapters/base-adapter.d.ts +54 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/business-rules/business-rule-validator-extension.d.ts +29 -0
- package/dist/business-rules/business-rule-validator.d.ts +51 -0
- package/dist/business-rules/index.d.ts +2 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +803 -0
- package/dist/rules-registry.d.ts +69 -0
- package/dist/specifications/async-composite-specification.d.ts +72 -0
- package/dist/specifications/composite-specification.d.ts +25 -0
- package/dist/specifications/index.d.ts +5 -0
- package/dist/specifications/memoized-specification.d.ts +84 -0
- package/dist/specifications/specification-operators.d.ts +70 -0
- package/dist/specifications/specification-validator.d.ts +26 -0
- package/dist/validation-error.d.ts +13 -0
- package/dist/validation-facade.d.ts +51 -0
- package/package.json +69 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { IValidationErrors, IValidator } from '../../../contracts/src/index.ts';
|
|
2
|
+
import { Result } from '../../../utils/src/index.ts';
|
|
3
|
+
import { ValidationError, ValidationErrors } from '../validation-error';
|
|
4
|
+
export declare abstract class BaseValidationAdapter<T, TSchema = unknown> implements IValidator<T> {
|
|
5
|
+
protected readonly schema: TSchema;
|
|
6
|
+
constructor(schema: TSchema);
|
|
7
|
+
/**
|
|
8
|
+
* Główna metoda walidacji - musi być zaimplementowana przez konkretne adaptery
|
|
9
|
+
*/
|
|
10
|
+
abstract validate(value: T): Result<T, IValidationErrors>;
|
|
11
|
+
/**
|
|
12
|
+
* Helper method do tworzenia ValidationError z kontekstem
|
|
13
|
+
*/
|
|
14
|
+
protected createValidationError(property: string, message: string, context?: Record<string, unknown>): ValidationError;
|
|
15
|
+
/**
|
|
16
|
+
* Helper method do tworzenia ValidationErrors z tablicy błędów
|
|
17
|
+
*/
|
|
18
|
+
protected createValidationErrors(errors: ValidationError[]): ValidationErrors;
|
|
19
|
+
/**
|
|
20
|
+
* Helper method do konwersji ścieżki na string
|
|
21
|
+
*/
|
|
22
|
+
protected pathToString(path: (string | number)[]): string;
|
|
23
|
+
/**
|
|
24
|
+
* Helper method do tworzenia Result.fail z błędami
|
|
25
|
+
*/
|
|
26
|
+
protected failWithErrors(errors: ValidationError[]): Result<T, IValidationErrors>;
|
|
27
|
+
/**
|
|
28
|
+
* Helper method do tworzenia Result.ok
|
|
29
|
+
*/
|
|
30
|
+
protected success(value: T): Result<T, IValidationErrors>;
|
|
31
|
+
}
|
|
32
|
+
export interface ErrorMapper<TExternalError> {
|
|
33
|
+
(error: TExternalError): ValidationError;
|
|
34
|
+
}
|
|
35
|
+
export declare class AdapterUtils {
|
|
36
|
+
/**
|
|
37
|
+
* Tworzy prosty adapter z funkcji walidacyjnej
|
|
38
|
+
*/
|
|
39
|
+
static create<T>(validateFn: (value: T) => {
|
|
40
|
+
success: boolean;
|
|
41
|
+
errors?: string[] | undefined;
|
|
42
|
+
}, errorProperty?: string): IValidator<T>;
|
|
43
|
+
/**
|
|
44
|
+
* Łączy wiele adapterów w jeden
|
|
45
|
+
*/
|
|
46
|
+
static combine<T>(...adapters: IValidator<T>[]): IValidator<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Tworzy adapter z custom error mapping
|
|
49
|
+
*/
|
|
50
|
+
static withErrorMapping<T, TError>(validateFn: (value: T) => {
|
|
51
|
+
success: boolean;
|
|
52
|
+
errors?: TError[] | undefined;
|
|
53
|
+
}, errorMapper: ErrorMapper<TError>): IValidator<T>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ISpecification } from '../../../contracts/src/index.ts';
|
|
2
|
+
import { Result } from '../../../utils/src/index.ts';
|
|
3
|
+
import { ValidationErrors } from '../validation-error';
|
|
4
|
+
import { BusinessRuleValidator } from './business-rule-validator';
|
|
5
|
+
export declare class BusinessRuleValidatorExtension<T> {
|
|
6
|
+
private validator;
|
|
7
|
+
constructor(validator: BusinessRuleValidator<T>);
|
|
8
|
+
/**
|
|
9
|
+
* Converts the validator to a specification
|
|
10
|
+
*/
|
|
11
|
+
toSpecification(_errorMessage?: string): ISpecification<T>;
|
|
12
|
+
/**
|
|
13
|
+
* Validates an object using additional specifications
|
|
14
|
+
*/
|
|
15
|
+
validateWithSpecifications(value: T, ...specs: ISpecification<T>[]): Result<T, ValidationErrors>;
|
|
16
|
+
}
|
|
17
|
+
declare module './business-rule-validator' {
|
|
18
|
+
interface BusinessRuleValidator<T> {
|
|
19
|
+
/**
|
|
20
|
+
* Converts this validator to a specification
|
|
21
|
+
*/
|
|
22
|
+
toSpecification(errorMessage?: string): ISpecification<T>;
|
|
23
|
+
/**
|
|
24
|
+
* Validates value with additional specifications
|
|
25
|
+
*/
|
|
26
|
+
validateWithSpecifications(value: T, ...specs: ISpecification<T>[]): Result<T, ValidationErrors>;
|
|
27
|
+
apply(rule: (validator: BusinessRuleValidator<T>) => BusinessRuleValidator<T>): BusinessRuleValidator<T>;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ISpecification, IValidator } from '../../../contracts/src/index.ts';
|
|
2
|
+
import { Result } from '../../../utils/src/index.ts';
|
|
3
|
+
import { ValidationErrors } from '../validation-error';
|
|
4
|
+
export declare class BusinessRuleValidator<T> implements IValidator<T> {
|
|
5
|
+
private rules;
|
|
6
|
+
private stopOnFirstFailure;
|
|
7
|
+
private lastCondition;
|
|
8
|
+
addRule(property: string, validationFn: (value: T) => boolean, message: string, context?: Record<string, any>): BusinessRuleValidator<T>;
|
|
9
|
+
addSpecification(property: string, specification: ISpecification<T>, message: string, context?: Record<string, any>): BusinessRuleValidator<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Dodaje globalną specyfikację, która dotyczy całego obiektu
|
|
12
|
+
*/
|
|
13
|
+
mustSatisfy(specification: ISpecification<T>, message: string, context?: Record<string, any>): BusinessRuleValidator<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Dodaje walidację dla konkretnej właściwości z użyciem specyfikacji
|
|
16
|
+
*/
|
|
17
|
+
propertyMustSatisfy<P>(property: keyof T & string, specification: ISpecification<P>, message: string, getValue: (obj: T) => P, context?: Record<string, any>): BusinessRuleValidator<T>;
|
|
18
|
+
/**
|
|
19
|
+
* Dodaje walidację dla zagnieżdżonego obiektu
|
|
20
|
+
*/
|
|
21
|
+
addNested<P>(property: string, validator: IValidator<P>, getValue: (obj: T) => P | undefined | null): BusinessRuleValidator<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Dodaje walidację warunkową
|
|
24
|
+
*/
|
|
25
|
+
when(condition: (value: T) => boolean, thenValidator: (validator: BusinessRuleValidator<T>) => void): BusinessRuleValidator<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Dodaje walidację warunkową
|
|
28
|
+
*/
|
|
29
|
+
otherwise(elseValidator: (validator: BusinessRuleValidator<T>) => void): BusinessRuleValidator<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Dodaje walidację warunkową opartą na specyfikacji
|
|
32
|
+
*/
|
|
33
|
+
whenSatisfies(specification: ISpecification<T>, thenValidator: (validator: BusinessRuleValidator<T>) => void): BusinessRuleValidator<T>;
|
|
34
|
+
/**
|
|
35
|
+
* Konfiguruje walidator do zatrzymania po pierwszym błędzie
|
|
36
|
+
*/
|
|
37
|
+
setStopOnFirstFailure(): BusinessRuleValidator<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Przeprowadza walidację
|
|
40
|
+
*/
|
|
41
|
+
validate(value: T): Result<T, ValidationErrors>;
|
|
42
|
+
/**
|
|
43
|
+
* Łączy ten walidator z innym
|
|
44
|
+
*/
|
|
45
|
+
and(other: IValidator<T>): BusinessRuleValidator<T>;
|
|
46
|
+
/**
|
|
47
|
+
* Tworzy nowy walidator ze specyfikacji
|
|
48
|
+
*/
|
|
49
|
+
static fromSpecification<T>(specification: ISpecification<T>, message: string, context?: Record<string, any>): BusinessRuleValidator<T>;
|
|
50
|
+
static create<T>(): BusinessRuleValidator<T>;
|
|
51
|
+
}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("@vytches/ddd-utils");class u{and(t){return new R(this,t)}or(t){return new v(this,t)}not(){return new B(this)}static create(t){return new N(t)}}let N=class extends u{constructor(t){super(),this.predicate=t}isSatisfiedBy(t){return this.predicate(t)}};class R extends u{constructor(t,e){super(),this.left=t,this.right=e}isSatisfiedBy(t){return this.left.isSatisfiedBy(t)&&this.right.isSatisfiedBy(t)}}class v extends u{constructor(t,e){super(),this.left=t,this.right=e}isSatisfiedBy(t){return this.left.isSatisfiedBy(t)||this.right.isSatisfiedBy(t)}}class B extends u{constructor(t){super(),this.spec=t}isSatisfiedBy(t){return!this.spec.isSatisfiedBy(t)}}class y{and(t){return new x(this,t)}or(t){return new F(this,t)}not(){return new E(this)}static create(t,e,i){return new b(t,e,i)}async explainFailureAsync(t,e){return null}}class b extends y{constructor(t,e,i){super(),this.predicate=t,this.name=e,this.description=i}async isSatisfiedByAsync(t,e){return this.predicate(t,e)}}class x extends y{constructor(t,e){super(),this.left=t,this.right=e,this.name=`(${this.left.name||"spec"} AND ${this.right.name||"spec"})`,this.description="Both specifications must be satisfied"}async isSatisfiedByAsync(t,e){const[i,s]=await Promise.all([this.left.isSatisfiedByAsync(t,e),this.right.isSatisfiedByAsync(t,e)]);return i&&s}async explainFailureAsync(t,e){const[i,s]=await Promise.all([this.left.isSatisfiedByAsync(t,e),this.right.isSatisfiedByAsync(t,e)]),n=[];if(!i&&this.left.explainFailureAsync){const a=await this.left.explainFailureAsync(t,e);a&&n.push(a)}if(!s&&this.right.explainFailureAsync){const a=await this.right.explainFailureAsync(t,e);a&&n.push(a)}return n.length>0?n.join(" AND "):null}}class F extends y{constructor(t,e){super(),this.left=t,this.right=e,this.name=`(${this.left.name||"spec"} OR ${this.right.name||"spec"})`,this.description="At least one specification must be satisfied"}async isSatisfiedByAsync(t,e){const[i,s]=await Promise.all([this.left.isSatisfiedByAsync(t,e),this.right.isSatisfiedByAsync(t,e)]);return i||s}async explainFailureAsync(t,e){const[i,s]=await Promise.all([this.left.isSatisfiedByAsync(t,e),this.right.isSatisfiedByAsync(t,e)]);if(!i&&!s){const n=[];if(this.left.explainFailureAsync){const a=await this.left.explainFailureAsync(t,e);a&&n.push(a)}if(this.right.explainFailureAsync){const a=await this.right.explainFailureAsync(t,e);a&&n.push(a)}return n.length>0?`(${n.join(" OR ")})`:null}return null}}class E extends y{constructor(t){super(),this.spec=t,this.name=`NOT(${this.spec.name||"spec"})`,this.description="The specification must NOT be satisfied"}async isSatisfiedByAsync(t,e){return!await this.spec.isSatisfiedByAsync(t,e)}async explainFailureAsync(t,e){return await this.spec.isSatisfiedByAsync(t,e)?`Expected specification to fail: ${this.spec.name||"specification"}`:null}}class O extends u{constructor(t){super(),this.inner=t,this.cache=new WeakMap}isSatisfiedBy(t){if(t===null||typeof t!="object"&&typeof t!="function")return this.inner.isSatisfiedBy(t);const e=this.cache.get(t);if(e!==void 0)return e;const i=this.inner.isSatisfiedBy(t);return this.cache.set(t,i),i}invalidate(t){this.cache.delete(t)}explainFailure(t){const e=this.inner;return e.explainFailure?e.explainFailure(t)??null:null}}class m extends u{isSatisfiedBy(t){return!0}}class g extends u{isSatisfiedBy(t){return!1}}class P extends u{constructor(t){super(),this.predicate=t}isSatisfiedBy(t){return this.predicate(t)}}class C extends u{constructor(t,e){super(),this.propertyName=t,this.expectedValue=e}isSatisfiedBy(t){return t[this.propertyName]===this.expectedValue}}class V extends u{constructor(t,e){super(),this.propertyName=t,this.possibleValues=e}isSatisfiedBy(t){return this.possibleValues.includes(t[this.propertyName])}}class $ extends u{constructor(t,e,i){super(),this.propertyName=t,this.min=e,this.max=i}isSatisfiedBy(t){const e=t[this.propertyName];return e>=this.min&&e<=this.max}}const k={alwaysTrue(){return new m},alwaysFalse(){return new g},create(r){return new P(r)},propertyEquals(r,t){return new C(r,t)},propertyIn(r,t){return new V(r,t)},propertyBetween(r,t,e){return new $(r,t,e)},and(...r){if(r.length===0)return new m;let t=r[0];for(let e=1;e<r.length;e++)t=new R(t,r[e]);return t},or(...r){if(r.length===0)return new g;let t=r[0];for(let e=1;e<r.length;e++)t=new v(t,r[e]);return t},not(r){return new B(r)}};class h{constructor(t,e,i){this.property=t,this.message=e,this.context=i}toString(){return`${this.property}: ${this.message}`}}class d extends Error{constructor(t){super(`Validation failed with ${t.length} error(s): ${t.map(e=>e.toString()).join("; ")}`),this.name="ValidationErrors",this.errors=t}get length(){return this.errors.length}}class p{constructor(){this.validationRules=[]}addRule(t,e,i,s){const n={specification:t,message:e,property:i||""};return s!==void 0&&(n.context=s),this.validationRules.push(n),this}addPropertyRule(t,e,i,s,n){const a={isSatisfiedBy:c=>e.isSatisfiedBy(s(c)),and:()=>{throw new Error("Operation not supported")},or:()=>{throw new Error("Operation not supported")},not:()=>{throw new Error("Operation not supported")}};return this.addRule(a,i,t,n)}validate(t){const e=[];for(const i of this.validationRules)i.specification.isSatisfiedBy(t)||e.push(new h(i.property||"",i.message,i.context));return e.length>0?o.Result.fail(new d(e)):o.Result.ok(t)}static fromSpecification(t,e,i,s){return new p().addRule(t,e,i,s)}static create(){return new p}}class f{constructor(){this.rules=[],this.stopOnFirstFailure=!1,this.lastCondition=null}addRule(t,e,i,s){return this.rules.push({property:t,validate:n=>e(n)?o.Result.ok(!0):o.Result.fail(new h(t,i,s))}),this}addSpecification(t,e,i,s){return this.addRule(t,n=>e.isSatisfiedBy(n),i,s)}mustSatisfy(t,e,i){return this.addSpecification("",t,e,i)}propertyMustSatisfy(t,e,i,s,n){return this.addRule(t,a=>e.isSatisfiedBy(s(a)),i,n)}addNested(t,e,i){return this.rules.push({property:t,validate:s=>{const n=i(s);if(n==null)return o.Result.fail(new h(t,"Cannot validate undefined or null nested object",{path:t}));const a=e.validate(n);if(a.isFailure){const c=a.error.errors.map(l=>{const w={...l.context||{},path:t+(l.property?`.${l.property}`:""),originalPath:l.property||"",parentPath:t};return new h(`${t}${l.property?`.${l.property}`:""}`,l.message,w)});return o.Result.fail(new h(t,"Nested validation failed",{errors:c,path:t,errorCount:c.length}))}return o.Result.ok(!0)}}),this}when(t,e){if(typeof t!="function")throw new Error("Condition must be a function");this.lastCondition=t;const i=new f;e(i);for(const s of i.rules)this.rules.push({...s,condition:t});return this}otherwise(t){if(this.lastCondition===null||this.lastCondition===void 0)throw new Error("Cannot call otherwise() without a preceding when() - lastCondition is null/undefined");if(typeof this.lastCondition!="function")throw new Error(`Cannot call otherwise() - lastCondition is not a function but a ${typeof this.lastCondition}`);const e=this.lastCondition,i=n=>!e(n),s=new f;t(s);for(const n of s.rules)this.rules.push({...n,condition:i});return this.lastCondition=null,this}whenSatisfies(t,e){return this.when(i=>t.isSatisfiedBy(i),e)}setStopOnFirstFailure(){return this.stopOnFirstFailure=!0,this}validate(t){const e=[];for(const i of this.rules){if(i.condition&&!i.condition(t))continue;const s=i.validate(t);if(s.isFailure&&(e.push(s.error),this.stopOnFirstFailure))break}return e.length>0?o.Result.fail(new d(e)):o.Result.ok(t)}and(t){const e=new f;return e.rules=[...this.rules],e.addRule("",i=>t.validate(i).isSuccess,"Failed combined validation"),e}static fromSpecification(t,e,i){return new f().mustSatisfy(t,e,i)}static create(){return new f}}const M={create(){return f.create()},fromSpecification(r,t,e){return p.fromSpecification(r,t,e)},combine(...r){return{validate:t=>{const e=[];for(const i of r){const s=i.validate(t);s.isFailure&&e.push(s.error)}if(e.length>0){const i=e.flatMap(s=>s.errors);return o.Result.fail(new d(i))}return o.Result.ok(t)}}},validateWithSpecification(r,t,e){return this.fromSpecification(t,e).validate(r)},validateWithRules(r,t){const e=p.create();for(const i of t)e.addRule(i.specification,i.message,i.property);return e.validate(r)},specificationToValidator(r,t,e){return this.fromSpecification(r,t,e)},validatorToSpecification(r){return u.create(t=>r.validate(t).isSuccess)},forNestedPath(r,t){if(r.length===0)return t;let e=t;for(let i=r.length-1;i>=0;i--){const s=r[i],n=f.create();n.addNested(s,e,a=>a?a[s]:void 0),e=n}return e},validatePath(r,t,e){const s=((a,c)=>{let l=a;for(const w of c){if(l==null)return;if(typeof l=="object"&&l!==null)l=l[w];else return}return l})(r,t);if(s===void 0)return o.Result.fail(new d([new h(t.join("."),"Path does not exist",{path:t})]));const n=e.validate(s);if(n.isFailure){const a=n.error.errors.map(c=>{const l=[...t];return c.property&&l.push(c.property),new h(l.join("."),c.message,{...c.context,fullPath:l})});return o.Result.fail(new d(a))}return o.Result.ok(r)},useExternal(r){return r}};class T{constructor(){this.name="core",this.required=(t,e="Field is required")=>i=>i.addRule(t,s=>s[t]!==void 0&&s[t]!==null,e),this.minLength=(t,e,i)=>s=>s.addRule(t,n=>String(n[t]).length>=e,i||`Minimum length is ${e}`),this.maxLength=(t,e,i)=>s=>s.addRule(t,n=>String(n[t]).length<=e,i||`Maximum length is ${e}`),this.pattern=(t,e,i="Invalid format")=>s=>s.addRule(t,n=>e.test(String(n[t])),i),this.range=(t,e,i,s)=>n=>n.addRule(t,a=>{const c=Number(a[t]);return!isNaN(c)&&c>=e&&c<=i},s||`Value must be between ${e} and ${i}`),this.email=(t,e="Invalid email address")=>i=>i.addRule(t,s=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(s[t])),e),this.satisfies=(t,e)=>i=>i.mustSatisfy(t,e),this.propertySatisfies=(t,e,i,s)=>n=>n.propertyMustSatisfy(t,e,i,s),this.whenSatisfies=(t,e)=>i=>i.whenSatisfies(t,e),this.otherwise=t=>e=>e.otherwise(t),this.when=(t,e)=>i=>i.when(t,e)}}const S=class S{static register(t){if(this.providers.has(t.name))throw new Error(`Rule provider with name "${t.name}" is already registered`);this.providers.set(t.name,t)}static getProvider(t){const e=this.providers.get(t);if(!e)throw new Error(`Rule provider "${t}" not found`);return e}static get Rules(){return this.core}static forDomain(t){return this.getProvider(t)}};S.providers=new Map,S.core=new T;let A=S;class j{constructor(t){this.schema=t}createValidationError(t,e,i){return new h(t,e,i)}createValidationErrors(t){return new d(t)}pathToString(t){return t.join(".")}failWithErrors(t){return o.Result.fail(this.createValidationErrors(t))}success(t){return o.Result.ok(t)}}class q{static create(t,e=""){return{validate:i=>{const s=t(i);if(!s.success&&s.errors){const n=s.errors.map(a=>new h(e,a));return o.Result.fail(new d(n))}return o.Result.ok(i)}}}static combine(...t){return{validate:e=>{const i=[];for(const s of t){const n=s.validate(e);n.isFailure&&i.push(...n.error.errors)}return i.length>0?o.Result.fail(new d(i)):o.Result.ok(e)}}}static withErrorMapping(t,e){return{validate:i=>{const s=t(i);if(!s.success&&s.errors){const n=s.errors.map(e);return o.Result.fail(new d(n))}return o.Result.ok(i)}}}}exports.AdapterUtils=q;exports.AlwaysFalseSpecification=g;exports.AlwaysTrueSpecification=m;exports.AndAsyncSpecification=x;exports.AndSpecification=R;exports.AsyncCompositeSpecification=y;exports.BaseValidationAdapter=j;exports.BusinessRuleValidator=f;exports.CompositeSpecification=u;exports.MemoizedSpecification=O;exports.NotAsyncSpecification=E;exports.NotSpecification=B;exports.OrAsyncSpecification=F;exports.OrSpecification=v;exports.PredicateSpecification=P;exports.PropertyBetweenSpecification=$;exports.PropertyEqualsSpecification=C;exports.PropertyInSpecification=V;exports.RulesRegistry=A;exports.Specification=k;exports.SpecificationValidator=p;exports.ValidationError=h;exports.ValidationErrors=d;exports.ValidationFacade=M;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Specification, CompositeSpecification, AsyncCompositeSpecification, MemoizedSpecification, NotSpecification, AndSpecification, OrSpecification, AndAsyncSpecification, OrAsyncSpecification, NotAsyncSpecification, AlwaysFalseSpecification, AlwaysTrueSpecification, SpecificationValidator, PredicateSpecification, PropertyBetweenSpecification, PropertyInSpecification, PropertyEqualsSpecification, } from './specifications';
|
|
2
|
+
export { BusinessRuleValidator } from './business-rules';
|
|
3
|
+
export { ValidationError, ValidationErrors } from './validation-error';
|
|
4
|
+
export { Validation as ValidationFacade } from './validation-facade';
|
|
5
|
+
export { RulesRegistry } from './rules-registry';
|
|
6
|
+
export { BaseValidationAdapter, AdapterUtils } from './adapters';
|