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.

231 lines (189 loc) 6.24 kB
import * as URI from 'urijs'; import { ViaRef } from 'scrivito_sdk/client'; import { ArgumentError, QueryParameters, parameterizeDataClass, throwNextTick, } from 'scrivito_sdk/common'; import { getDataClass, getDataClassOrThrow, } from 'scrivito_sdk/data_integration'; import { basicObjToDataContext } from 'scrivito_sdk/data_integration/basic_obj_to_data_context'; import { DataItem, DataItemPojo, DataScopePojo, itemPojoToScopePojo, } from 'scrivito_sdk/data_integration/data_class'; import { isValidDataId } from 'scrivito_sdk/data_integration/data_id'; import { DataStack, findItemInDataStack, findScopeInDataStack, } from 'scrivito_sdk/data_integration/data_stack'; import { ExternalDataItem } from 'scrivito_sdk/data_integration/external_data_class'; import { findItemInGlobalData, findScopeInGlobalData, } from 'scrivito_sdk/data_integration/global_data'; import { ObjDataItem } from 'scrivito_sdk/data_integration/obj_data_class'; import { loadWithDefault } from 'scrivito_sdk/loadable'; import { BasicLink, BasicObj, DataIdentifier, isValidDataIdentifier, } from 'scrivito_sdk/models'; export type DataContext = Record<DataIdentifier, DataContextValue>; export type DataContextValue = string; export type DataContextCallback = ( identifier: DataIdentifier ) => DataContextValue | undefined; function isValidDataContextValue( maybeValue: unknown ): maybeValue is DataContextValue | undefined { return typeof maybeValue === 'string' || maybeValue === undefined; } export function getDataContextQuery( objOrLink: BasicObj | BasicLink, dataStack: DataStack, query?: string ): string | undefined { const parameters = getDataContextParameters(objOrLink, dataStack); if (parameters) { return URI.buildQuery( query ? Object.assign(parameters, URI.parseQuery(query)) : parameters ); } return query; } interface DataContextParameters { [parameterName: string]: string; } export function getDataContextParameters( objOrLink: BasicObj | BasicLink, dataStack: DataStack ): DataContextParameters | undefined { if (dataStack.length === 0) return; const target = getObj(objOrLink); if (!target) return; let params: DataContextParameters = {}; [target, ...target.ancestors()].forEach((obj) => { const dataParam = obj?.dataParam(); if (!dataParam) return; const [dataClass] = dataParam; if (!dataClass) return; const itemElement = findItemInDataStack(dataClass, dataStack); params = { ...params, ...dataContextParamsForElement(itemElement, dataClass), }; }); if (Object.keys(params).length > 0) return params; } function dataContextParamsForElement( stackElement: DataItemPojo | undefined, dataClass: string ): DataContextParameters | undefined { if (stackElement && stackElement._class === dataClass) { return { [parameterizeDataClass(dataClass)]: stackElement._id, }; } } export function findItemElementInDataStackAndGlobalData( dataClassName: string, dataStack: DataStack ): DataItemPojo | undefined { return ( findItemInDataStack(dataClassName, dataStack) || findItemInGlobalData(dataClassName) ); } export function findScopeElementInDataStackAndGlobalData( dataClassName: string, dataStack: DataStack, viaRef: ViaRef ): DataScopePojo | undefined { if (viaRef === 'multi') { const scopePojo = findScopeInDataStack(dataClassName, dataStack); if (scopePojo) return scopePojo; } const itemPojo = findItemInDataStack(dataClassName, dataStack); if (itemPojo) return itemPojoToScopePojo(itemPojo); return findScopeInGlobalData(dataClassName); } export function dataContextFromQueryParams( obj: BasicObj, params: QueryParameters ): DataContext | 'loading' | 'unavailable' | undefined { const dataParam = obj.dataParam(); if (!dataParam) return; const [dataClassName] = dataParam; if (!dataClassName) return; const dataId = getDataId(dataClassName, params); if (!isValidDataId(dataId)) return 'unavailable'; const dataClass = getDataClass(dataClassName); if (!dataClass) return; const dataItem = loadWithDefault('loading', () => dataClass.get(dataId)); if (dataItem === 'loading') return 'loading'; if (!dataItem) return 'unavailable'; return dataItemToDataContext(dataItem); } export function dataItemToDataContext(dataItem: DataItem): DataContext { if (dataItem instanceof ObjDataItem) { return objDataItemToDataContext(dataItem); } // assumption: DataItem can only be either ObjDataItem or ExternalDataItem return externalDataItemToDataContext(dataItem as ExternalDataItem); } function objDataItemToDataContext(dataItem: ObjDataItem) { const basiObj = dataItem.getBasicObj(); return basiObj ? basicObjToDataContext(basiObj) : {}; } function externalDataItemToDataContext(dataItem: ExternalDataItem) { return { _class: dataItem.dataClassName(), _id: dataItem.id(), ...dataItem.getCustomAttributes(), }; } function getDataId(dataClassName: string, params: QueryParameters) { return ( getDataIdFromParams(dataClassName, params) || getDataIdOfFirstDataItem(dataClassName) ); } function getDataIdFromParams(dataClassName: string, params: QueryParameters) { const dataId = params[parameterizeDataClass(dataClassName)]; if (typeof dataId === 'string' && dataId.length > 0) return dataId; } function getDataIdOfFirstDataItem(dataClassName: string) { const [firstDataItem] = getDataClassOrThrow(dataClassName) .all() .transform({ limit: 1 }) .take(); if (firstDataItem) return firstDataItem.id(); } function getObj(objOrLink: BasicObj | BasicLink) { if (objOrLink instanceof BasicObj) return objOrLink; if (objOrLink.isInternal()) { const obj = objOrLink.obj(); if (obj instanceof BasicObj) return obj; } } export function getDataContextValue( identifier: DataIdentifier, context: DataContext ): DataContextValue | undefined { if (!isValidDataIdentifier(identifier)) return undefined; const value = context[identifier]; if (isValidDataContextValue(value)) return value; throwNextTick( new ArgumentError( `Expected a data context value to be a string or undefined, but got ${value}` ) ); }