mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-11-21 03:15:49 +08:00
refactor validator
This commit is contained in:
parent
15f0d704aa
commit
29c5054b6e
@ -93,12 +93,12 @@ const PropsSchema = Type.Object({
|
||||
customerIncrement: Type.Object({
|
||||
bg: Type.Optional(Type.String()),
|
||||
children: Type.Optional(Type.String()),
|
||||
_active: Type.Object(Type.Object({ bg: Type.String() })),
|
||||
_active: Type.Object({ bg: Type.String() }),
|
||||
}),
|
||||
customerDecrement: Type.Object({
|
||||
bg: Type.Optional(Type.String()),
|
||||
children: Type.Optional(Type.String()),
|
||||
_active: Type.Object(Type.Object({ bg: Type.String() })),
|
||||
_active: Type.Object({ bg: Type.String() }),
|
||||
}),
|
||||
});
|
||||
|
||||
|
@ -25,7 +25,7 @@ class EditorStore {
|
||||
};
|
||||
|
||||
appStorage = new AppStorage();
|
||||
schemaValidator = new SchemaValidator();
|
||||
schemaValidator = new SchemaValidator(registry);
|
||||
|
||||
get app() {
|
||||
return this.appStorage.app;
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { ApplicationComponent } from '@sunmao-ui/core';
|
||||
import { Registry } from '@sunmao-ui/runtime';
|
||||
import Ajv from 'ajv';
|
||||
import { registry } from '../setup';
|
||||
import {
|
||||
ISchemaValidator,
|
||||
ComponentValidatorRule,
|
||||
AllComponentsValidatorRule,
|
||||
TraitValidatorRule,
|
||||
ValidatorRule,
|
||||
ValidateErrorResult
|
||||
ValidateErrorResult,
|
||||
ValidatorMap,
|
||||
} from './interfaces';
|
||||
import { rules } from './rules';
|
||||
|
||||
@ -16,13 +17,12 @@ export class SchemaValidator implements ISchemaValidator {
|
||||
private traitRules: TraitValidatorRule[] = [];
|
||||
private componentRules: ComponentValidatorRule[] = [];
|
||||
private allComponentsRules: AllComponentsValidatorRule[] = [];
|
||||
private ajv: Ajv;
|
||||
private ajv!: Ajv;
|
||||
private validatorMap!: ValidatorMap;
|
||||
|
||||
constructor() {
|
||||
this.addRules(rules)
|
||||
this.ajv = new Ajv({})
|
||||
.addKeyword('kind')
|
||||
.addKeyword('modifier');
|
||||
constructor(registry: Registry) {
|
||||
this.initAjv(registry);
|
||||
this.addRules(rules);
|
||||
}
|
||||
|
||||
addRules(rules: ValidatorRule[]) {
|
||||
@ -43,8 +43,9 @@ export class SchemaValidator implements ISchemaValidator {
|
||||
|
||||
validate(components: ApplicationComponent[]) {
|
||||
this.result = [];
|
||||
const t1 = performance.now();
|
||||
this.allComponentsRules.forEach(rule => {
|
||||
const r = rule.validate({ components: components, ajv: this.ajv });
|
||||
const r = rule.validate({ components: components, validators: this.validatorMap });
|
||||
if (r.length > 0) {
|
||||
this.result = this.result.concat(r);
|
||||
}
|
||||
@ -54,8 +55,7 @@ export class SchemaValidator implements ISchemaValidator {
|
||||
const r = rule.validate({
|
||||
component,
|
||||
components: components,
|
||||
registry,
|
||||
ajv: this.ajv,
|
||||
validators: this.validatorMap,
|
||||
});
|
||||
if (r.length > 0) {
|
||||
this.result = this.result.concat(r);
|
||||
@ -69,8 +69,7 @@ export class SchemaValidator implements ISchemaValidator {
|
||||
trait,
|
||||
component,
|
||||
components: components,
|
||||
registry,
|
||||
ajv: this.ajv,
|
||||
validators: this.validatorMap,
|
||||
});
|
||||
if (r.length > 0) {
|
||||
this.result = this.result.concat(r);
|
||||
@ -78,6 +77,8 @@ export class SchemaValidator implements ISchemaValidator {
|
||||
});
|
||||
});
|
||||
});
|
||||
const t2 = performance.now();
|
||||
console.log('validate time:', t2 - t1, 'ms');
|
||||
return this.result;
|
||||
}
|
||||
|
||||
@ -87,4 +88,23 @@ export class SchemaValidator implements ISchemaValidator {
|
||||
// });
|
||||
// return components;
|
||||
}
|
||||
|
||||
private initAjv(registry: Registry) {
|
||||
this.ajv = new Ajv({}).addKeyword('kind').addKeyword('modifier');
|
||||
|
||||
this.validatorMap = {
|
||||
components: {},
|
||||
traits: {},
|
||||
};
|
||||
registry.getAllComponents().forEach(c => {
|
||||
this.validatorMap.components[`${c.version}/${c.metadata.name}`] = this.ajv.compile(
|
||||
c.spec.properties
|
||||
);
|
||||
});
|
||||
registry.getAllTraits().forEach(t => {
|
||||
this.validatorMap.traits[`${t.version}/${t.metadata.name}`] = this.ajv.compile(
|
||||
t.spec.properties
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,27 @@
|
||||
import { ApplicationComponent, ComponentTrait } from '@sunmao-ui/core';
|
||||
import { Registry } from '@sunmao-ui/runtime';
|
||||
import Ajv from 'ajv';
|
||||
import { ValidateFunction } from 'ajv';
|
||||
|
||||
export interface ComponentValidateContext {
|
||||
component: ApplicationComponent;
|
||||
components: ApplicationComponent[];
|
||||
registry: Registry;
|
||||
ajv: Ajv;
|
||||
export interface ValidatorMap {
|
||||
components: Record<string, ValidateFunction>;
|
||||
traits: Record<string, ValidateFunction>;
|
||||
}
|
||||
|
||||
export interface TraitValidateContext {
|
||||
interface BaseValidateContext {
|
||||
validators: ValidatorMap;
|
||||
}
|
||||
|
||||
export interface ComponentValidateContext extends BaseValidateContext {
|
||||
component: ApplicationComponent;
|
||||
components: ApplicationComponent[];
|
||||
}
|
||||
|
||||
export interface TraitValidateContext extends BaseValidateContext {
|
||||
trait: ComponentTrait;
|
||||
component: ApplicationComponent;
|
||||
components: ApplicationComponent[];
|
||||
registry: Registry;
|
||||
ajv: Ajv;
|
||||
}
|
||||
export interface AllComponentsValidateContext {
|
||||
export interface AllComponentsValidateContext extends BaseValidateContext {
|
||||
components: ApplicationComponent[];
|
||||
ajv: Ajv;
|
||||
}
|
||||
|
||||
export type ValidateContext =
|
||||
|
@ -66,12 +66,11 @@ export class ComponentPropertyValidatorRule implements ComponentValidatorRule {
|
||||
|
||||
validate({
|
||||
component,
|
||||
registry,
|
||||
ajv,
|
||||
validators,
|
||||
}: ComponentValidateContext): ValidateErrorResult[] {
|
||||
const results: ValidateErrorResult[] = [];
|
||||
const spec = registry.getComponentByType(component.type);
|
||||
if (!spec) {
|
||||
const validate = validators.components[component.type];
|
||||
if (!validate) {
|
||||
results.push({
|
||||
message: `Cannot find component spec: ${component.type}.`,
|
||||
componentId: component.id,
|
||||
@ -79,10 +78,8 @@ export class ComponentPropertyValidatorRule implements ComponentValidatorRule {
|
||||
return results;
|
||||
}
|
||||
|
||||
const propertySchema = spec.spec.properties;
|
||||
const regExp = new RegExp('.*{{.*}}.*');
|
||||
|
||||
const validate = ajv.compile(propertySchema);
|
||||
const valid = validate(component.properties);
|
||||
if (!valid) {
|
||||
validate.errors!.forEach(error => {
|
||||
@ -112,12 +109,11 @@ export class TraitPropertyValidatorRule implements TraitValidatorRule {
|
||||
validate({
|
||||
trait,
|
||||
component,
|
||||
registry,
|
||||
ajv,
|
||||
validators,
|
||||
}: TraitValidateContext): ValidateErrorResult[] {
|
||||
const results: ValidateErrorResult[] = [];
|
||||
const spec = registry.getTraitByType(trait.type);
|
||||
if (!spec) {
|
||||
const validate = validators.traits[trait.type];
|
||||
if (!validate) {
|
||||
results.push({
|
||||
message: `Cannot find trait spec: ${trait.type}.`,
|
||||
componentId: component.id,
|
||||
@ -126,10 +122,6 @@ export class TraitPropertyValidatorRule implements TraitValidatorRule {
|
||||
return results;
|
||||
}
|
||||
|
||||
const propertySchema = spec.spec.properties;
|
||||
const regExp = new RegExp('.*{{.*}}.*');
|
||||
|
||||
const validate = ajv.compile(propertySchema);
|
||||
const valid = validate(trait.properties);
|
||||
if (!valid) {
|
||||
validate.errors!.forEach(error => {
|
||||
@ -139,6 +131,7 @@ export class TraitPropertyValidatorRule implements TraitValidatorRule {
|
||||
const value = trait.properties[path];
|
||||
|
||||
// if value is an expression, skip it
|
||||
const regExp = new RegExp('.*{{.*}}.*');
|
||||
if (typeof value === 'string' && regExp.test(value)) {
|
||||
return;
|
||||
}
|
||||
|
@ -51,9 +51,9 @@ export type SunmaoLib = {
|
||||
};
|
||||
|
||||
export class Registry {
|
||||
components: Map<string, Map<string, ImplementedRuntimeComponent>> = new Map();
|
||||
traits: Map<string, Map<string, ImplementedRuntimeTrait>> = new Map();
|
||||
modules: Map<string, Map<string, ImplementedRuntimeModule>> = new Map();
|
||||
components = new Map<string, Map<string, ImplementedRuntimeComponent>>()
|
||||
traits = new Map<string, Map<string, ImplementedRuntimeTrait>>()
|
||||
modules = new Map<string, Map<string, ImplementedRuntimeModule>>()
|
||||
|
||||
registerComponent(c: ImplementedRuntimeComponent) {
|
||||
if (this.components.get(c.version)?.has(c.metadata.name)) {
|
||||
@ -80,6 +80,16 @@ export class Registry {
|
||||
return this.getComponent(version, name);
|
||||
}
|
||||
|
||||
getAllComponents(): ImplementedRuntimeComponent[] {
|
||||
const res: ImplementedRuntimeComponent[] = [];
|
||||
for (const version of this.components.values()) {
|
||||
for (const component of version.values()) {
|
||||
res.push(component);
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
registerTrait(t: ImplementedRuntimeTrait) {
|
||||
if (this.traits.get(t.version)?.has(t.metadata.name)) {
|
||||
throw new Error(
|
||||
@ -115,6 +125,16 @@ export class Registry {
|
||||
return res;
|
||||
}
|
||||
|
||||
getAllTraits(): ImplementedRuntimeTrait[] {
|
||||
const res: ImplementedRuntimeTrait[] = [];
|
||||
for (const version of this.traits.values()) {
|
||||
for (const trait of version.values()) {
|
||||
res.push(trait);
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
registerModule(c: ImplementedRuntimeModule, overWrite = false) {
|
||||
const parsedModule = parseModuleSchema(cloneDeep(c));
|
||||
if (!overWrite && this.modules.get(c.version)?.has(c.metadata.name)) {
|
||||
|
Loading…
Reference in New Issue
Block a user