@atlaskit/editor-plugin-extension
Version:
editor-plugin-extension plugin for @atlaskit/editor-core
93 lines (90 loc) • 3.81 kB
JavaScript
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))
};
}, {});
};