UNPKG

@progress/sitefinity-nextjs-sdk

Version:

Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.

313 lines (312 loc) 13.4 kB
import { RestSdkTypes, RestClient } from './rest-client'; import { RootUrlService } from './root-url.service'; export class ServiceMetadata { static serviceMetadataCache; static serviceMetadataHash; static taxonomies; static async fetch(metadataHash, traceContext) { if (!ServiceMetadata.serviceMetadataCache || metadataHash !== ServiceMetadata.serviceMetadataHash) { const serviceUrl = RootUrlService.getServerCmsServiceUrl(); const metadataUrl = `${serviceUrl}/sfmeta`; const metadata = await RestClient.sendRequest({ url: metadataUrl, traceContext }); ServiceMetadata.serviceMetadataCache = metadata; const taxonomies = await RestClient.getItems({ type: RestSdkTypes.Taxonomies, traceContext }); ServiceMetadata.taxonomies = taxonomies.Items; ServiceMetadata.serviceMetadataHash = metadataHash; } return ServiceMetadata.serviceMetadataCache; } static getDefaultFieldName(typeFullName) { const entitySet = this.getSetNameFromType(typeFullName); if (entitySet) { const entityTypeDef = this.getEntityDefinition(entitySet); const defaultFieldPropName = 'Telerik.Sitefinity.V1.DefaultField'; const propertiesPropName = 'properties'; if (entityTypeDef.hasOwnProperty(defaultFieldPropName)) { return entityTypeDef[defaultFieldPropName]; } else if (entityTypeDef.hasOwnProperty(propertiesPropName)) { const defaultFieldName = entityTypeDef[propertiesPropName][defaultFieldPropName]; if (defaultFieldName) { return defaultFieldName; } } } return 'Title'; } static getSetNameFromType(itemType) { const definition = ServiceMetadata.serviceMetadataCache.definitions[itemType]; if (definition != null) { const sets = ServiceMetadata.serviceMetadataCache.entityContainer.entitySets; const setName = Object.keys(sets).find((x) => { return sets[x]['entityType']['$ref'].endsWith(itemType); }); return setName; } return itemType; } static getModuleDisplayName(itemType) { const definition = ServiceMetadata.serviceMetadataCache.definitions[itemType]; if (definition) { const displayName = definition['properties']['Telerik.Sitefinity.V1.DisplayName']; return displayName; } return ''; } static getParentType(itemType) { const definition = ServiceMetadata.serviceMetadataCache.definitions[itemType]; if (definition != null) { const parent = definition['properties']['Parent']; if (parent != null) { const anyOfProperty = parent['anyOf']; if (anyOfProperty != null && anyOfProperty.length > 0) { let refProperty = anyOfProperty.find(x => x.$ref != null); if (refProperty != null) { return refProperty.$ref.replace('#/definitions/', ''); } } } } return null; } static getChildTypes(itemType) { const result = []; const definition = ServiceMetadata.serviceMetadataCache.definitions[itemType]; if (definition != null) { const childTypes = definition['properties']['Telerik.Sitefinity.V1.ChildTypes']; if (childTypes != null) { result.push(childTypes); childTypes.forEach(childType => { let grandChildTypes = this.getChildTypes(childType); for (let i = 0; i < grandChildTypes.length; i++) { let currentInheritanceLevel = result.at(i + 1); if (currentInheritanceLevel != null) { currentInheritanceLevel.push(...grandChildTypes[i]); } else { result.push(grandChildTypes[i]); } } }); } } return result; } static isPropertyACollection(type, propName) { let entityTypeDef = ServiceMetadata.serviceMetadataCache.definitions[type]; let propMeta = entityTypeDef['properties'][propName]; let propType = propMeta['type']; if (!propType) { return false; } if (Array.isArray(propType) || propType === 'array') { return true; } return false; } static getRelatedType(type, relationName) { const typeDefinition = ServiceMetadata.serviceMetadataCache.definitions[type]; let properties = typeDefinition['properties']; let property = properties[relationName]; if (typeof property !== 'object') { return null; } let relatedReferenceType = property['$ref']; if (relatedReferenceType == null) { let itemsProperty = property['items']; if (itemsProperty != null) { relatedReferenceType = itemsProperty['$ref']; } } if (relatedReferenceType == null) { let anyOfProperty = property['anyOf']; if (anyOfProperty && anyOfProperty.length > 0) { let relatedItemProperty = anyOfProperty.find(x => x['$ref'] != null); if (relatedItemProperty != null) { relatedReferenceType = relatedItemProperty['$ref']; } } } if (relatedReferenceType == null) { return null; } const foundEntity = Object.values(this.serviceMetadataCache.entityContainer.entitySets).some(x => x['entityType']['$ref'] === relatedReferenceType); if (foundEntity) { return relatedReferenceType.replace('#/definitions/', ''); } return null; } static getEntityDefinition(itemType) { const mainEntitySet = ServiceMetadata.serviceMetadataCache.entityContainer.entitySets[itemType]; if (!mainEntitySet) { throw new Error(`Could not find metadata for type ${itemType}`); } const entityTypeRef = mainEntitySet.entityType['$ref']; const entityTypeName = entityTypeRef.replace('#/definitions/', ''); const entityTypeDef = ServiceMetadata.serviceMetadataCache.definitions[entityTypeName]; return entityTypeDef; } static isRelatedProperty(type, propName) { return !!this.getRelatedType(type, propName); } static isPrimitiveProperty(type, propName) { const definition = ServiceMetadata.serviceMetadataCache.definitions[type]; let properties = definition['properties']; let property = properties[propName]; if (property == null) { throw new Error(`The field - ${propName} is not recognized as a property of the current type - ${type}`); } return (typeof property === 'object') && !this.isRelatedProperty(type, propName); } static serializeFilterValue(type, propName, value) { const definition = ServiceMetadata.serviceMetadataCache.definitions[type]; if (this.isPrimitiveProperty(type, propName)) { const propMeta = definition['properties'][propName]; const propType = propMeta['type']; const propFormat = propMeta['format']; let propFormatToString = null; if (propFormat != null) { propFormatToString = propFormat.toString(); } if (propType === null || propType === undefined) { return null; } const propTypeArray = propType; const propTypeString = propType.toString(); if (value === null) { if (propTypeArray != null && propTypeArray.some(x => x === 'null')) { return 'null'; } return null; } if (propTypeString === 'array') { if (propMeta.items && propMeta.items.format) { switch (propMeta.items.format) { case 'string': return `'${value}'`; default: return value.toString(); } } return null; } else if (propFormatToString === 'uuid') { return value.toString(); } else if (propFormatToString === 'date-time') { if (value instanceof Date) { return value.toISOString(); } else if (Date.parse(value)) { return new Date(Date.parse(value)).toISOString(); } return null; } else if (propTypeString === 'boolean' && value instanceof Boolean) { return value.toString(); } else if (propTypeArray != null && propType.length > 0) { if (propTypeArray.some(x => x.toString() === 'number') || propTypeArray.some(x => x.toString() === 'boolean')) { return value.ToString(); } else if (propTypeArray.some(x => x.toString() === 'string')) { return `'${value}'`; } } else if (value != null) { return value.ToString(); } } return null; } static getSimpleFields(type) { let definition = ServiceMetadata.serviceMetadataCache.definitions[type]; let propertiesObject = definition['properties']; return Object.keys(propertiesObject).map((key) => { if (this.isPrimitiveProperty(type, key)) { return key; } return null; }).filter(x => !!x); } static getRelationFields(type) { let definition = ServiceMetadata.serviceMetadataCache.definitions[type]; let propertiesObject = definition['properties']; return Object.keys(propertiesObject).map((key) => { if (this.isRelatedProperty(type, key)) { return key; } return null; }).filter(x => !!x); } static getTaxonomyFieldName(type, taxonomyName) { let definition = ServiceMetadata.serviceMetadataCache.definitions[type]; let propertiesObject = definition['properties']; return Object.keys(propertiesObject).find((key) => { const fieldMeta = propertiesObject[key]; return fieldMeta['Telerik.Sitefinity.V1.Taxonomy'] === taxonomyName; }); } static getFieldType(type, propName) { const definition = ServiceMetadata.serviceMetadataCache.definitions[type]; const propMeta = definition['properties'][propName]; const fieldType = propMeta['Telerik.Sitefinity.V1.FieldType']?.toString(); if (fieldType === 'ShortText' || fieldType === 'LongText') { return FieldType.TextField; } else if (fieldType === 'Choices' || fieldType === 'MultipleChoice') { return FieldType.ChoiceField; } else if (fieldType === 'Number') { return FieldType.NumberField; } const propFormat = propMeta['format']?.toString(); if (propFormat === 'date-time') { return FieldType.DatetimeField; } const propType = propMeta['type']; if (propType) { const propTypeNumberArray = Array.isArray(propType); if (propTypeNumberArray) { const propAsArray = propType; if (propAsArray.includes('number')) { return FieldType.NumberField; } else if (propAsArray.includes('boolean')) { return FieldType.BooleanField; } else if (propAsArray.includes('string')) { return FieldType.TextField; } } else { if (propType === 'integer') { return FieldType.NumberField; } else if (propType === 'boolean') { return FieldType.BooleanField; } else if (propType === 'string') { return FieldType.TextField; } } } let taxonomy = propMeta['Telerik.Sitefinity.V1.Taxonomy']; if (taxonomy && ServiceMetadata.taxonomies.find(x => x.Name === taxonomy)) { return FieldType.ClassificationField; } return FieldType.TextField; } } export var FieldType; (function (FieldType) { FieldType[FieldType["TextField"] = 0] = "TextField"; FieldType[FieldType["ChoiceField"] = 1] = "ChoiceField"; FieldType[FieldType["NumberField"] = 2] = "NumberField"; FieldType[FieldType["ClassificationField"] = 3] = "ClassificationField"; FieldType[FieldType["DatetimeField"] = 4] = "DatetimeField"; FieldType[FieldType["BooleanField"] = 5] = "BooleanField"; })(FieldType || (FieldType = {}));