Skip to content

Commit ea7f194

Browse files
authored
feature: add async function (#7)
1 parent c53cfba commit ea7f194

File tree

6 files changed

+105
-9
lines changed

6 files changed

+105
-9
lines changed

packages/scope-validator/lib/pattern.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export default class Pattern {
1818
return this.regex.test(compare);
1919
}
2020

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> = {};
2323

2424
let parameterNames = this.str.split(/(?:\${|})/g);
2525
parameterNames = parameterNames.filter((value, index) => index % 2);
@@ -38,11 +38,11 @@ export default class Pattern {
3838

3939
const regex = new RegExp(`^${regexStr}$`);
4040

41-
const parameterValues = compare.match(regex);
41+
const parameterValues: string[] | null = compare.match(regex);
4242
parameterValues?.shift();
4343

4444
parameterNames.forEach((name, index) => {
45-
result[name] = parameterValues?.[index];
45+
result[name] = parameterValues?.[index] ?? '';
4646
});
4747

4848
return result;
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export default interface ScopeValidatorContext<T> {
2-
parameters?: Record<string, unknown>;
2+
parameters?: Record<string, string>;
33

44
received?: T;
55
}

packages/scope-validator/lib/scope-validator-factory.ts

+35-3
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,51 @@ type ScopeValidatorFunction<T> = (
77
context: ScopeValidatorContext<T>
88
) => boolean;
99

10+
type ScopeValidatorAsyncFunction<T> = (
11+
name: string,
12+
context: ScopeValidatorContext<T>
13+
) => Promise<boolean>;
14+
1015
export default class ScopeValidatorFactory<T> {
11-
static create<T = Record<string, unknown>>(
16+
static create<T = Record<string, string>>(
1217
pattern: string,
1318
func: ScopeValidatorFunction<T>
1419
): ScopeValidator<T> {
1520
const CustomScopeValidator = class extends ScopeValidator<T> {
21+
private readonly func;
22+
1623
constructor() {
1724
super(pattern);
25+
26+
this.func = func;
1827
}
1928

20-
// eslint-disable-next-line class-methods-use-this
2129
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);
2355
}
2456
};
2557

packages/scope-validator/lib/scope-validator-manager.ts

+32
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,38 @@ export default class ScopeValidatorManager<T> {
1111
this.scopeValidators.push(...scopeValidators);
1212
}
1313

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+
1446
validate(scope: string, context?: T): boolean;
1547
validate(scopes: string[], context?: T): boolean[];
1648

packages/scope-validator/lib/scope-validator.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ export default abstract class ScopeValidator<T> {
1313
return this.pattern.test(str);
1414
}
1515

16-
abstract validate(name: string, context: ScopeValidatorContext<T>): boolean;
16+
abstract validate(
17+
name: string,
18+
context: ScopeValidatorContext<T>
19+
): boolean | Promise<boolean>;
1720
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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+
});

0 commit comments

Comments
 (0)