UNPKG

more-xrm

Version:

Create more applications using the Microsoft Dynamics Xrm platform, enables querying the dynamics data model from any application.

143 lines (142 loc) 7.27 kB
import { WebApiVersion } from "./Dynamics"; import { dynamicsBatch } from "./DynamicsBatch"; import { dynamicsRequest } from "./DynamicsRequest"; export default function dynamicsMetadata(accessToken) { return new DynamicsMetadataClient(accessToken); } export function isLookupAttribute(attribute) { return attribute.Type === 'Lookup' && attribute['LookupEntityName']; } export function isOptionSetAttribute(attribute) { return (attribute.Type === 'Picklist' || attribute.Type === 'State' || attribute.Type === 'Status') && attribute['PicklistOptions']; } const entityProperties = [ "Description", "DisplayName", "EntitySetName", "IconSmallName", "IsActivity", "IsCustomEntity", "LogicalName", "PrimaryIdAttribute", "PrimaryNameAttribute" ]; const attributeProperties = [ "AttributeType", "DisplayName", "IsCustomAttribute", "LogicalName", "SchemaName" ]; const ExcludedAttributeTypeFilters = [ 'Uniqueidentifier', 'CalendarRules', 'EntityName', 'ManagedProperty', 'Owner', 'Virtual', 'Lookup', 'Picklist', 'Status', 'State' ]; const ExcludedAttributeNameFilters = [ 'exchangerate', 'utcconversiontimezonecode', 'timezoneruleversionnumber', 'importsequencenumber', 'organizationid', 'transactioncurrencyid', 'versionnumber', 'createdonbehalfby', 'modifiedonbehalfby', 'overriddencreatedon', 'entityimage_timestamp' ]; class DynamicsMetadataClient { constructor(accessToken) { this.dynamicsHeaders = accessToken && { 'Authorization': 'Bearer ' + accessToken }; } attributes(entityName) { return dynamicsBatch(this.dynamicsHeaders) .requestAllUrls(this.getMetadataUrls(entityName, false)) .execute() .then(data => this.flatten(data) .filter((attribute) => attribute.LogicalName.indexOf('yomi') === -1 || attribute.LogicalName.indexOf('base') != attribute.LogicalName.length - 4) .map(DynamicsMetadataMapper.MapAttribute)); } entities() { return dynamicsRequest(`/api/data/${WebApiVersion}/EntityDefinitions?$select=EntitySetName,Description,DisplayName,LogicalName,PrimaryIdAttribute,PrimaryNameAttribute,IconSmallName,IsActivity,IsCustomEntity`, this.dynamicsHeaders) .then(data => data .map(entity => DynamicsMetadataMapper.MapEntity(entity))); } entity(entityName) { return dynamicsRequest(`/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')?$select=EntitySetName,Description,DisplayName,LogicalName,PrimaryIdAttribute,PrimaryNameAttribute,IconSmallName,IsActivity,IsCustomEntity`, this.dynamicsHeaders) .then(entity => this.attributes(entityName) .then(attributes => DynamicsMetadataMapper.MapEntity(entity, attributes))); } entityAttributes(...entityNames) { return dynamicsBatch(this.dynamicsHeaders) .requestAllUrls(this.flatten(entityNames.map(e => this.getMetadataUrls(e, true)))) .execute() .then(data => { const entities = []; const items = this.flatten(data); let currentEntity; for (const item of items) { if (item.EntitySetName) { currentEntity = DynamicsMetadataMapper.MapEntity(item); entities.push(currentEntity); } else if (item.LogicalName.indexOf('yomi') == -1 && item.LogicalName.indexOf('base') != item.LogicalName.length - 4) { currentEntity.Attributes.push(DynamicsMetadataMapper.MapAttribute(item)); } } return entities; }); } getMetadataUrls(entityName, includeEntity = false) { const attributeTypeFilter = ExcludedAttributeTypeFilters.map(v => `AttributeType ne Microsoft.Dynamics.CRM.AttributeTypeCode'${v}'`).join(' and '); const attributeNameFilter = ExcludedAttributeNameFilters.map(v => `LogicalName ne '${v}'`).join(' and '); return [ `/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')?$select=${entityProperties}`, `/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes?$select=${attributeProperties}&$filter=${attributeTypeFilter} and ${attributeNameFilter}`, `/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.LookupAttributeMetadata?$select=${attributeProperties},Targets`, `/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=${attributeProperties}&$expand=OptionSet($select=Options)`, `/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.StatusAttributeMetadata?$select=${attributeProperties}&$expand=OptionSet($select=Options)`, `/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.StateAttributeMetadata?$select=${attributeProperties}&$expand=OptionSet($select=Options)` ].slice(includeEntity ? 0 : 1); } flatten(values) { return [].concat(...values); } } class DynamicsMetadataMapper { static MapAttribute(attribute) { return { LogicalName: attribute.LogicalName, DisplayName: (attribute.DisplayName && attribute.DisplayName.UserLocalizedLabel && attribute.DisplayName.UserLocalizedLabel.Label) || attribute.LogicalName, Type: attribute.AttributeType, IsCustomAttribute: attribute.IsCustomAttribute, LookupEntityName: isLookup(attribute) && attribute.Targets[0], LookupSchemaName: isLookup(attribute) && attribute.SchemaName, PicklistOptions: isOptionSet(attribute) && attribute.OptionSet.Options.map((opt) => ({ Label: (opt.Label && opt.Label.UserLocalizedLabel && opt.Label.UserLocalizedLabel.Label), Value: opt.Value })) }; } static MapEntity(entity, attributes) { return { Description: (entity.Description && entity.Description.UserLocalizedLabel && entity.Description.UserLocalizedLabel.Label) || '', DisplayName: (entity.DisplayName && entity.DisplayName.UserLocalizedLabel && entity.DisplayName.UserLocalizedLabel.Label) || entity.LogicalName, EntitySetName: entity.EntitySetName, IconSmallName: entity.IconSmallName, IsActivity: entity.IsActivity, IsCustomEntity: entity.IsCustomEntity, LogicalName: entity.LogicalName, PrimaryIdAttribute: entity.PrimaryIdAttribute, PrimaryNameAttribute: entity.PrimaryNameAttribute, Attributes: attributes || [] }; } } function isLookup(attribute) { return Array.isArray(attribute['Targets']); } function isOptionSet(attribute) { return attribute['OptionSet'] && Array.isArray(attribute['OptionSet'].Options); }