File tree 6 files changed +105
-9
lines changed
6 files changed +105
-9
lines changed Original file line number Diff line number Diff line change @@ -18,8 +18,8 @@ export default class Pattern {
18
18
return this . regex . test ( compare ) ;
19
19
}
20
20
21
- getParameters ( compare : string ) : Record < string , unknown > {
22
- const result : Record < string , unknown > = { } ;
21
+ getParameters ( compare : string ) : Record < string , string > {
22
+ const result : Record < string , string > = { } ;
23
23
24
24
let parameterNames = this . str . split ( / (?: \$ { | } ) / g) ;
25
25
parameterNames = parameterNames . filter ( ( value , index ) => index % 2 ) ;
@@ -38,11 +38,11 @@ export default class Pattern {
38
38
39
39
const regex = new RegExp ( `^${ regexStr } $` ) ;
40
40
41
- const parameterValues = compare . match ( regex ) ;
41
+ const parameterValues : string [ ] | null = compare . match ( regex ) ;
42
42
parameterValues ?. shift ( ) ;
43
43
44
44
parameterNames . forEach ( ( name , index ) => {
45
- result [ name ] = parameterValues ?. [ index ] ;
45
+ result [ name ] = parameterValues ?. [ index ] ?? '' ;
46
46
} ) ;
47
47
48
48
return result ;
Original file line number Diff line number Diff line change 1
1
export default interface ScopeValidatorContext < T > {
2
- parameters ?: Record < string , unknown > ;
2
+ parameters ?: Record < string , string > ;
3
3
4
4
received ?: T ;
5
5
}
Original file line number Diff line number Diff line change @@ -7,19 +7,51 @@ type ScopeValidatorFunction<T> = (
7
7
context : ScopeValidatorContext < T >
8
8
) => boolean ;
9
9
10
+ type ScopeValidatorAsyncFunction < T > = (
11
+ name : string ,
12
+ context : ScopeValidatorContext < T >
13
+ ) => Promise < boolean > ;
14
+
10
15
export default class ScopeValidatorFactory < T > {
11
- static create < T = Record < string , unknown > > (
16
+ static create < T = Record < string , string > > (
12
17
pattern : string ,
13
18
func : ScopeValidatorFunction < T >
14
19
) : ScopeValidator < T > {
15
20
const CustomScopeValidator = class extends ScopeValidator < T > {
21
+ private readonly func ;
22
+
16
23
constructor ( ) {
17
24
super ( pattern ) ;
25
+
26
+ this . func = func ;
18
27
}
19
28
20
- // eslint-disable-next-line class-methods-use-this
21
29
validate ( name : string , context : ScopeValidatorContext < T > ) : boolean {
22
- return func ( name , context ) ;
30
+ return this . func ( name , context ) ;
31
+ }
32
+ } ;
33
+
34
+ return new CustomScopeValidator ( ) ;
35
+ }
36
+
37
+ static createAsync < T = Record < string , string > > (
38
+ pattern : string ,
39
+ func : ScopeValidatorAsyncFunction < T >
40
+ ) : ScopeValidator < T > {
41
+ const CustomScopeValidator = class extends ScopeValidator < T > {
42
+ private readonly func ;
43
+
44
+ constructor ( ) {
45
+ super ( pattern ) ;
46
+
47
+ this . func = func ;
48
+ }
49
+
50
+ async validate (
51
+ name : string ,
52
+ context : ScopeValidatorContext < T >
53
+ ) : Promise < boolean > {
54
+ return this . func ( name , context ) ;
23
55
}
24
56
} ;
25
57
Original file line number Diff line number Diff line change @@ -11,6 +11,38 @@ export default class ScopeValidatorManager<T> {
11
11
this . scopeValidators . push ( ...scopeValidators ) ;
12
12
}
13
13
14
+ async validateAsync ( scope : string , context ?: T ) : Promise < boolean > ;
15
+ async validateAsync ( scopes : string [ ] , context ?: T ) : Promise < boolean [ ] > ;
16
+
17
+ async validateAsync (
18
+ scope : string | string [ ] ,
19
+ context ?: T
20
+ ) : Promise < boolean | boolean [ ] > {
21
+ if ( scope instanceof Array ) {
22
+ return Promise . all (
23
+ scope . map ( async ( one ) => this . validateAsync ( one , context ) )
24
+ ) ;
25
+ }
26
+
27
+ const matchValidators = this . scopeValidators . filter ( ( validator ) =>
28
+ validator . canValidate ( scope )
29
+ ) ;
30
+
31
+ let result = true ;
32
+ await Promise . all (
33
+ matchValidators . map ( async ( validator ) => {
34
+ const isCheck = await validator . validate ( scope , {
35
+ received : context ,
36
+ parameters : validator . pattern . getParameters ( scope ) ,
37
+ } ) ;
38
+
39
+ if ( result && ! isCheck ) result = false ;
40
+ } )
41
+ ) ;
42
+
43
+ return matchValidators . length >= 1 && result ;
44
+ }
45
+
14
46
validate ( scope : string , context ?: T ) : boolean ;
15
47
validate ( scopes : string [ ] , context ?: T ) : boolean [ ] ;
16
48
Original file line number Diff line number Diff line change @@ -13,5 +13,8 @@ export default abstract class ScopeValidator<T> {
13
13
return this . pattern . test ( str ) ;
14
14
}
15
15
16
- abstract validate ( name : string , context : ScopeValidatorContext < T > ) : boolean ;
16
+ abstract validate (
17
+ name : string ,
18
+ context : ScopeValidatorContext < T >
19
+ ) : boolean | Promise < boolean > ;
17
20
}
Original file line number Diff line number Diff line change
1
+ import { ScopeValidatorFactory , ScopeValidatorManager } from '../../lib' ;
2
+
3
+ const TestValidator1 = ScopeValidatorFactory . createAsync (
4
+ // eslint-disable-next-line no-template-curly-in-string
5
+ '${param1}-${param2}' ,
6
+ async ( name , { parameters } ) => {
7
+ const { param1, param2 } = parameters ?? { } ;
8
+
9
+ return new Promise ( ( resolve ) => {
10
+ if ( param1 === param2 ) resolve ( true ) ;
11
+ else resolve ( false ) ;
12
+ } ) ;
13
+ }
14
+ ) ;
15
+
16
+ describe ( 'success' , ( ) => {
17
+ it ( 'validate' , async ( ) => {
18
+ const scopeValidatorManager = new ScopeValidatorManager ( ) ;
19
+ scopeValidatorManager . use ( TestValidator1 ) ;
20
+
21
+ const result = await scopeValidatorManager . validateAsync ( [
22
+ 'test-test' ,
23
+ 'test-test2' ,
24
+ 'test-test-test' ,
25
+ ] ) ;
26
+
27
+ expect ( result ) . toEqual ( [ true , false , false ] ) ;
28
+ } ) ;
29
+ } ) ;
You can’t perform that action at this time.
0 commit comments