UNPKG

scrivito

Version:

Scrivito is a professional, yet easy to use SaaS Enterprise Content Management Service, built for digital agencies and medium to large businesses. It is completely maintenance-free, cost-effective, and has unprecedented performance and security.

308 lines (266 loc) 8.26 kB
import { AttributeJson, CustomAttributeJsonMapping, LinkJson, } from 'scrivito_sdk/client'; import { InternalError, assumePresence, deserializeAsDate, deserializeAsFloat, deserializeAsInteger, } from 'scrivito_sdk/common'; import { BasicLink, BasicLinkAttributes, Binary, CmsAttributeType, DataLocator, getObjIncludingUnavailableFrom, } from 'scrivito_sdk/models'; import { autoConvertToLink, autoConvertToLinklist, autoConvertToList, autoConvertToReference, autoConvertToReferencelist, autoConvertToSingle, } from 'scrivito_sdk/models/auto_convert'; import { ContentValueProvider } from 'scrivito_sdk/models/basic_attribute_content'; import { BasicAttributeValue, PlainAttributeValue, } from 'scrivito_sdk/models/basic_attribute_types'; import { objSpaceScopeExcludingDeleted } from 'scrivito_sdk/models/obj_space_scope_excluding_deleted'; import { BasicTypeInfo } from 'scrivito_sdk/models/type_info'; type BackendValue = AttributeJson | null | unknown; type BackendType = keyof CustomAttributeJsonMapping; export function deserialize<Type extends CmsAttributeType>( model: ContentValueProvider, value: BackendValue, typeInfo: BasicTypeInfo<Type>, ): BasicAttributeValue<Type>; export function deserialize( model: ContentValueProvider, value: BackendValue, typeInfo: BasicTypeInfo<CmsAttributeType>, ): BasicAttributeValue<(typeof typeInfo)[0]> { switch (typeInfo[0]) { case 'binary': { const binaryJson = deserializeValue(value, typeInfo); return binaryJson ? new Binary(binaryJson.id, model.objSpaceId()) : null; } case 'reference': { const refId = deserializeValue(value, typeInfo); return refId ? convertReference(refId, model) : null; } case 'referencelist': return deserializeValue(value, typeInfo).map((id) => convertReference(id, model), ); case 'widget': { const widgetId = deserializeValue(value, typeInfo); return widgetId ? model.widget(widgetId) : null; } case 'widgetlist': return deserializeValue(value, typeInfo).map((id) => // the backend keeps widgetlists and widget pool consistent // there should never be a 'missing' widget here. assumePresence(model.widget(id)), ); default: return deserializeValue(value, typeInfo); } } export function deserializeValue<Type extends CmsAttributeType>( value: BackendValue, typeInfo: BasicTypeInfo<Type>, ): PlainAttributeValue<Type>; export function deserializeValue( value: BackendValue, typeInfo: BasicTypeInfo<CmsAttributeType>, ) { switch (typeInfo[0]) { case 'binary': return deserializeBinaryValue(value); case 'boolean': return deserializeBooleanValue(value); case 'datalocator': return deserializeDataLocatorValue(value); case 'date': return deserializeDateValue(value); case 'datetime': return deserializeDateValue(value); case 'float': return deserializeFloatValue(autoConvertToSingle(value)); case 'enum': return deserializeEnumValue(autoConvertToSingle(value), typeInfo); case 'html': return deserializeHtmlOrStringValue(autoConvertToSingle(value)); case 'integer': return deserializeIntegerValue(autoConvertToSingle(value)); case 'link': return deserializeLinkValue(autoConvertToLink(value)); case 'linklist': return deserializeLinklistValue(autoConvertToLinklist(value)); case 'multienum': return deserializeMultienumValue(autoConvertToList(value), typeInfo); case 'reference': return deserializeReferenceValue(autoConvertToReference(value)); case 'referencelist': return deserializeReferencelistValue(autoConvertToReferencelist(value)); case 'string': return deserializeHtmlOrStringValue(autoConvertToSingle(value)); case 'stringlist': return deserializeStringlistValue(autoConvertToList(value)); case 'widget': return deserializeWidgetValue(value); case 'widgetlist': return deserializeWidgetlistValue(value); default: throw new InternalError(); } } function deserializeBinaryValue(value: BackendValue) { if (isBackendValueOfType('binary', value)) { return value[1]; } return null; } function deserializeBooleanValue(value: BackendValue) { if (isBackendValueOfType('boolean', value)) { return value[1]; } return false; } function deserializeDataLocatorValue(value: BackendValue) { if (isBackendValueOfType('datalocator', value)) { return new DataLocator(value[1] || { class: null }); } return new DataLocator({ class: null }); } function deserializeDateValue(value: BackendValue) { if (isBackendValueOfType('date', value)) { return deserializeAsDate(value[1]); } return null; } function deserializeHtmlOrStringValue(value: BackendValue) { if ( isBackendValueOfType('html', value) || isBackendValueOfType('string', value) ) { return value[1]; } return ''; } function deserializeEnumValue( value: BackendValue, typeInfo: BasicTypeInfo<'enum'>, ) { if (isBackendValueOfType('string', value)) { const [, valueFromBackend] = value; const [, { values }] = typeInfo; if (values.includes(valueFromBackend)) return valueFromBackend; } return null; } function deserializeMultienumValue( value: BackendValue, typeInfo: BasicTypeInfo<'multienum'>, ) { if (isBackendValueOfType('stringlist', value)) { const [, { values }] = typeInfo; return value[1].filter((item) => values.includes(item)); } return []; } function deserializeFloatValue(value: BackendValue) { if (isBackendValueOfType('number', value)) { return deserializeAsFloat(value[1].toString()); } if (isBackendValueOfType('string', value)) { const [, valueFromBackend] = value; if (valueFromBackend.match(/^-?\d+(\.\d+)?$/)) { return deserializeAsFloat(valueFromBackend); } } return null; } function deserializeIntegerValue(value: BackendValue) { if ( isBackendValueOfType('number', value) || isBackendValueOfType('string', value) ) { return deserializeAsInteger(value[1]); } return null; } function deserializeLinkValue(value: BackendValue) { if (isBackendValueOfType('link', value)) { return convertToLink(value[1]); } return null; } function deserializeLinklistValue(value: BackendValue) { if (isBackendValueOfType('linklist', value)) { return value[1].map(convertToLink); } return []; } function convertToLink(valueFromBackend: LinkJson) { const { query, rel, target, title, url } = valueFromBackend; const linkParams: BasicLinkAttributes = { query, rel, target, title, url }; if ('fragment' in valueFromBackend) { linkParams.hash = valueFromBackend.fragment; } if ('obj_id' in valueFromBackend) linkParams.objId = valueFromBackend.obj_id; return new BasicLink(linkParams); } function convertReference( valueFromBackend: string, model: ContentValueProvider, ) { return getObjIncludingUnavailableFrom( objSpaceScopeExcludingDeleted(model.objSpaceId()), valueFromBackend, ); } function deserializeReferenceValue(value: BackendValue) { if (isBackendValueOfType('reference', value)) { return value[1]; } return null; } function deserializeReferencelistValue(value: BackendValue) { if (isBackendValueOfType('referencelist', value)) { return value[1]; } return []; } function deserializeStringlistValue(value: BackendValue) { if (isBackendValueOfType('stringlist', value)) { return value[1]; } return []; } function deserializeWidgetValue(value: BackendValue) { if (isBackendValueOfType('widget', value)) return value[1]; if (isBackendValueOfType('widgetlist', value) && value[1].length > 0) { return value[1][0]; } return null; } function deserializeWidgetlistValue(value: BackendValue) { if (isBackendValueOfType('widgetlist', value)) return value[1]; if (isBackendValueOfType('widget', value) && value[1]) { return [value[1]]; } return []; } function isBackendValueOfType<Type extends BackendType>( type: Type, value: BackendValue, ): value is CustomAttributeJsonMapping[typeof type] { return Array.isArray(value) && value[0] === type; }