CannerCMS / cannercms

⚡️ Content Management Framework creates custom CMS fast and easy. Support data sources such as Firebase/Firestore, GraphQL and Restful APIs.

Home Page:https://www.cannerdata.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Improve the typing and pipeline of validation

Mosoc opened this issue · comments

Is your feature request related to a problem? Please describe.

const ajv = new Ajv();
const validate = ajv.compile(validation);
// custom validator
const {validator, errorMessage} = validation;
const reject = message => ({error: true, message});
const validatorResult = validator && validator(value, reject);

In validation.js, we can see that it always create a new ajv instance, pass the whole validation: Object as schema to ajv.compile() to get validate function.

Then get validator: function and errorMessage: string from validation: Object by destructing assignment to follow-up action.

This mixed object and pipeline design might cause:

  • Hard to type checking and management
  • Potential risk of name conflict
  • Performance issue

Describe the solution you'd like

Use same props, but add schema property for holding ajv schema object.

    <string
      keyName="text"
      title="Text"
      validation= {{
        schema: {pattern: '^[a-zA-Z0-9]{4,10}$'} // JSONSchemaOptions
        validator: ()=>( /* ... */ ) // ValidationFunction
        errorMessage: "Error!"
      }}
    />

Describe alternatives you've considered

Use different props instead.

<string
  keyName="text"
  title="Text"
  validation={{pattern: '^[a-zA-Z0-9]{4,10}$'}}
  customizedValidator={()=>( /* ... */ )}
  errorMessage="Error!"
/>

Additional context about solution

We can get this properties by destructing assignment and create ajv instance only when schema existing.

const { schema, validator, errorMessage} = validation;
let validate = null
if(schema && !isEmpty(schema)) {
  const ajv = new Ajv();
  validate = ajv.compile(schema);
}

Typing
Also, we should complete the type definition of validation HoC.

For ajv usage, we can refer to ajv.d.ts
and keywords

And for customized validator, it will be following statement:

 validator?: (value: any) => Object  | Promise<Object>  | Promise<void> | void;
commented

After the discussion, we think this usage is great. thanks!

 <string
      keyName="text"
      title="Text"
      validation= {{
        schema: {pattern: '^[a-zA-Z0-9]{4,10}$'} // JSONSchemaOptions
        validator: ()=>() //ValidationFunction
        errorMessage: "Error!"
      }}
    />