UNPKG

@atlaskit/editor-plugin-extension

Version:

editor-plugin-extension plugin for @atlaskit/editor-core

93 lines (90 loc) 3.81 kB
import { isOptionsGrouped } from '@atlaskit/select'; import { ALLOWED_LOGGED_MACRO_PARAMS, ALLOWED_PARAM_TYPES } from './constants'; import { ValidationError } from './types'; export const validate = (field, value) => { return validateRequired(field, value); }; const isEmptyString = value => typeof value === 'string' && value === ''; const isEmptyArray = value => Array.isArray(value) && value.length === 0; const getUngroupedOptions = groupedOptions => { return groupedOptions.flatMap(option => option.options); }; export const validateRequired = ({ isRequired, isMultiple }, value) => { if (isRequired) { const isUndefined = typeof value === 'undefined'; const isEmpty = isEmptyString(value) || isMultiple && isEmptyArray(value) || false; return isUndefined || isEmpty ? ValidationError.Required : undefined; } return undefined; }; export const getOptionFromValue = (options, value) => { if (!Array.isArray(options) || options.length === 0) { return undefined; } if (Array.isArray(value)) { if (isOptionsGrouped(options)) { return getUngroupedOptions(options).filter(option => value.includes(option.value)); } return options.filter(option => value.includes(option.value)); } if (isOptionsGrouped(options)) { return getUngroupedOptions(options).find(option => value === option.value); } return options.find(option => value === option.value); }; // Atlaskit uses final-form to power the form. // Final-form will create nesting in the tree if a dot (.) is used in the name of the field. // A parent is provided from a <Fieldset /> and is appended to the name here for simplicity export const getSafeParentedName = (name, parentName) => { if (parentName && name.indexOf(`${parentName}.`) === -1) { return `${parentName}.${name}`; } return name; }; // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp const duplicateFieldRegex = /:[0-9]+$/; export const isDuplicateField = key => duplicateFieldRegex.test(key); export const getNameFromDuplicateField = key => key.replace(duplicateFieldRegex, ''); // An overly cautious parser for sanitizing configuration parameters of UGC export const parseParamType = (paramValue, paramField // eslint-disable-next-line @typescript-eslint/no-explicit-any ) => { if (paramValue && paramField) { if (paramField.type === 'string') { if (paramField.name === 'types') { // Parse types field as an array of valid content types const contentTypes = ['page', 'blogpost', 'comment', 'attachment']; return paramValue && paramValue.split(',').map(type => type.trim()).filter(type => contentTypes.includes(type)); } if (paramField.name === 'width') { return parseFloat(paramValue); } // Strings are very risky - return empty string in case anything slips through return ''; } if (ALLOWED_PARAM_TYPES.includes(paramField.type)) { // The param types defined here are already parsed and safe to log return paramValue; } } // Safety net return null; }; export const getLoggedParameters = (macroKey, currentParams, macroFields // eslint-disable-next-line @typescript-eslint/no-empty-object-type ) => { // Get the parameters only defined in the allowlist of logged macro/parameter keys return Object.keys(currentParams).filter(paramKey => { var _ALLOWED_LOGGED_MACRO; return (_ALLOWED_LOGGED_MACRO = ALLOWED_LOGGED_MACRO_PARAMS[macroKey]) === null || _ALLOWED_LOGGED_MACRO === void 0 ? void 0 : _ALLOWED_LOGGED_MACRO.includes(paramKey); }).reduce((obj, param) => { return { ...obj, [param]: parseParamType(currentParams[param], macroFields === null || macroFields === void 0 ? void 0 : macroFields.find(field => field.name === param)) }; }, {}); };