mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-23 14:39:32 +08:00
feat(blocksTools): mockBlockProps to provide schema errors
This commit is contained in:
parent
c5bd4ebc9a
commit
6c192d42b0
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@lowdefy/block-tools",
|
||||
"version": "1.0.1-alpha.4",
|
||||
"version": "1.0.1-alpha.5",
|
||||
"licence": "Apache-2.0",
|
||||
"description": "Lowdefy Block Tools",
|
||||
"homepage": "https://lowdefy.com",
|
||||
|
53
packages/blockTools/src/blockSchema.json
Normal file
53
packages/blockTools/src/blockSchema.json
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"object"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"type": "object"
|
||||
},
|
||||
"layout": {
|
||||
"type": "object"
|
||||
},
|
||||
"blocks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"type": "object"
|
||||
},
|
||||
"areas": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"blocks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,17 @@
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import Ajv from 'ajv';
|
||||
import AjvErrors from 'ajv-errors';
|
||||
import { type } from '@lowdefy/helpers';
|
||||
import blockSchema from './blockSchema.json';
|
||||
|
||||
const initAjv = (options) => {
|
||||
const ajv = new Ajv({ allErrors: true, jsonPointers: true, ...options });
|
||||
AjvErrors(ajv, options);
|
||||
return ajv;
|
||||
};
|
||||
const ajvInstance = initAjv();
|
||||
|
||||
const mockBlockProps = ({ block, meta, logger }) => {
|
||||
const [value, setState] = useState(type.enforceType(meta.valueType, null));
|
||||
@ -25,6 +35,12 @@ const mockBlockProps = ({ block, meta, logger }) => {
|
||||
let log = alert;
|
||||
if (logger) log = logger;
|
||||
|
||||
// evaluate block schema
|
||||
blockSchema.properties = { ...blockSchema.properties, ...meta.schema };
|
||||
const validate = ajvInstance.compile(blockSchema);
|
||||
block.schemaErrors = !validate(block);
|
||||
if (block.schemaErrors) block.schemaErrors = validate.errors;
|
||||
|
||||
// block defaults
|
||||
block.blockId = block.id;
|
||||
if (meta.category === 'list' || meta.category === 'container' || meta.category === 'context') {
|
||||
|
@ -51,6 +51,7 @@ test('basic display', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Display",
|
||||
}
|
||||
`);
|
||||
@ -78,6 +79,17 @@ test('basic display with methods', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": Array [
|
||||
Object {
|
||||
"dataPath": "",
|
||||
"keyword": "additionalProperties",
|
||||
"message": "should NOT have additional properties",
|
||||
"params": Object {
|
||||
"additionalProperty": "methods",
|
||||
},
|
||||
"schemaPath": "#/additionalProperties",
|
||||
},
|
||||
],
|
||||
"type": "Display",
|
||||
}
|
||||
`);
|
||||
@ -106,6 +118,7 @@ test('basic input', () => {
|
||||
"registerMethod": [Function],
|
||||
"setValue": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Input",
|
||||
"value": null,
|
||||
}
|
||||
@ -132,6 +145,7 @@ test('input setState', () => {
|
||||
"registerMethod": [Function],
|
||||
"setValue": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Input",
|
||||
"value": null,
|
||||
}
|
||||
@ -163,6 +177,7 @@ test('basic container', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Container",
|
||||
}
|
||||
`);
|
||||
@ -191,6 +206,7 @@ test('basic context', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Context",
|
||||
}
|
||||
`);
|
||||
@ -222,6 +238,7 @@ test('basic list', () => {
|
||||
"removeItem": [Function],
|
||||
"unshiftItem": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "List",
|
||||
}
|
||||
`);
|
||||
@ -254,6 +271,7 @@ test('list methods', () => {
|
||||
"removeItem": [Function],
|
||||
"unshiftItem": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "List",
|
||||
}
|
||||
`);
|
||||
@ -308,6 +326,7 @@ test('blocks container', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Container",
|
||||
}
|
||||
`);
|
||||
@ -368,6 +387,7 @@ test('blocks areas container', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Container",
|
||||
}
|
||||
`);
|
||||
@ -415,6 +435,7 @@ test('areas container', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Container",
|
||||
}
|
||||
`);
|
||||
@ -462,6 +483,7 @@ test('areas context', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Context",
|
||||
}
|
||||
`);
|
||||
@ -516,6 +538,7 @@ test('areas list', () => {
|
||||
"removeItem": [Function],
|
||||
"unshiftItem": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "List",
|
||||
}
|
||||
`);
|
||||
@ -556,6 +579,7 @@ test('actions display', () => {
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Display",
|
||||
}
|
||||
`);
|
||||
@ -564,3 +588,76 @@ test('actions display', () => {
|
||||
res.methods.registerMethod({ action: 'open' });
|
||||
expect(logger).toBeCalledTimes(3);
|
||||
});
|
||||
|
||||
test('provide schema errors', () => {
|
||||
let block = {
|
||||
id: 'a',
|
||||
type: 'Display',
|
||||
properties: {
|
||||
mistake: true,
|
||||
},
|
||||
};
|
||||
const meta = {
|
||||
category: 'display',
|
||||
schema: {
|
||||
properties: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
mistake: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(mockBlockProps({ block, meta })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"blockId": "a",
|
||||
"id": "a",
|
||||
"methods": Object {
|
||||
"callAction": [Function],
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"properties": Object {
|
||||
"mistake": true,
|
||||
},
|
||||
"schemaErrors": false,
|
||||
"type": "Display",
|
||||
}
|
||||
`);
|
||||
block = {
|
||||
id: 'a',
|
||||
type: 'Display',
|
||||
properties: {
|
||||
mistake: 1,
|
||||
},
|
||||
};
|
||||
expect(mockBlockProps({ block, meta })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"blockId": "a",
|
||||
"id": "a",
|
||||
"methods": Object {
|
||||
"callAction": [Function],
|
||||
"registerAction": [Function],
|
||||
"registerMethod": [Function],
|
||||
},
|
||||
"properties": Object {
|
||||
"mistake": 1,
|
||||
},
|
||||
"schemaErrors": Array [
|
||||
Object {
|
||||
"dataPath": "/properties/mistake",
|
||||
"keyword": "type",
|
||||
"message": "should be boolean",
|
||||
"params": Object {
|
||||
"type": "boolean",
|
||||
},
|
||||
"schemaPath": "#/properties/properties/properties/mistake/type",
|
||||
},
|
||||
],
|
||||
"type": "Display",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
import Ajv from 'ajv';
|
||||
import AjvErrors from 'ajv-errors';
|
||||
import blockSchema from './blockSchema.json';
|
||||
|
||||
const initAjv = (options) => {
|
||||
const ajv = new Ajv({ allErrors: true, jsonPointers: true, ...options });
|
||||
@ -23,51 +24,6 @@ const initAjv = (options) => {
|
||||
return ajv;
|
||||
};
|
||||
|
||||
const blockSchema = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['id', 'type'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
},
|
||||
properties: {
|
||||
type: 'object',
|
||||
},
|
||||
layout: {
|
||||
type: 'object',
|
||||
},
|
||||
blocks: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
type: 'object',
|
||||
},
|
||||
areas: {
|
||||
type: 'object',
|
||||
patternProperties: {
|
||||
'^.*$': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
blocks: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const ajvInstance = initAjv();
|
||||
const runBlockSchemaTests = ({ examples, meta }) => {
|
||||
blockSchema.properties = { ...blockSchema.properties, ...meta.schema };
|
||||
|
@ -55,6 +55,12 @@
|
||||
"$ref": "#/definitions/request"
|
||||
}
|
||||
},
|
||||
"required": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"object"
|
||||
]
|
||||
},
|
||||
"mutations": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -33,7 +33,7 @@
|
||||
"version:major": "yarn version major -d"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lowdefy/block-tools": "1.0.1-alpha.4",
|
||||
"@lowdefy/block-tools": "1.0.1-alpha.5",
|
||||
"@lowdefy/graphql": "0.0.0-experimental.0",
|
||||
"apollo-server-express": "2.18.2",
|
||||
"express": "4.17.1",
|
||||
|
@ -2794,7 +2794,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lowdefy/block-tools@1.0.1-alpha.4, @lowdefy/block-tools@workspace:packages/blockTools":
|
||||
"@lowdefy/block-tools@1.0.1-alpha.5, @lowdefy/block-tools@workspace:packages/blockTools":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@lowdefy/block-tools@workspace:packages/blockTools"
|
||||
dependencies:
|
||||
@ -2943,7 +2943,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@babel/core": 7.12.3
|
||||
"@babel/preset-react": 7.12.1
|
||||
"@lowdefy/block-tools": 1.0.1-alpha.4
|
||||
"@lowdefy/block-tools": 1.0.1-alpha.5
|
||||
"@lowdefy/graphql": 0.0.0-experimental.0
|
||||
apollo-server-express: 2.18.2
|
||||
babel-loader: 8.1.0
|
||||
|
Loading…
Reference in New Issue
Block a user