UNPKG

@schema-render/core-react

Version:

Through a set of simple JSON Schema, efficiently build a set of forms.

85 lines (84 loc) 3.45 kB
import { cloneDeep, mapKeys, toLower } from "./tinyLodash"; export function isInvalidTraverseSchema({ properties }) { return !properties || typeof properties !== 'object' || Array.isArray(properties); } export default function traverseSchema(schema, visitor, options) { const opts = { mapKey: 'renderType', ignoreCase: true, clone: true, initialState: {}, initialStore: {}, ...options }; const finalSchema = opts.clone ? cloneDeep(schema) : schema; // 将 visitor 转换成小写 visitor = mapKeys(visitor, (_, key)=>key.toLowerCase()); const traverse = ({ schema, path, state, store })=>{ if (isInvalidTraverseSchema(schema)) return; Object.keys(schema.properties).forEach((field)=>{ var // 节点进入事件 _$$_enter, _special_enter, /** * 节点退出事件 */ _$$_exit, _$$Object_exit, _special_exit; const subSchema = schema.properties[field]; const subPath = [ ...path, field ]; const currentState = cloneDeep(state); const params = { schema: subSchema, parentSchema: schema, path: subPath, field, state: currentState, store }; const innerTraverse = (innerParams)=>{ traverse({ schema: subSchema, path: subPath, state: currentState, ...innerParams, store }); }; // $$: 匹配所有的节点类型 const $$ = visitor.$$ ?? {}; const $$Object = visitor.$$object ?? {}; (_$$_enter = $$.enter) === null || _$$_enter === void 0 ? void 0 : _$$_enter.call($$, { ...params, traverse: innerTraverse }); // special: 匹配特定的节点类型 let nodeType = subSchema[opts.mapKey] ?? ''; nodeType = opts.ignoreCase ? toLower(nodeType) : nodeType; const isObjectLike = toLower(nodeType).startsWith('object'); // 对象类型进入事件 if (isObjectLike) { var _$$Object_enter; (_$$Object_enter = $$Object.enter) === null || _$$Object_enter === void 0 ? void 0 : _$$Object_enter.call($$Object, { ...params, traverse: innerTraverse }); } // 特定节点进入事件 const special = visitor[nodeType] ?? {}; (_special_enter = special.enter) === null || _special_enter === void 0 ? void 0 : _special_enter.call(special, { ...params, traverse: innerTraverse }); (_$$_exit = $$.exit) === null || _$$_exit === void 0 ? void 0 : _$$_exit.call($$, params); isObjectLike && ((_$$Object_exit = $$Object.exit) === null || _$$Object_exit === void 0 ? void 0 : _$$Object_exit.call($$Object, params)); (_special_exit = special.exit) === null || _special_exit === void 0 ? void 0 : _special_exit.call(special, params); }); }; traverse({ schema: finalSchema, path: [], state: opts.initialState, store: opts.initialStore }); return finalSchema; }