de/frontend/src/views/system/datasource/convert.js

188 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const isBoolean = require('lodash.isboolean')
const isEmpty = require('lodash.isempty')
const isInteger = require('lodash.isinteger')
const isNull = require('lodash.isnull')
const isNumber = require('lodash.isnumber')
const isObject = require('lodash.isobject')
const isString = require('lodash.isstring')
const isArray = Array.isArray
class Convert {
constructor() {
this._option = {
$id: 'http://example.com/root.json',
$schema: 'http://json-schema.org/draft-07/schema#'
}
this._object = null
}
/**
* 转换函数
* @param {*} object 需要转换的对象
* @param {*} ?option 可选参数,目前只有能设置 root 节点的 $id 和 $schema
*/
format(object, option = {}) {
// 数据校验确保传入的的object只能是对象或数组
if (!isObject(object)) {
throw new TypeError('传入参数只能是对象或数组')
}
// 合并属性
this._option = Object.assign(this._option, option)
// 需要转换的对象
this._object = object
let convertRes
// 数组类型和对象类型结构不一样
if (isArray(object)) {
convertRes = this._arrayToSchema()
} else {
convertRes = this._objectToSchema()
}
// 释放
this._object = null
return convertRes
}
/**
* 数组类型转换成JSONSCHEMA
*/
_arrayToSchema() {
// root节点基本信息
const result = this._value2object(this._object, this._option.$id, '', true)
if (this._object.length > 0) {
const itemArr = []
for (let index = 0; index < this._object.length; index++) {
// 创建items对象的基本信息
const objectItem = this._object[index]
let item = this._value2object(objectItem, `#/items`, 'items')
if (isObject(objectItem) && !isEmpty(objectItem)) {
// 递归遍历
const objectItemSchema = this._json2schema(objectItem, `#/items`)
// 合并对象
item = Object.assign(item, objectItemSchema)
}
itemArr.push(item)
}
result['items'] = itemArr
}
return result
}
/**
* 对象类型转换成JSONSCHEMA
*/
_objectToSchema() {
let baseResult = this._value2object(this._object, this._option.$id, '', true)
const objectSchema = this._json2schema(this._object)
baseResult = Object.assign(baseResult, objectSchema)
return baseResult
}
_json2schema(object, name = '') {
// 如果递归值不是对象那么return掉
if (!isObject(object)) {
return
}
// 处理当前路径$id
if (name === '' || name === undefined) {
name = '#'
}
const result = {}
// 判断传入object是对象还是数组。
if (isArray(object)) {
result.items = {}
} else {
result.properties = {}
}
// 遍历传入的对象
for (const key in object) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
const element = object[key]
// 如果只是undefined。跳过
if (element === undefined) {
continue
}
const $id = `${name}/properties/${key}`
// 判断当前 element 的值 是否也是对象如果是就继续递归不是就赋值给result
if (!result['properties']) {
continue
}
if (isObject(element)) {
// 创建当前属性的基本信息
result['properties'][key] = this._value2object(element, $id, key)
if (isArray(element)) {
// 针对空数组和有值的数组做不同处理
if (element.length > 0) {
// 是数组
const itemArr = []
for (let index = 0; index < element.length; index++) {
const elementItem = element[index]
// 创建items对象的基本信息
let item = this._value2object(elementItem, `${$id}/items`, key + 'items')
// 判断第一项是否是对象,且对象属性不为空
if (isObject(elementItem) && !isEmpty(elementItem)) {
// 新增的properties才合并进来
item = Object.assign(item, this._json2schema(elementItem, `${$id}/items`))
}
itemArr.push(item)
}
result['properties'][key]['items'] = itemArr
}
} else {
// 不是数组,递归遍历获取,然后合并对象属性
result['properties'][key] = Object.assign(result['properties'][key], this._json2schema(element, $id))
}
} else {
// 一般属性直接获取基本信息
if (result['properties']) {
result['properties'][key] = this._value2object(element, $id, key)
}
}
}
}
return result
}
/**
* 把json的值转换成对象类型
* @param {*} value
* @param {*} $id
* @param {*} key
*/
_value2object(value, $id, key = '', root = false) {
const objectTemplate = {
$id: $id,
title: `The ${key} Schema`,
mock: {
'mock': value
}
}
// 判断是否为初始化root数据
if (root) {
objectTemplate['$schema'] = this._option.$schema
objectTemplate['title'] = `The Root Schema`
objectTemplate['mock'] = undefined
}
if (isBoolean(value)) {
objectTemplate.type = 'boolean'
} else if (isInteger(value)) {
objectTemplate.type = 'integer'
} else if (isNumber(value)) {
objectTemplate.type = 'number'
} else if (isString(value)) {
objectTemplate.type = 'string'
} else if (isNull(value)) {
objectTemplate.type = 'null'
} else if (isArray(value)) {
objectTemplate.type = 'array'
objectTemplate['mock'] = undefined
} else if (isObject(value)) {
objectTemplate.type = 'object'
objectTemplate['mock'] = undefined
}
return objectTemplate
}
}
export default Convert