UNPKG

schema-based-json-editor

Version:

A reactjs and vuejs component of schema based json editor.

963 lines (962 loc) 28.9 kB
import toNumber from 'lodash.tonumber'; import toInteger from 'lodash.tointeger'; import isObject from 'lodash.isobject'; import isInteger from 'lodash.isinteger'; import { defaultLocale as defaultMarkDownTipLocale } from 'markdown-tip'; import { defaultLocale as defaultFileUploaderLocale } from 'file-uploader-component'; export { toNumber, toInteger }; import { __extends, __decorate, __assign } from 'tslib'; window.__extends = __extends; window.__decorate = __decorate; window.__assign = __assign; /** * @public */ export var themes = { bootstrap3: { card: 'well', row: 'row', errorRow: 'row has-error', input: 'form-control', errorInput: 'form-control', textarea: 'form-control', errorTextarea: 'form-control', checkbox: 'checkbox pull-left', radiobox: 'radio-inline', button: 'btn btn-default', buttonGroup: 'btn-group', title: 'control-label', description: 'help-block', select: 'form-control' }, bootstrap4: { card: 'card card-body', row: '', errorRow: 'text-danger', input: 'form-control', errorInput: 'form-control is-invalid', textarea: 'form-control', errorTextarea: 'form-control is-invalid', checkbox: '', radiobox: '', button: 'btn btn-default', buttonGroup: 'btn-group', title: 'col-form-label', description: 'form-text', select: 'form-control' }, bootstrap5: { card: 'card card-body', row: '', errorRow: 'text-danger', input: 'form-control', errorInput: 'form-control is-invalid', textarea: 'form-control', errorTextarea: 'form-control is-invalid', checkbox: '', radiobox: '', button: 'btn btn-default', buttonGroup: 'btn-group', title: 'col-form-label', description: 'form-text', select: 'form-control' }, antd3: { card: 'ant-card ant-card-bordered ant-card-body', row: 'ant-row', errorRow: 'ant-row has-error', input: 'ant-input', errorInput: 'ant-input', textarea: 'ant-input', errorTextarea: 'ant-input', checkbox: 'ant-checkbox', radiobox: 'ant-radio', button: 'ant-btn', buttonGroup: 'ant-btn-group', title: 'ant-form-item-label', description: 'ant-form-explain', select: 'ant-input' }, 'element-ui2': { card: 'el-form el-card box-card el-card__body', row: 'el-form-item', errorRow: 'el-form-item is-error', input: 'el-input__inner', errorInput: 'el-input__inner', textarea: 'el-textarea__inner', errorTextarea: 'el-textarea__inner', button: 'el-button el-button--default el-button--small', buttonGroup: 'el-button-group', checkbox: 'el-checkbox', radiobox: 'el-radio', title: '', description: '', select: 'el-input__inner' }, iview2: { card: 'ivu-card ivu-card-body', row: 'ivu-row', errorRow: 'ivu-row ivu-form-item-error', input: 'ivu-input', errorInput: 'ivu-input', textarea: 'ivu-input', errorTextarea: 'ivu-input', button: 'ivu-btn', buttonGroup: 'ivu-btn-group ivu-btn-group-small', checkbox: 'ivu-checkbox', radiobox: 'ivu-radio', title: 'ivu-form-item-label', description: '', select: 'ivu-input' }, iview3: { card: 'ivu-card ivu-card-body', row: 'ivu-row', errorRow: 'ivu-row ivu-form-item-error', input: 'ivu-input', errorInput: 'ivu-input', textarea: 'ivu-input', errorTextarea: 'ivu-input', button: 'ivu-btn', buttonGroup: 'ivu-btn-group ivu-btn-group-small', checkbox: 'ivu-checkbox', radiobox: 'ivu-radio', title: 'ivu-form-item-label', description: '', select: 'ivu-input' }, blueprint1: { card: 'pt-card', row: '', errorRow: '', input: 'pt-input pt-fill', errorInput: 'pt-input pt-fill', textarea: 'pt-input pt-fill', errorTextarea: 'pt-input pt-fill', button: 'pt-button', buttonGroup: 'pt-button-group', checkbox: 'pt-checkbox', radiobox: 'pt-radio', title: 'pt-label', description: 'pt-text-muted', select: 'pt-input pt-fill' }, blueprint2: { card: 'pt-card', row: '', errorRow: '', input: 'pt-input pt-fill', errorInput: 'pt-input pt-fill', textarea: 'pt-input pt-fill', errorTextarea: 'pt-input pt-fill', button: 'pt-button', buttonGroup: 'pt-button-group', checkbox: 'pt-checkbox', radiobox: 'pt-radio', title: 'pt-label', description: 'pt-text-muted', select: 'pt-input pt-fill' }, blueprint3: { card: 'pt3-card', row: '', errorRow: '', input: 'pt3-input pt3-fill', errorInput: 'pt3-input pt3-fill', textarea: 'pt3-input pt-fill', errorTextarea: 'pt3-input pt-fill', button: 'pt3-button', buttonGroup: 'pt3-button-group', checkbox: 'pt3-checkbox', radiobox: 'pt3-radio', title: 'pt3-label', description: 'pt3-text-muted', select: 'pt3-input pt3-fill' } }; /** * @public */ export var defaultTheme = { card: 'schema-based-json-editor--card', row: 'schema-based-json-editor--row', errorRow: 'schema-based-json-editor--error-row', input: 'schema-based-json-editor--input', errorInput: 'schema-based-json-editor--error-input', textarea: 'schema-based-json-editor--textarea', errorTextarea: 'schema-based-json-editor--error-textarea', checkbox: 'schema-based-json-editor--checkbox', radiobox: 'schema-based-json-editor--radiobox', button: 'schema-based-json-editor--button', buttonGroup: 'schema-based-json-editor--button-group', title: 'schema-based-json-editor--title', description: 'schema-based-json-editor--description', select: 'schema-based-json-editor--select' }; for (var themeName in themes) { for (var key in themes[themeName]) { themes[themeName][key] += ' ' + defaultTheme[key]; } } /** * @public */ export function getTheme(name) { if (name === undefined) { return defaultTheme; } if (typeof name === 'string') { return themes[name] || defaultTheme; } return name; } /** * @public */ export var defaultLocale = { button: { collapse: 'Collapse', expand: 'Expand', add: 'Add', delete: 'Delete' }, error: { minLength: 'Value must be at least {0} characters long.', maxLength: 'Value must be at most {0} characters long.', pattern: "Value doesn't match the pattern {0}.", minimum: 'Value must be >= {0}.', maximum: 'Value must be <= {0}.', largerThan: 'Value must be > {0}.', smallerThan: 'Value must be < {0}.', minItems: 'The length of the array must be >= {0}.', uniqueItems: 'The item in {0} and {1} must not be same.', multipleOf: 'Value must be multiple value of {0}.', minProperties: 'Properties count must be >= {0}.', maxProperties: 'Properties count must be <= {0}.' }, info: { notExists: 'not exists', true: 'true', false: 'false', search: 'search' }, markdownTipLocale: defaultMarkDownTipLocale, fileUploaderLocale: defaultFileUploaderLocale }; /** * @public */ export var locales = {}; /** * @public */ export function getLocale(locale) { return locale || defaultLocale; } /** * @public */ export var bootstrap3Icon = { isText: false, collapse: 'glyphicon glyphicon-chevron-down', expand: 'glyphicon glyphicon-chevron-right', add: 'glyphicon glyphicon-plus', delete: 'glyphicon glyphicon-remove' }; /** * @public */ export var icons = { bootstrap3: bootstrap3Icon, fontawesome4: { isText: false, collapse: 'fa fa-caret-square-o-down', expand: 'fa fa-caret-square-o-right', add: 'fa fa-plus', delete: 'fa fa-times' }, fontawesome5: { isText: false, collapse: 'fas fa-caret-square-down', expand: 'fas fa-caret-square-right', add: 'fas fa-plus', delete: 'fas fa-times' }, antd3: { isText: false, collapse: 'anticon anticon-down', expand: 'anticon anticon-right', add: 'anticon anticon-plus', delete: 'anticon anticon-close' }, 'element-ui2': { isText: false, collapse: 'el-icon-arrow-down', expand: 'el-icon-arrow-right', add: 'el-icon-plus', delete: 'el-icon-close' }, iview2: { isText: false, collapse: 'ivu-icon ivu-icon-ios-arrow-down', expand: 'ivu-icon ivu-icon-ios-arrow-right', add: 'ivu-icon ivu-icon-ios-plus-empty', delete: 'ivu-icon ivu-icon-ios-close-empty' }, iview3: { isText: false, collapse: 'ivu-icon ivu-icon-ios-arrow-down', expand: 'ivu-icon ivu-icon-ios-arrow-back', add: 'ivu-icon ivu-icon-md-add', delete: 'ivu-icon ivu-icon-md-close' }, 'bootstrap-icons': { isText: false, collapse: 'bi bi-arrows-collapse', expand: 'bi bi-arrows-expand', add: 'bi bi-plus', delete: 'bi bi-trash' } }; /** * @public */ export function getIcon(name, locale) { if (name === undefined) { return { isText: true, collapse: locale.button.collapse, expand: locale.button.expand, add: locale.button.add, delete: locale.button.delete }; } if (typeof name === 'string') { return icons[name] || { isText: true, collapse: locale.button.collapse, expand: locale.button.expand, add: locale.button.add, delete: locale.button.delete }; } return name; } /** * @public */ export function getDefaultValue(required, schema, initialValue) { if (required === void 0) { required = undefined; } if (initialValue !== undefined) { switch (schema.type) { case 'object': if (isObject(initialValue)) { return initialValue; } break; case 'array': if (Array.isArray(initialValue)) { return initialValue; } break; case 'number': case 'integer': if (typeof initialValue === 'number') { return initialValue; } break; case 'boolean': if (typeof initialValue === 'boolean') { return initialValue; } break; case 'string': if (typeof initialValue === 'string') { return initialValue; } break; case undefined: return initialValue; case 'null': default: if (initialValue === null) { return initialValue; } } } if (!required) { return undefined; } if (schema.default !== undefined) { switch (schema.type) { case 'object': if (isObject(schema.default)) { return schema.default; } break; case 'array': if (Array.isArray(schema.default)) { return schema.default; } break; case 'number': case 'integer': if (typeof schema.default === 'number') { return schema.default; } break; case 'boolean': if (typeof schema.default === 'boolean') { return schema.default; } break; case 'string': if (typeof schema.default === 'string') { return schema.default; } break; case 'null': default: if (schema.default === null) { return schema.default; } } } switch (schema.type) { case 'object': var value = {}; for (var property in schema.properties) { var propertySchema = schema.properties[property]; value[propertySchema.propertyName || property] = undefined; } return value; case 'array': return []; case 'number': case 'integer': if (schema.enum !== undefined && schema.enum.length > 0) { return schema.enum[0]; } else { return 0; } case 'boolean': return false; case 'string': if (schema.enum !== undefined && schema.enum.length > 0) { return schema.enum[0]; } else { return ''; } case 'null': default: return null; } } /** * @public */ export var buttonGroupStyle = { marginLeft: '10px' }; /** * @public */ export var buttonGroupStyleString = 'margin-left: 10px'; /** * @public */ export function isSame(value1, value2) { if (typeof value1 === 'string' || typeof value1 === 'number' || typeof value1 === 'boolean' || value1 === null || value1 === undefined) { return value1 === value2; } if (typeof value2 === 'string' || typeof value2 === 'number' || typeof value2 === 'boolean' || value2 === null || value2 === undefined) { return false; } if (Array.isArray(value1)) { if (Array.isArray(value2) && value1.length === value2.length) { for (var i = 0; i < value1.length; i++) { if (!isSame(value1[i], value2[i])) { return false; } } return true; } return false; } if (Array.isArray(value2) || Object.keys(value1).length !== Object.keys(value2).length) { return false; } for (var key in value1) { if (value1.hasOwnProperty(key) && !isSame(value1[key], value2[key])) { return false; } } return true; } /** * @public */ export function switchItem(value, el, sibling) { var fromIndex = +el.dataset.index; if (sibling) { var toIndex = +sibling.dataset.index; value.splice(toIndex, 0, value[fromIndex]); if (fromIndex > toIndex) { value.splice(fromIndex + 1, 1); } else { value.splice(fromIndex, 1); } } else { value.push(value[fromIndex]); value.splice(fromIndex, 1); } } /** * @public */ export function getErrorMessageOfArray(value, schema, locale) { if (value !== undefined) { if (schema.minItems !== undefined && value.length < schema.minItems) { return locale.error.minItems.replace('{0}', String(schema.minItems)); } if (schema.uniqueItems) { for (var i = 1; i < value.length; i++) { for (var j = 0; j < i; j++) { if (isSame(value[i], value[j])) { return locale.error.uniqueItems.replace('{0}', String(j)).replace('{1}', String(i)); } } } } } return ''; } /** * @public */ export function getErrorMessageOfNumber(value, schema, locale) { if (value !== undefined) { if (schema.minimum !== undefined) { if (schema.exclusiveMinimum) { if (value <= schema.minimum) { return locale.error.largerThan.replace('{0}', String(schema.minimum)); } } else { if (value < schema.minimum) { return locale.error.minimum.replace('{0}', String(schema.minimum)); } } } if (schema.maximum !== undefined) { if (schema.exclusiveMaximum) { if (value >= schema.maximum) { return locale.error.smallerThan.replace('{0}', String(schema.maximum)); } } else { if (value > schema.maximum) { return locale.error.maximum.replace('{0}', String(schema.maximum)); } } } if (schema.multipleOf && schema.multipleOf > 0 && !isInteger(value / schema.multipleOf)) { return locale.error.multipleOf.replace('{0}', String(schema.multipleOf)); } } return ''; } /** * @public */ export function getErrorMessageOfString(value, schema, locale) { if (value !== undefined) { if (schema.minLength !== undefined && value.length < schema.minLength) { return locale.error.minLength.replace('{0}', String(schema.minLength)); } if (schema.maxLength !== undefined && value.length > schema.maxLength) { return locale.error.maxLength.replace('{0}', String(schema.maxLength)); } if (schema.pattern !== undefined && !new RegExp(schema.pattern).test(value)) { return locale.error.pattern.replace('{0}', String(schema.pattern)); } } return ''; } /** * @public */ export function getErrorMessageOfObject(value, schema, locale) { if (value !== undefined) { var length_1 = 0; for (var key in value) { if (value.hasOwnProperty(key) && value[key] !== undefined) { length_1++; } } if (schema.minProperties !== undefined && length_1 < schema.minProperties) { return locale.error.minProperties.replace('{0}', String(schema.minProperties)); } if (schema.maxProperties !== undefined && length_1 > schema.maxProperties) { return locale.error.maxProperties.replace('{0}', String(schema.maxProperties)); } } return ''; } /** * @public */ export function toggleOptional(value, schema, initialValue) { if (value === undefined) { return getDefaultValue(true, schema, initialValue); } else { return undefined; } } /** * @public */ export function recordInvalidPropertiesOfObject(invalidProperties, isValid, property) { var index = invalidProperties.indexOf(property); if (isValid) { if (index !== -1) { invalidProperties.splice(index, 1); } } else { if (index === -1) { invalidProperties.push(property); } } } /** * @public */ export function recordInvalidIndexesOfArray(invalidIndexes, isValid, i) { var index = invalidIndexes.indexOf(i); if (isValid) { if (index !== -1) { invalidIndexes.splice(index, 1); } } else { if (index === -1) { invalidIndexes.push(i); } } } var imageExtensions = ['.png', '.jpg', '.bmp', '.gif']; /** * @public */ export function isImageUrl(value) { if (!value || value.length <= 'https://'.length) { return false; } if (value.substr(0, 'http://'.length) !== 'http://' && value.substr(0, 'https://'.length) !== 'https://') { return false; } var extensionName = value.substr(value.length - 4, 4); return imageExtensions.indexOf(extensionName) !== -1; } /** * @public */ export function isBase64Image(value) { if (!value) { return false; } return value.indexOf("data:image/") === 0 && value.indexOf(";base64,") !== -1; } /** * @public */ export function replaceProtocal(src) { if (src.indexOf('http://') === 0 && src.indexOf('http://localhost') !== 0) { return 'https://' + src.substring('http://'.length); } return src; } /** * @public */ export var imagePreviewStyleString = 'display: block; height: auto; margin: 6px 0; max-width: 100%;'; /** * @public */ export var imagePreviewStyle = { display: 'block', height: 'auto', margin: '6px 0', maxWidth: '100%' }; function printInConsole(message) { console.log(message); } /** * @public */ export function initializeMarkdown(markdownit, hljs, forceHttps) { if (forceHttps === void 0) { forceHttps = undefined; } if (!markdownit) { return undefined; } var md = markdownit({ linkify: true, highlight: function (str, lang) { if (hljs) { if (lang && hljs.getLanguage(lang)) { try { return "<pre><code class=\"hljs " + lang + "\">" + hljs.highlight(lang, str).value + "</code></pre>"; } catch (error) { printInConsole(error); } } else { try { return "<pre><code class=\"hljs\">" + hljs.highlightAuto(str).value + "</code></pre>"; } catch (error) { printInConsole(error); } } } return "<pre><code class=\"hljs\">" + md.utils.escapeHtml(str) + "</code></pre>"; } }); md.renderer.rules.image = function (tokens, index, options, env, self) { var token = tokens[index]; var aIndex = token.attrIndex('src'); if (forceHttps) { token.attrs[aIndex][1] = replaceProtocal(token.attrs[aIndex][1]); } token.attrPush(['style', imagePreviewStyleString]); return md.renderer.rules.image(tokens, index, options, env, self); }; var defaultLinkRender; if (md.renderer.rules.link_open) { defaultLinkRender = md.renderer.rules.link_open; } else { defaultLinkRender = function (tokens, index, options, env, self) { return self.renderToken(tokens, index, options); }; } md.renderer.rules.link_open = function (tokens, index, options, env, self) { tokens[index].attrPush(['target', '_blank']); tokens[index].attrPush(['rel', 'nofollow']); return defaultLinkRender(tokens, index, options, env, self); }; return md; } /** * @public */ export function findTitle(value, properties) { if (value) { for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) { var _a = properties_1[_i], property = _a.property, schema = _a.schema; var title = value[property]; if ((schema.type === 'number' || schema.type === 'integer' || schema.type === 'string') && schema.enum && schema.enumTitles) { var index = schema.enum.indexOf(title); if (index !== -1 && index < schema.enumTitles.length) { var enumTitle = schema.enumTitles[index]; if (typeof enumTitle === 'string' && enumTitle.length > 0) { if (enumTitle.length > 23) { return enumTitle.substring(0, 20) + '...'; } return enumTitle; } } } if (typeof title === 'string' && title.length > 0) { if (title.length > 23) { return title.substring(0, 20) + '...'; } return title; } } } return undefined; } function findTitleFromSchema(value, schema) { if (value) { for (var property in schema.properties) { if (schema.properties.hasOwnProperty(property)) { var title = value[property]; if (typeof title === 'string' && title.length > 0) { if (title.length > 23) { return title.substring(0, 20) + '...'; } return title; } } } } return undefined; } /** * @public */ export function getTitle() { var titles = []; for (var _i = 0; _i < arguments.length; _i++) { titles[_i] = arguments[_i]; } for (var _a = 0, titles_1 = titles; _a < titles_1.length; _a++) { var title = titles_1[_a]; if (title === undefined || title === null) { continue; } return String(title); } return ''; } /** * @public */ export function compare(a, b) { if (typeof a.schema.propertyOrder === 'number') { if (typeof b.schema.propertyOrder === 'number') { return a.schema.propertyOrder - b.schema.propertyOrder; } return -1; } if (typeof b.schema.propertyOrder === 'number') { return 1; } return 0; } /** * @public */ export function filterObject(_a, filterValue) { var property = _a.property, schema = _a.schema; return filterValue === '' || property.indexOf(filterValue) !== -1 || (!!schema.title && schema.title.indexOf(filterValue) !== -1) || (!!schema.description && schema.description.indexOf(filterValue) !== -1); } /** * @public */ export function filterArray(value, index, schema, filterValue) { var result = filterValue === '' || String(index).indexOf(filterValue) !== -1 || (schema.type === 'string' && value.indexOf(filterValue) !== -1) || ((schema.type === 'number' || schema.type === 'integer') && String(value).indexOf(filterValue) !== -1); if (result) { return true; } if (schema.type === 'object') { var title = getTitle(findTitleFromSchema(value, schema), schema.title); return title.indexOf(filterValue) !== -1; } return false; } /** * @public */ export var minItemCountIfNeedFilter = 6; /** * @public */ export function isRequired(required, value, schema, property) { /** * return true: required * return undefined: optional * return false: hidden */ if (required && required.some(function (r) { return r === property; })) { return true; } if (value && schema.properties[property]) { var requiredWhen = schema.properties[property].requiredWhen; if (requiredWhen) { var left = requiredWhen[0], operator = requiredWhen[1]; var right = requiredWhen[2]; if (schema.properties[left]) { if (operator === '===') { return value[left] === right; } if (operator === 'in') { return Array.isArray(right) && right.indexOf(value[left]) !== -1; } if (operator === 'isUndefined') { return value[left] === undefined; } } } var optionalWhen = schema.properties[property].optionalWhen; if (optionalWhen) { var left = optionalWhen[0], operator = optionalWhen[1]; var right = optionalWhen[2]; if (schema.properties[left]) { if (operator === '===') { return value[left] === right ? undefined : false; } if (operator === 'in') { return Array.isArray(right) && right.indexOf(value[left]) !== -1 ? undefined : false; } if (operator === 'isUndefined') { return value[left] === undefined ? undefined : false; } } } } return undefined; } /** * @public */ export function findContainer(childNodes) { for (var i = 0; i < childNodes.length; i++) { var node = childNodes[i]; if (node.nodeName === 'DIV') { return node; } } return undefined; } /** * @public */ export function getOptions(schema) { var enumTitles = schema.enumTitles || []; return schema.enum.map(function (e, i) { return ({ value: e, label: typeof enumTitles[i] === 'string' ? enumTitles[i] : e }); }); } /** * @public */ export function getNumberStep(schema) { if (schema.step !== undefined) { return schema.step; } return schema.type === 'number' ? 'any' : undefined; }