@ovine/core
Version:
Build flexible admin system with json.
170 lines (169 loc) • 5.98 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { resolveRenderer } from 'amis';
import { filter } from 'amis/lib/utils/tpl';
import { get, isArray, isEmpty, isObject, map, omit, isFunction } from 'lodash';
import { checkLimitByKeys } from "../../../routes/limit/exports";
import logger from "../../../utils/logger";
const log = logger.getLogger('dev:amisSchema:utils');
// 校验 schema 权限
const checkSchemaLimit = (schema, nodePath) => {
const { limits, limitsLogic = 'and' } = schema || {};
if (!limits) {
return true;
}
if (limitsLogic === 'or' && typeof limits !== 'string') {
return !!limits.some((limit) => checkLimitByKeys(limit, { nodePath }));
}
const isAuth = checkLimitByKeys(limits, { nodePath });
return isAuth;
};
// 过滤无权限操作
export const filterSchemaLimit = (schema, option) => {
const { nodePath, isDefinitions } = option || {};
if (!isObject(schema)) {
return;
}
if (isArray(schema)) {
const limitedIdxAr = [];
schema.forEach((item, index) => {
if (!checkSchemaLimit(item, nodePath)) {
limitedIdxAr.push(index);
}
else {
filterSchemaLimit(item, { nodePath });
}
});
limitedIdxAr.forEach((idx, index) => {
schema.splice(idx - index, 1);
});
return;
}
if (!checkSchemaLimit(schema, nodePath)) {
;
schema.type = 'lib-omit';
return;
}
map(schema, (val, key) => {
if (!isObject(schema)) {
return;
}
if (!checkSchemaLimit(val, nodePath)) {
if (isDefinitions) {
schema[key] = {
type: 'lib-omit',
};
}
else {
delete schema[key];
}
return;
}
filterSchemaLimit(val, { nodePath, isDefinitions: key === 'definitions' });
});
};
// 自定义格式 转换为 amis 格式
export const convertToAmisSchema = (schema, option) => {
const { definitions, preset, constants } = option;
if (!preset && !definitions && !constants) {
return schema;
}
const { nodePath } = preset || {};
map(schema, (value, key) => {
// trans constants key
if (constants) {
if (typeof value === 'string' && /\$\{[A-Z][A-Z0-9_]*\}/.test(value)) {
const newVal = filter(value, constants);
schema[key] = newVal;
}
if (typeof key === 'string' && /\$\{[A-Z][A-Z0-9_]*\}/.test(key)) {
const newKey = filter(key, constants);
schema[newKey] = value;
delete schema[key];
}
}
// Omit " apis" and "limits"
if (key === 'apis' || key === 'limits') {
return;
}
if (isObject(value)) {
schema[key] = convertToAmisSchema(value, option);
return;
}
// resolve definitions functions keys
if (key === '$ref' && isFunction(get(definitions, value))) {
delete schema.$ref;
schema = get(definitions, value)(schema) || { type: 'lib-omit' };
return;
}
// resolve preset keys
const presetRefType = key === '$preset'
? 'key'
: typeof value === 'string' && value.indexOf('$preset.') === 0
? 'value'
: '';
if (!presetRefType) {
return;
}
const isKeyRef = presetRefType === 'key';
const presetVal = get(preset, isKeyRef ? value : value.replace('$preset.', ''));
const logStr = ` [${key}: ${value}] 请检查 ${nodePath}/preset 或者 schema.preset`;
if (!presetVal) {
log.warn('$preset 不存在。', logStr);
return;
}
if (!isKeyRef) {
schema[key] = presetVal;
return;
}
if (!isObject(presetVal)) {
log.warn('$preset为key时,只能引用object值。', logStr);
return;
}
delete schema.$preset;
schema = Object.assign(Object.assign({}, presetVal), schema);
});
return schema;
};
// 处理自定义格式
export const resolveLibSchema = (schema) => {
const { preset = {}, definitions, constants } = schema, rest = __rest(schema, ["preset", "definitions", "constants"]);
if (isEmpty(preset) && isEmpty(definitions) && !constants) {
return Object.assign(Object.assign({}, rest), { definitions });
}
const reformSchema = Object.assign({ definitions, preset }, rest);
const amisSchema = convertToAmisSchema(reformSchema, { definitions, preset, constants });
const authSchema = omit(amisSchema, ['preset']);
filterSchemaLimit(authSchema, preset);
return authSchema;
};
// 自定义解析器
export const libResolver = (path, schema) => {
return resolveRenderer(path, schema);
};
// 顶层有 type 与 css 属性, 自动注入 lib-css
export const wrapCss = (schema) => {
const { css: getCss, tag, htmlClassName, definitions, constants, preset } = schema, rest = __rest(schema, ["css", "tag", "htmlClassName", "definitions", "constants", "preset"]);
if (!getCss && !tag && !htmlClassName) {
return schema;
}
return {
tag,
preset,
definitions,
constants,
htmlClassName,
body: rest,
css: getCss,
type: 'lib-css',
};
};