@stackbit/sdk
Version:
160 lines • 9.07 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.styleFieldPartialSchema = void 0;
const joi_1 = __importDefault(require("joi"));
const lodash_1 = __importDefault(require("lodash"));
const config_consts_1 = require("../config-consts");
const sizePattern = /^[xylrtb](?:\d+(?::\d+(?::\d+)?)?)?|\d+(?::\d+(?::\d+)?)?$/;
const sizeTailwindPattern = /^tw[xylrtb]?(?:\d+|\d\.5|px)?$/;
const styleSizeSchema = stylePropWithAll(joi_1.default.array()
.items(joi_1.default.string().pattern(sizePattern).meta({ errorDesc: 'size pattern' }))
.single(), joi_1.default.array()
.items(joi_1.default.string().pattern(sizeTailwindPattern).meta({ errorDesc: 'tailwind size pattern' }))
.single()).prefs({
messages: {
'string.pattern.base': 'Illegal definition "{{#value}}" of style field "{{#label}}". This field must match "padding" or "margin" style pattern'
},
errors: { wrap: { label: false } }
});
const anyRangePattern = /^\d+(?::\d+(?::\d+)?)?$/;
const borderWidthSchema = stylePropWithAll(joi_1.default.array().items(joi_1.default.string().pattern(anyRangePattern)).single()).prefs({
messages: {
'string.pattern.base': 'Illegal definition "{{#value}}" of style field "{{#label}}". This field must match "borderWidth" style pattern'
},
errors: { wrap: { label: false } }
});
const fontWeightPattern = /^[1-8]00:[2-9]00(?::\d+)?$/;
const opacityPattern = /^[1-9]?[05]:(?:5|[1-9][05]|100)$/;
const styleColorSchema = arrayOf(joi_1.default.object({
value: joi_1.default.string().required(),
label: joi_1.default.string().required(),
color: joi_1.default.string(),
styleObjectColor: joi_1.default.string()
}).xor('color', 'styleObjectColor'));
const stylePropsSchema = joi_1.default.object({
objectFit: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.objectFit),
objectPosition: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.nineRegions),
flexDirection: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.flexDirection),
justifyContent: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.justifyContent),
justifyItems: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.justifyItems),
justifySelf: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.justifySelf),
alignContent: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.alignContent),
alignItems: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.alignItems),
alignSelf: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.alignSelf),
padding: styleSizeSchema,
margin: styleSizeSchema,
width: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.width),
height: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.height),
fontFamily: arrayOf(joi_1.default.object({
value: joi_1.default.string().required(),
label: joi_1.default.string().required()
})),
fontSize: stylePropWithAll(joi_1.default.string().pattern(sizePattern), arrayOf(joi_1.default.string().pattern(sizePattern), joi_1.default.number().integer().min(0).multiple(1))),
fontStyle: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.fontStyle),
fontWeight: stylePropWithAll(joi_1.default.string().pattern(fontWeightPattern), arrayOf(joi_1.default.string().pattern(fontWeightPattern), joi_1.default.string().valid(...config_consts_1.STYLE_PROPS_VALUES.fontWeight))),
textAlign: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.textAlign),
textColor: styleColorSchema,
textDecoration: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.textDecoration),
backgroundColor: styleColorSchema,
backgroundPosition: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.nineRegions),
backgroundSize: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.backgroundSize),
borderRadius: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.borderRadius),
borderWidth: borderWidthSchema,
borderColor: styleColorSchema,
borderStyle: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.borderStyle),
boxShadow: arrayOfStringsWithAll(...config_consts_1.STYLE_PROPS_VALUES.boxShadow),
opacity: stylePropWithAll(joi_1.default.string().pattern(opacityPattern), arrayOf(joi_1.default.string().pattern(opacityPattern), joi_1.default.number().integer().min(0).max(100).multiple(5)))
});
const styleFieldNotFound = 'style.field.not.found';
exports.styleFieldPartialSchema = joi_1.default.object({
type: joi_1.default.string().valid('style').required(),
styles: joi_1.default.object()
.pattern(joi_1.default.string(), stylePropsSchema)
.custom((value, { error, state, errorsArray }) => {
const fields = lodash_1.default.nth(state.ancestors, 1);
const fieldsByName = lodash_1.default.keyBy(fields, 'name');
const errors = errorsArray();
lodash_1.default.forEach(value, (styleProps, fieldName) => {
if (fieldName !== 'self' && !lodash_1.default.has(fieldsByName, fieldName)) {
errors.push(error(styleFieldNotFound, { fieldName }));
return;
}
});
if (errors && errors.length) {
return errors;
}
return value;
})
.required()
.prefs({
messages: {
[styleFieldNotFound]: '{{#label}}.{{#fieldName}} does not match any model field name or the "self" keyword'
},
errors: { wrap: { label: false } }
})
});
function stylePropError(errors) {
return lodash_1.default.map(errors, (error) => {
if (!['alternatives.types', 'alternatives.match'].includes(error.code)) {
return error;
}
const stylePropSchema = lodash_1.default.head(lodash_1.default.get(error, 'state.schemas'));
const stylePropName = lodash_1.default.get(stylePropSchema, 'key');
const stylePropJoiSchema = lodash_1.default.get(stylePropSchema, 'schema');
if (!stylePropJoiSchema) {
return error;
}
const schemaDescription = stylePropJoiSchema.describe();
const matches = lodash_1.default.get(schemaDescription, 'matches');
const localTypes = lodash_1.default.reduce(matches, (localTypes, match) => {
const schema = lodash_1.default.get(match, 'schema');
const schemaType = lodash_1.default.get(schema, 'type');
if (schemaType === 'string') {
if (lodash_1.default.has(schema, 'allow')) {
const items = lodash_1.default.get(schema, 'allow', []);
localTypes.singleItems.push(...items.map((value) => `"${value}"`));
}
else if (lodash_1.default.has(schema, 'rules') && lodash_1.default.some(schema.rules, { name: 'pattern' })) {
localTypes.singleItems.push(`${stylePropName} pattern`);
}
}
else if (schemaType === 'array') {
const schemaItems = lodash_1.default.get(schema, 'items');
lodash_1.default.forEach(schemaItems, (schemaItem) => {
if (schemaItem.type === 'string') {
if (lodash_1.default.has(schemaItem, 'allow')) {
const items = lodash_1.default.get(schemaItem, 'allow', []);
localTypes.arrayItems.push(...items.map((value) => `"${value}"`));
}
else if (lodash_1.default.has(schemaItem, 'rules') && lodash_1.default.some(schemaItem.rules, { name: 'pattern' })) {
const errorDesc = lodash_1.default.get(schemaItem, ['metas', 0, 'errorDesc'], 'pattern');
localTypes.singleItems.push(`array of ${stylePropName} ${errorDesc}`);
}
}
else if (schemaItem.type === 'number') {
localTypes.singleItems.push(`array of valid ${stylePropName} numeric values`);
}
});
}
return localTypes;
}, { singleItems: [], arrayItems: [] });
error.code = 'alternatives.types';
lodash_1.default.set(error, 'local.types', [...localTypes.singleItems, ...(localTypes.arrayItems.length ? [`array of [${localTypes.arrayItems.join(', ')}]`] : [])]);
return error;
});
}
function arrayOfStringsWithAll(...values) {
return stylePropWithAll(arrayOf(joi_1.default.string().valid(...values)));
}
function stylePropWithAll(...items) {
return joi_1.default.alternatives()
.try(joi_1.default.string().valid('*'), ...items)
.error(stylePropError);
}
function arrayOf(...items) {
return joi_1.default.array().items(...items);
}
//# sourceMappingURL=style-field-schema.js.map