Last active
February 8, 2019 13:56
Revisions
-
iwannabebot revised this gist
Feb 8, 2019 . 1 changed file with 1704 additions and 616 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,21 +1,8 @@ import { Observable } from "rxjs"; import { HttpClient, HttpHeaders } from "@angular/common/http"; // tslint:disable:no-bitwise // tslint:disable:max-line-length export class XrmMetaSdk { private _arrayElements = [ "Attributes", @@ -123,23 +110,23 @@ export class XrmMetaSdk { } else { const __this = _this; __this.RetrieveRelations( table.Id, entity => { const o2ms = entity.OneToManyRelationships; const m2os = entity.ManyToOneRelationships; const m2ms = entity.ManyToManyRelationships; subscriber.next(this.ParseRelations(table.Id, o2ms, m2os, m2ms)); subscriber.complete(); }, err => { subscriber.error(err); } ); } }); } private ParseTables(entities: XrmMetaEntity[]): IQueryTable[] { const tables = entities.map(entity => { return { Alias: "", @@ -163,12 +150,7 @@ export class XrmMetaSdk { Id: att.LogicalName, Name: this.readLabel(att), Table: tableId, OptionSet: this.readOption(att), Type: this.readAttributeType(att.AttributeType), Targets: att.Targets } as IQueryColumn; @@ -180,7 +162,7 @@ export class XrmMetaSdk { tableId: string, o2ms: XrmMetaOneToManyRelation[], m2os: XrmMetaOneToManyRelation[], m2ms: XrmMetaManyToManyRelation[] ): IQueryRelation[] { const relations: IQueryRelation[] = []; for (let i = 0; i < o2ms.length; i++) { @@ -239,82 +221,1316 @@ export class XrmMetaSdk { } return relations; } public GetOperatorsOfColumn(column: IQueryColumn): OperatorMap { const operators: OperatorMap = new OperatorMap(); switch (column.Type) { case QueryColumnType.Boolean: { operators.push( QueryOperatorType.Equal, QueryOperandInputType.TwoOptions ); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.TwoOptions ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); break; } case QueryColumnType.Customer: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Customer); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Customer ); operators.push( QueryOperatorType.In, QueryOperandInputType.CustomerMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.CustomerMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); break; } case QueryColumnType.DateTime: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.DateTime); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.DateTime ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.InFiscalPeriod, QueryOperandInputType.DateTimePe ); operators.push( QueryOperatorType.InFiscalPeriodAndYear, QueryOperandInputType.DateTimeFyPe ); operators.push( QueryOperatorType.InFiscalYear, QueryOperandInputType.DateTimeFy ); operators.push( QueryOperatorType.InOrAfterFiscalPeriodAndYear, QueryOperandInputType.DateTimeFyPe ); operators.push( QueryOperatorType.InOrBeforeFiscalPeriodAndYear, QueryOperandInputType.DateTimeFyPe ); operators.push(QueryOperatorType.Last7Days, QueryOperandInputType.None); operators.push( QueryOperatorType.LastFiscalPeriod, QueryOperandInputType.None ); operators.push( QueryOperatorType.LastFiscalYear, QueryOperandInputType.None ); operators.push(QueryOperatorType.LastMonth, QueryOperandInputType.None); operators.push(QueryOperatorType.LastWeek, QueryOperandInputType.None); operators.push( QueryOperatorType.LastXDays, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LastXFiscalPeriods, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LastXFiscalYears, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LastXHours, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LastXMonths, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LastXWeeks, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LastXYears, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LastYear, QueryOperandInputType.Integer ); operators.push(QueryOperatorType.Next7Days, QueryOperandInputType.None); operators.push( QueryOperatorType.NextFiscalPeriod, QueryOperandInputType.None ); operators.push( QueryOperatorType.NextFiscalYear, QueryOperandInputType.None ); operators.push(QueryOperatorType.NextMonth, QueryOperandInputType.None); operators.push(QueryOperatorType.NextWeek, QueryOperandInputType.None); operators.push( QueryOperatorType.NextXDays, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.NextXFiscalPeriods, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.NextXFiscalYears, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.NextXHours, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.NextXMonths, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.NextXWeeks, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.NextXYears, QueryOperandInputType.Integer ); operators.push(QueryOperatorType.NextYear, QueryOperandInputType.None); operators.push( QueryOperatorType.OlderThanXYears, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.OlderThanXMonths, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.OlderThanXWeeks, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.OlderThanXDays, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.OlderThanXHours, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.OlderThanXMinutes, QueryOperandInputType.Integer ); operators.push(QueryOperatorType.On, QueryOperandInputType.DateTime); operators.push( QueryOperatorType.OnOrAfter, QueryOperandInputType.DateTime ); operators.push( QueryOperatorType.OnOrBefore, QueryOperandInputType.DateTime ); operators.push( QueryOperatorType.ThisFiscalPeriod, QueryOperandInputType.None ); operators.push( QueryOperatorType.ThisFiscalYear, QueryOperandInputType.None ); operators.push(QueryOperatorType.ThisMonth, QueryOperandInputType.None); operators.push(QueryOperatorType.ThisWeek, QueryOperandInputType.None); operators.push(QueryOperatorType.ThisYear, QueryOperandInputType.None); operators.push(QueryOperatorType.Today, QueryOperandInputType.None); operators.push(QueryOperatorType.Tomorrow, QueryOperandInputType.None); operators.push(QueryOperatorType.Yesterday, QueryOperandInputType.None); operators.push(QueryOperatorType.NotOn, QueryOperandInputType.DateTime); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.DateTime ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.DateTime ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.DateTime ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.DateTime ); break; } case QueryColumnType.Decimal: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Decimal); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Decimal ); operators.push( QueryOperatorType.In, QueryOperandInputType.DecimalMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.DecimalMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.DecimalRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.DecimalRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.Decimal ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.Decimal ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.Decimal ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.Decimal ); break; } case QueryColumnType.Double: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Double); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Double ); operators.push( QueryOperatorType.In, QueryOperandInputType.DoubleMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.DoubleMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.DoubleRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.DoubleRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.Double ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.Double ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.Double ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.Double ); break; } case QueryColumnType.Integer: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Integer); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.In, QueryOperandInputType.IntegerMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.IntegerMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.Integer ); break; } case QueryColumnType.Lookup: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Lookup); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Lookup ); operators.push( QueryOperatorType.In, QueryOperandInputType.LookupMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.LookupMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); break; } case QueryColumnType.Memo: { operators.push( QueryOperatorType.Equal, QueryOperandInputType.Paragraph ); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Paragraph ); operators.push( QueryOperatorType.In, QueryOperandInputType.StringMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.StringMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.Paragraph ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.Paragraph ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.Paragraph ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.Paragraph ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.Paragraph ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.Paragraph ); operators.push(QueryOperatorType.Like, QueryOperandInputType.Paragraph); operators.push( QueryOperatorType.NotLike, QueryOperandInputType.Paragraph ); break; } case QueryColumnType.Money: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Decimal); operators.push(QueryOperatorType.NotEqual, QueryOperandInputType.Decimal); operators.push( QueryOperatorType.In, QueryOperandInputType.DecimalMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.DecimalMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.DecimalRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.DecimalRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.Decimal ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.Decimal ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.Decimal ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.Decimal ); break; } case QueryColumnType.Owner: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Owner); operators.push(QueryOperatorType.NotEqual, QueryOperandInputType.Owner); operators.push( QueryOperatorType.In, QueryOperandInputType.OwnerMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.OwnerMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.EqualUserId, QueryOperandInputType.User ); operators.push( QueryOperatorType.NotEqualUserId, QueryOperandInputType.User ); operators.push( QueryOperatorType.EqualUserOrUserHierarchy, QueryOperandInputType.User ); operators.push( QueryOperatorType.EqualUserOrUserHierarchyAndTeams, QueryOperandInputType.UserTeamMultiple ); operators.push( QueryOperatorType.EqualUserOrUserTeams, QueryOperandInputType.UserTeamMultiple ); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); break; } case QueryColumnType.PartyList: { operators.push( QueryOperatorType.Equal, QueryOperandInputType.PartyList ); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.PartyList ); operators.push( QueryOperatorType.In, QueryOperandInputType.PartyListMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.PartyListMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); break; } case QueryColumnType.Picklist: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Options); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Options ); operators.push( QueryOperatorType.In, QueryOperandInputType.OptionsMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.OptionsMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.Integer ); break; } case QueryColumnType.State: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Options); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Options ); operators.push( QueryOperatorType.In, QueryOperandInputType.OptionsMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.OptionsMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.Integer ); break; } case QueryColumnType.Status: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Options); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Options ); operators.push( QueryOperatorType.In, QueryOperandInputType.OptionsMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.OptionsMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.IntegerRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.Integer ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.Integer ); break; } case QueryColumnType.String: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.String); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.String ); operators.push( QueryOperatorType.In, QueryOperandInputType.StringMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.StringMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); break; } case QueryColumnType.Uniqueidentifier: { operators.push(QueryOperatorType.Equal, QueryOperandInputType.Lookup); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.Lookup ); operators.push( QueryOperatorType.In, QueryOperandInputType.LookupMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.LookupMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push(QueryOperatorType.Above, QueryOperandInputType.Lookup); operators.push( QueryOperatorType.AboveOrEqual, QueryOperandInputType.Lookup ); operators.push(QueryOperatorType.Under, QueryOperandInputType.Lookup); operators.push( QueryOperatorType.UnderOrEqual, QueryOperandInputType.Lookup ); operators.push( QueryOperatorType.NotUnder, QueryOperandInputType.Lookup ); operators.push( QueryOperatorType.EqualBusinessId, QueryOperandInputType.Lookup ); operators.push( QueryOperatorType.EqualUserId, QueryOperandInputType.Lookup ); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); break; } case QueryColumnType.CalendarRules: { operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); break; } case QueryColumnType.Virtual: { break; } case QueryColumnType.BigInt: { operators.push( QueryOperatorType.Equal, QueryOperandInputType.BigInteger ); operators.push( QueryOperatorType.NotEqual, QueryOperandInputType.BigInteger ); operators.push( QueryOperatorType.In, QueryOperandInputType.BigIntegerMultiple ); operators.push( QueryOperatorType.NotIn, QueryOperandInputType.BigIntegerMultiple ); operators.push(QueryOperatorType.Null, QueryOperandInputType.None); operators.push(QueryOperatorType.NotNull, QueryOperandInputType.None); operators.push( QueryOperatorType.BeginsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotBeginWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.Contains, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotContain, QueryOperandInputType.String ); operators.push( QueryOperatorType.EndsWith, QueryOperandInputType.String ); operators.push( QueryOperatorType.DoesNotEndWith, QueryOperandInputType.String ); operators.push(QueryOperatorType.Like, QueryOperandInputType.String); operators.push(QueryOperatorType.NotLike, QueryOperandInputType.String); operators.push( QueryOperatorType.Between, QueryOperandInputType.BigIntegerRange ); operators.push( QueryOperatorType.NotBetween, QueryOperandInputType.BigIntegerRange ); operators.push( QueryOperatorType.GreaterThan, QueryOperandInputType.BigInteger ); operators.push( QueryOperatorType.GreaterEqual, QueryOperandInputType.BigInteger ); operators.push( QueryOperatorType.LessThan, QueryOperandInputType.BigInteger ); operators.push( QueryOperatorType.LessEqual, QueryOperandInputType.BigInteger ); break; } case QueryColumnType.ManagedProperty: { break; } case QueryColumnType.EntityName: { break; } } return operators; } public GetInputParentType(inputType: QueryOperandInputType): QueryOperandType { switch (inputType) { case QueryOperandInputType.Integer: case QueryOperandInputType.IntegerMultiple: case QueryOperandInputType.IntegerRange: case QueryOperandInputType.BigInteger: case QueryOperandInputType.BigIntegerMultiple: case QueryOperandInputType.BigIntegerRange: case QueryOperandInputType.Decimal: case QueryOperandInputType.DecimalMultiple: case QueryOperandInputType.DecimalRange: case QueryOperandInputType.Double: case QueryOperandInputType.DoubleMultiple: case QueryOperandInputType.DoubleRange: return QueryOperandType.Number; case QueryOperandInputType.String: case QueryOperandInputType.StringMultiple: case QueryOperandInputType.Paragraph: return QueryOperandType.String; case QueryOperandInputType.DateTime: case QueryOperandInputType.DateTimeFy: case QueryOperandInputType.DateTimePe: case QueryOperandInputType.DateTimeFyPe: return QueryOperandType.DateTime; case QueryOperandInputType.Lookup: case QueryOperandInputType.LookupMultiple: case QueryOperandInputType.Customer: case QueryOperandInputType.CustomerMultiple: case QueryOperandInputType.Owner: case QueryOperandInputType.OwnerMultiple: case QueryOperandInputType.PartyList: case QueryOperandInputType.PartyListMultiple: case QueryOperandInputType.User: case QueryOperandInputType.UserTeam: case QueryOperandInputType.UserTeamMultiple: return QueryOperandType.Lookup; case QueryOperandInputType.TwoOptions: { return QueryOperandType.TwoOptions; } case QueryOperandInputType.Options: case QueryOperandInputType.OptionsMultiple: return QueryOperandType.Options; default: { return QueryOperandType.None; } } } //#region helpers private readLabel(metaRecord: any): string { try { const disp = metaRecord.DisplayName as DisplayName; return disp.UserLocalizedLabel.Label; } catch { let label = null; for (let i = 0; i < metaRecord.DisplayName.LocalizedLabels.length; i++) { if (metaRecord.DisplayName.LocalizedLabels[i].LanguageCode === 1033) { label = metaRecord.DisplayName.LocalizedLabels[i].Label; } } if (label === null) { if (metaRecord.DisplayName.LocalizedLabels.length > 0) { label = metaRecord.DisplayName.LocalizedLabels[0].Label; } else { label = metaRecord.LogicalName; } } return label; } } private readOption(att: XrmMetaAttribute): IQueryOption[] { try { return att.OptionSet.Options.map(op => { return { Key: this.readOptionLabel(op), Value: op.Value } as IQueryOption; }); } catch { return []; } } private readOptionLabel(metaRecord: any): string { try { const disp = metaRecord.DisplayName as DisplayName; return disp.UserLocalizedLabel.Label; } catch { let label = null; for (let i = 0; i < metaRecord.Label.LocalizedLabels.length; i++) { if (metaRecord.Label.LocalizedLabels[i].LanguageCode === 1033) { label = metaRecord.Label.LocalizedLabels[i].Label; } } if (label === null) { if (metaRecord.Label.LocalizedLabels.length > 0) { label = metaRecord.Label.LocalizedLabels[0].Label; } else { label = "Option #"; } } return label; } } private readAttributeType(type: string): QueryColumnType { switch (type) { case "Lookup": { return QueryColumnType.Lookup; } case "State": { return QueryColumnType.State; } case "Memo": { return QueryColumnType.Memo; } case "Boolean": { return QueryColumnType.Boolean; } case "String": { return QueryColumnType.String; } case "Integer": { return QueryColumnType.Integer; } case "DateTime": { return QueryColumnType.DateTime; } case "Status": { return QueryColumnType.Status; } case "Uniqueidentifier": { return QueryColumnType.Uniqueidentifier; } case "Picklist": { return QueryColumnType.Picklist; @@ -369,371 +1585,31 @@ export class XrmMetaSdk { return this.clientUrl || window.location.hostname; } //#endregion //#region internals private RetrieveAllEntities( successCallBack, errorCallBack ) { const _this = this; if (typeof successCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveAllEntities successCallBack must be a function." ); } if (typeof errorCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveAllEntities errorCallBack must be a function." ); } const entityFiltersValue = this._evaluateEntityFilters(1); const request = [ '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">', // Allows retrieval if ImageAttributeMetadata objects '<soapenv:Header><a:SdkClientVersion xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">7.0</a:SdkClientVersion></soapenv:Header>', "<soapenv:Body>", '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">', @@ -742,13 +1618,13 @@ export class XrmMetaSdk { "<a:KeyValuePairOfstringanyType>", "<b:key>EntityFilters</b:key>", '<b:value i:type="c:EntityFilters" xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata">' + _this._xmlEncode(entityFiltersValue) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>RetrieveAsIfPublished</b:key>", '<b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this._xmlEncode(true.toString()) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "</a:Parameters>", @@ -762,50 +1638,53 @@ export class XrmMetaSdk { const req = new XMLHttpRequest(); req.open( "POST", _this.getUrl() + "/XRMServices/2011/Organization.svc/web", true ); try { req.responseType = "msxml-document" as any; } catch (e) {} req.setRequestHeader("Accept", "application/xml, text/xml, */*"); req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); req.setRequestHeader( "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute" ); req.onreadystatechange = function() { const __this = _this; if (req.readyState === 4 /* complete */) { req.onreadystatechange = null; // Addresses potential memory leak issue with IE if (req.status === 200) { // Success const doc = req.responseXML; try { __this._setSelectionNamespaces(doc); } catch (e) {} const entityMetadataNodes = __this._selectNodes(doc, "//c:EntityMetadata"); const entityMetadataCollection: XrmMetaEntity[] = []; for (let i = 0; i < entityMetadataNodes.length; i++) { const a = __this._objectifyNode(entityMetadataNodes[i]); a._type = "EntityMetadata"; entityMetadataCollection.push(a); } successCallBack(entityMetadataCollection); } else { errorCallBack(__this._getError(req)); } } }; req.send(request); } private RetrieveAttributes( LogicalName, successCallBack, errorCallBack ) { let MetadataId = null; const _this = this; if (LogicalName == null && MetadataId == null) { throw new Error( "SDK.Metadata.RetrieveEntity requires either the LogicalName or MetadataId parameter not be null." ); @@ -835,15 +1714,15 @@ export class XrmMetaSdk { "SDK.Metadata.RetrieveEntity errorCallBack must be a function." ); } const entityFiltersValue = _this._evaluateEntityFilters(2); let entityLogicalNameValueNode = ""; if (LogicalName == null) { entityLogicalNameValueNode = '<b:value i:nil="true" />'; } else { entityLogicalNameValueNode = '<b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this._xmlEncode(LogicalName.toLowerCase()) + "</b:value>"; } const request = [ @@ -857,19 +1736,19 @@ export class XrmMetaSdk { "<a:KeyValuePairOfstringanyType>", "<b:key>EntityFilters</b:key>", '<b:value i:type="c:EntityFilters" xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata">' + _this._xmlEncode(entityFiltersValue) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>MetadataId</b:key>", '<b:value i:type="ser:guid" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">' + _this._xmlEncode(MetadataId) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>RetrieveAsIfPublished</b:key>", '<b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this._xmlEncode(true.toString()) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", @@ -887,34 +1766,33 @@ export class XrmMetaSdk { const req = new XMLHttpRequest(); req.open( "POST", _this.getUrl() + "/XRMServices/2011/Organization.svc/web", true ); try { req.responseType = "msxml-document" as any; } catch (e) {} req.setRequestHeader("Accept", "application/xml, text/xml, */*"); req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); req.setRequestHeader( "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute" ); req.onreadystatechange = function() { const __this = _this; if (req.readyState === 4 /* complete */) { req.onreadystatechange = null; // Addresses potential memory leak issue with IE if (req.status === 200) { const doc = req.responseXML; try { __this._setSelectionNamespaces(doc); } catch (e) {} const a: XrmMetaEntity = __this._objectifyNode(__this._selectSingleNode(doc, "//b:value")); a._type = "EntityMetadata"; successCallBack(a.Attributes); } else { // Failure errorCallBack(__this._getError(req)); } } }; @@ -923,10 +1801,10 @@ export class XrmMetaSdk { private RetrieveRelations( LogicalName, successCallBack, errorCallBack ) { let MetadataId = null; const _this = this; if (LogicalName == null && MetadataId == null) { throw new Error( @@ -958,16 +1836,15 @@ export class XrmMetaSdk { "SDK.Metadata.RetrieveEntity errorCallBack must be a function." ); } const entityFiltersValue = _this._evaluateEntityFilters(8); let entityLogicalNameValueNode = ""; if (LogicalName == null) { entityLogicalNameValueNode = '<b:value i:nil="true" />'; } else { entityLogicalNameValueNode = '<b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this._xmlEncode(LogicalName.toLowerCase()) + "</b:value>"; } const request = [ @@ -981,19 +1858,19 @@ export class XrmMetaSdk { "<a:KeyValuePairOfstringanyType>", "<b:key>EntityFilters</b:key>", '<b:value i:type="c:EntityFilters" xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata">' + _this._xmlEncode(entityFiltersValue) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>MetadataId</b:key>", '<b:value i:type="ser:guid" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">' + _this._xmlEncode(MetadataId) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>RetrieveAsIfPublished</b:key>", '<b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this._xmlEncode(true.toString()) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", @@ -1011,186 +1888,397 @@ export class XrmMetaSdk { const req = new XMLHttpRequest(); req.open( "POST", _this.getUrl() + "/XRMServices/2011/Organization.svc/web", true ); try { req.responseType = "msxml-document" as any; } catch (e) {} req.setRequestHeader("Accept", "application/xml, text/xml, */*"); req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); req.setRequestHeader( "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute" ); req.onreadystatechange = function() { const __this = _this; if (req.readyState === 4 /* complete */) { req.onreadystatechange = null; // Addresses potential memory leak issue with IE if (req.status === 200) { const doc = req.responseXML; try { __this._setSelectionNamespaces(doc); } catch (e) {} const a: XrmMetaEntity = __this._objectifyNode(__this._selectSingleNode(doc, "//b:value")); a._type = "EntityMetadata"; successCallBack(a); } else { // Failure errorCallBack(__this._getError(req)); } } }; req.send(request); } private _getError(resp) { const _this = this; if (resp.status === 12029) { return new Error("The attempt to connect to the server failed."); } if (resp.status === 12007) { return new Error("The server name could not be resolved."); } const faultXml = resp.responseXML; let errorMessage = "Unknown (unable to parse the fault)"; let faultstring = null; let ErrorCode = null; if (typeof faultXml === "object") { const bodyNode = faultXml.firstChild.firstChild; // Retrieve the fault node for (let i = 0; i < bodyNode.childNodes.length; i++) { const node = bodyNode.childNodes[i]; // NOTE: This comparison does not handle the case where the XML namespace changes if ("s:Fault" === node.nodeName) { for (let j = 0; j < node.childNodes.length; j++) { const testNode = node.childNodes[j]; if ("faultstring" === testNode.nodeName) { faultstring = _this._getNodeText(testNode); } if ("detail" === testNode.nodeName) { for (let k = 0; k < testNode.childNodes.length; k++) { const orgServiceFault = testNode.childNodes[k]; if ("OrganizationServiceFault" === orgServiceFault.nodeName) { for (let l = 0; l < orgServiceFault.childNodes.length; l++) { const ErrorCodeNode = orgServiceFault.childNodes[l]; if ("ErrorCode" === ErrorCodeNode.nodeName) { ErrorCode = _this._getNodeText(ErrorCodeNode); break; } } } } } } break; } } } if (ErrorCode != null && faultstring != null) { errorMessage = "Error Code:" + ErrorCode + " Message: " + faultstring; } else { if (faultstring != null) { errorMessage = faultstring; } } return new Error(errorMessage); } private _evaluateEntityFilters(EntityFilters) { const entityFilterArray = []; if ((1 & EntityFilters) === 1) { entityFilterArray.push("Entity"); } if ((2 & EntityFilters) === 2) { entityFilterArray.push("Attributes"); } if ((4 & EntityFilters) === 4) { entityFilterArray.push("Privileges"); } if ((8 & EntityFilters) === 8) { entityFilterArray.push("Relationships"); } return entityFilterArray.join(" "); } private _isMetadataArray(elementName) { const _this = this; for (let i = 0; i < _this._arrayElements.length; i++) { if (elementName === _this._arrayElements[i]) { return true; } } return false; } private _objectifyNode(node) { const _this = this; // Check for null if (node.attributes != null && node.attributes.length === 1) { if ( node.attributes.getNamedItem("i:nil") != null && node.attributes.getNamedItem("i:nil").nodeValue === "true" ) { return null; } } // Check if it is a value if (node.firstChild != null && node.firstChild.nodeType === 3) { const nodeName = _this._getNodeName(node); switch (nodeName) { // Integer Values case "ActivityTypeMask": case "ObjectTypeCode": case "ColumnNumber": case "DefaultFormValue": case "MaxValue": case "MinValue": case "MaxLength": case "Order": case "Precision": case "PrecisionSource": case "LanguageCode": return parseInt(node.firstChild.nodeValue, 10); // Boolean values case "AutoRouteToOwnerQueue": case "CanBeChanged": case "CanTriggerWorkflow": case "IsActivity": case "IsAIRUpdated": case "IsActivityParty": case "IsAvailableOffline": case "IsChildEntity": case "IsCustomEntity": case "IsCustomOptionSet": case "IsDocumentManagementEnabled": case "IsEnabledForCharts": case "IsGlobal": case "IsImportable": case "IsIntersect": case "IsManaged": case "IsReadingPaneEnabled": case "IsValidForAdvancedFind": case "CanBeSecuredForCreate": case "CanBeSecuredForRead": case "CanBeSecuredForUpdate": case "IsCustomAttribute": case "IsManaged": case "IsPrimaryId": case "IsPrimaryName": case "IsSecured": case "IsValidForCreate": case "IsValidForRead": case "IsValidForUpdate": case "IsCustomRelationship": case "CanBeBasic": case "CanBeDeep": case "CanBeGlobal": case "CanBeLocal": return node.firstChild.nodeValue === "true" ? true : false; // OptionMetadata.Value and BooleanManagedProperty.Value and AttributeRequiredLevelManagedProperty.Value case "Value": // BooleanManagedProperty.Value if ( node.firstChild.nodeValue === "true" || node.firstChild.nodeValue === "false" ) { return node.firstChild.nodeValue === "true" ? true : false; } // AttributeRequiredLevelManagedProperty.Value if ( node.firstChild.nodeValue === "ApplicationRequired" || node.firstChild.nodeValue === "None" || node.firstChild.nodeValue === "Recommended" || node.firstChild.nodeValue === "SystemRequired" ) { return node.firstChild.nodeValue; } const numberValue = parseInt(node.firstChild.nodeValue, 10); if (isNaN(numberValue)) { // FormatName.Value return node.firstChild.nodeValue; } else { // OptionMetadata.Value return numberValue; } break; // String values default: return node.firstChild.nodeValue; } } // Check if it is a known array if (_this._isMetadataArray(_this._getNodeName(node))) { const arrayValue = []; for (let i = 0; i < node.childNodes.length; i++) { let objectTypeName; if ( node.childNodes[i].attributes != null && node.childNodes[i].attributes.getNamedItem("i:type") != null ) { objectTypeName = node.childNodes[i].attributes .getNamedItem("i:type") .nodeValue.split(":")[1]; } else { objectTypeName = _this._getNodeName(node.childNodes[i]); } const b = _this._objectifyNode(node.childNodes[i]); b._type = objectTypeName; arrayValue.push(b); } return arrayValue; } // Null entity description labels are returned as <label/> - not using i:nil = true; if (node.childNodes.length === 0) { return null; } // Otherwise return an object const c: any = {}; if (node.attributes.getNamedItem("i:type") != null) { c._type = node.attributes.getNamedItem("i:type").nodeValue.split(":")[1]; } for (let i = 0; i < node.childNodes.length; i++) { if (node.childNodes[i].nodeType === 3) { c[_this._getNodeName(node.childNodes[i])] = node.childNodes[i].nodeValue; } else { c[_this._getNodeName(node.childNodes[i])] = _this._objectifyNode( node.childNodes[i] ); } } return c; } private _selectNodes(node, XPathExpression) { const _this = this; if (typeof node.selectNodes !== "undefined") { return node.selectNodes(XPathExpression); } else { const output = []; const XPathResults = node.evaluate( XPathExpression, node, _this._NSResolver, XPathResult.ANY_TYPE, null ); let result = XPathResults.iterateNext(); while (result) { output.push(result); result = XPathResults.iterateNext(); } return output; } } private _selectSingleNode(node, xpathExpr) { const _this = this; if (typeof node.selectSingleNode !== "undefined") { return node.selectSingleNode(xpathExpr); } else { const xpe = new XPathEvaluator(); const xPathNode = xpe.evaluate( xpathExpr, node, _this._NSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null ); return xPathNode != null ? xPathNode.singleNodeValue : null; } } private _selectSingleNodeText(node, xpathExpr) { const _this = this; const x = _this._selectSingleNode(node, xpathExpr); if (_this._isNodeNull(x)) { return null; } if (typeof x.text !== "undefined") { return x.text; } else { return x.textContent; } } private _getNodeText(node) { if (typeof node.text !== "undefined") { return node.text; } else { return node.textContent; } } private _isNodeNull(node) { if (node == null) { return true; } if ( node.attributes.getNamedItem("i:nil") != null && node.attributes.getNamedItem("i:nil").value === "true" ) { return true; } return false; } private _getNodeName(node) { if (typeof node.baseName !== "undefined") { return node.baseName; } else { return node.localName; } } private _setSelectionNamespaces(doc) { const namespaces = [ "xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'", "xmlns:a='http://schemas.microsoft.com/xrm/2011/Contracts'", "xmlns:i='http://www.w3.org/2001/XMLSchema-instance'", "xmlns:b='http://schemas.datacontract.org/2004/07/System.Collections.Generic'", "xmlns:c='http://schemas.microsoft.com/xrm/2011/Metadata'" ]; doc.setProperty("SelectionNamespaces", namespaces.join(" ")); } private _NSResolver(prefix) { const ns = { s: "http://schemas.xmlsoap.org/soap/envelope/", a: "http://schemas.microsoft.com/xrm/2011/Contracts", i: "http://www.w3.org/2001/XMLSchema-instance", b: "http://schemas.datacontract.org/2004/07/System.Collections.Generic", c: "http://schemas.microsoft.com/xrm/2011/Metadata" }; return ns[prefix] || null; } private _xmlEncode(strInput) { let c; let XmlEncode = ""; if (strInput == null) { return null; } if (strInput === "") { return ""; } for (let cnt = 0; cnt < strInput.length; cnt++) { c = strInput.charCodeAt(cnt); if ( (c > 96 && c < 123) || (c > 64 && c < 91) || c === 32 || (c > 47 && c < 58) || c === 46 || c === 44 || c === 45 || c === 95 ) { XmlEncode = XmlEncode + String.fromCharCode(c); } else { XmlEncode = XmlEncode + "&#" + c + ";"; } } return XmlEncode; } //#endregion } -
iwannabebot revised this gist
Feb 8, 2019 . No changes.There are no files selected for viewing
-
iwannabebot created this gist
Feb 8, 2019 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,217 @@ export interface XrmMetaAttribute { LogicalName: string; MetadataId: string; DisplayName: DisplayName; Description: Description; IsCustomizable: IsCustomizable; IsAuditEnabled: IsAuditEnabled; OptionsSet: any; AttributeType: string; HasChanged?: any; AttributeOf?: any; ColumnNumber: number; DeprecatedVersion?: any; IntroducedVersion: string; EntityLogicalName: string; IsCustomAttribute: boolean; IsPrimaryId: boolean; IsPrimaryName: boolean; IsValidForCreate: boolean; IsValidForRead: boolean; IsValidForUpdate: boolean; CanBeSecuredForRead: boolean; CanBeSecuredForCreate: boolean; CanBeSecuredForUpdate: boolean; IsSecured: boolean; IsRetrievable: boolean; IsFilterable: boolean; IsSearchable: boolean; IsManaged: boolean; LinkedAttributeId?: any; IsValidForForm: boolean; IsRequiredForForm: boolean; IsValidForGrid: boolean; SchemaName: string; ExternalName?: any; IsLogical: boolean; IsDataSourceSecret: boolean; InheritsFrom?: any; SourceType: number; AutoNumberFormat: string; Format: string; ImeMode: string; MaxLength: number; YomiOf?: any; IsLocalizable: boolean; DatabaseLength: number; FormulaDefinition?: any; SourceTypeMask: number; AttributeTypeName: AttributeTypeName; IsValidForAdvancedFind: IsValidForAdvancedFind; RequiredLevel: RequiredLevel; FormatName: FormatName; Targets: string[]; } export interface XrmMetaEntity { LogicalName: string; MetadataId: string; DisplayName: DisplayName; Description: Description; IsCustomizable: IsCustomizable; IsAuditEnabled: IsAuditEnabled; HasChanged: any; ActivityTypeMask: number; Attributes: XrmMetaAttribute[]; DisplayCollectionName: DisplayCollectionName; IsActivity: boolean; IsActivityParty: boolean; IsBusinessProcessEnabled: string; IsChildEntity: boolean; IsCustomEntity: boolean; IsValidForAdvancedFind: boolean; IsValidForQueue: IsValidForQueue; ManyToManyRelationships: XrmMetaManyToManyRelation[]; ManyToOneRelationships: XrmMetaOneToManyRelation[]; ObjectTypeCode: number; OneToManyRelationships: XrmMetaOneToManyRelation[]; OwnershipType: string; PrimaryIdAttribute: string; PrimaryNameAttribute: string; SchemaName: string; CollectionSchemaName: string; Keys: any; EntitySetName: string; _type: string; } export enum XrmEntityFilter { Default = 1, Entity = 1, Attributes = 2, Privileges = 4, Relationships = 8, All = 15 } export interface AttributeTypeName { Value: string; } export interface FormatName { Value: string; } export interface RequiredLevel { Value: string; CanBeChanged: boolean; ManagedPropertyLogicalName: string; } export interface IsValidForAdvancedFind { Value: boolean; CanBeChanged: boolean; ManagedPropertyLogicalName: string; } export interface LocalizedLabel { MetadataId: string; HasChanged?: any; IsManaged: boolean; Label: any; LanguageCode: number; _type: string; } export interface UserLocalizedLabel { MetadataId: string; HasChanged?: any; IsManaged: boolean; Label?: any; LanguageCode: number; } export interface Description { LocalizedLabels: LocalizedLabel[]; UserLocalizedLabel: UserLocalizedLabel; } export interface LocalizedLabel { Label: any; MetadataId: string; HasChanged?: any; IsManaged: boolean; LanguageCode: number; _type: string; } export interface DisplayCollectionName { LocalizedLabels: LocalizedLabel[]; UserLocalizedLabel: UserLocalizedLabel; } export interface LocalizedLabel { MetadataId: string; HasChanged?: any; IsManaged: boolean; Label: any; LanguageCode: number; _type: string; } export interface DisplayName { LocalizedLabels: LocalizedLabel[]; UserLocalizedLabel: UserLocalizedLabel; } export interface IsAuditEnabled { CanBeChanged: boolean; ManagedPropertyLogicalName: string; Value: boolean; } export interface IsCustomizable { CanBeChanged: boolean; ManagedPropertyLogicalName: string; Value: boolean; } export interface IsValidForQueue { CanBeChanged: boolean; ManagedPropertyLogicalName: string; Value: boolean; } export interface XrmMetaRelation { IsCustomRelationship?: boolean; IsValidForAdvancedFind?: boolean; SchemaName: string; RelationshipType?: XrmMetaRelationshipType; } export interface XrmMetaOneToManyRelation extends XrmMetaRelation { ReferencedAttribute: string; ReferencedEntity: string; ReferencingAttribute: string; ReferencingEntity: string; ReferencedEntityNavigationPropertyName: string; ReferencingEntityNavigationPropertyName: string; } export interface XrmMetaManyToManyRelation extends XrmMetaRelation { Entity1LogicalName: string; Entity2LogicalName: string; IntersectEntityName: string; Entity1IntersectAttribute: string; Entity2IntersectAttribute: string; Entity1NavigationPropertyName: string; Entity2NavigationPropertyName: string; } export enum XrmMetaRelationshipType { OneToManyRelationship = 0, Default = 0, ManyToManyRelationship = 1 } This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1196 @@ import { XrmMetaOneToManyRelation, XrmMetaManyToManyRelation, IQueryRelation, QueryColumnType, QueryRelationType, IQueryTable, XrmEntityFilter, XrmMetaEntity, DisplayName XrmMetaAttribute } from "xrm-meta-models"; import { Observable } from "rxjs"; import { HttpClient, HttpHeaders } from "@angular/common/http"; // tslint:disable:no-bitwise // tslint:disable:max-line-length export class XrmMetaSdk { private _arrayElements = [ "Attributes", "ManyToManyRelationships", "ManyToOneRelationships", "OneToManyRelationships", "Privileges", "LocalizedLabels", "Options", "Targets" ]; constructor(private http: HttpClient, private clientUrl: string) {} public GetTables(): Observable<IQueryTable[]> { const _this = this; return new Observable<IQueryTable[]>(subscriber => { if (_this.IsLocal()) { this.http .get<XrmMetaEntity[]>("http://localhost:54566/GetEntity") .subscribe( entities => { subscriber.next(this.ParseTables(entities)); }, err => { subscriber.error(err); }, () => { subscriber.complete(); } ); } else { _this.RetrieveAllEntities( (entities: XrmMetaEntity[]) => { subscriber.next(this.ParseTables(entities)); subscriber.complete(); }, err => { subscriber.error(err); } ); } }); } public GetColumnsOfTable(table: IQueryTable): Observable<IQueryColumn[]> { const _this = this; return new Observable<IQueryColumn[]>(subscriber => { if (_this.IsLocal()) { this.http .get<XrmMetaAttribute[]>( "http://localhost:54566/GetAttribute/" + table.Id ) .subscribe( attributes => { const columns = _this.ParseColumns(table.Id, attributes); subscriber.next(columns); }, err => { subscriber.error(err); }, () => { subscriber.complete(); } ); } else { const __this = _this; _this.RetrieveAttributes( table.Id, (attributes: XrmMetaAttribute[]) => { const columns = _this.ParseColumns(table.Id, attributes); subscriber.next(columns); subscriber.complete(); }, err => { subscriber.error(err); } ); } }); } public GetRelationsOfTable(table: IQueryTable): Observable<IQueryRelation[]> { const _this = this; return new Observable<IQueryRelation[]>(subscriber => { if (_this.IsLocal()) { _this.http .get<XrmMetaEntity>( "http://localhost:54566/GetRelationships/" + table.Id ) .subscribe( entity => { const o2ms = entity.OneToManyRelationships; const m2os = entity.ManyToOneRelationships; const m2ms = entity.ManyToManyRelationships; subscriber.next(this.ParseRelations(table.Id, o2ms, m2os, m2ms)); }, err => { subscriber.error(err); }, () => { subscriber.complete(); } ); } else { const __this = _this; __this.RetrieveRelations( table.Id, null, (entity) => { const o2ms = entity.OneToManyRelationships; const m2os = entity.ManyToOneRelationships; const m2ms = entity.ManyToManyRelationships; subscriber.next(this.ParseRelations(table.Id, o2ms, m2os, m2ms)); subscriber.complete(); }, (err) => { subscriber.error(err); } ); } }); } private ParseTables( entities: XrmMetaEntity[]): IQueryTable[] { const tables = entities.map(entity => { return { Alias: "", Id: entity.LogicalName, Name: this.readLabel(entity), PrimaryKeyName: entity.PrimaryIdAttribute, PrimaryName: entity.PrimaryNameAttribute } as IQueryTable; }); return tables; } private ParseColumns( tableId: string, attributes: XrmMetaAttribute[] ): IQueryColumn[] { const columns = attributes.map(att => { return { Alias: "", Id: att.LogicalName, Name: this.readLabel(att), Table: tableId, OptionSet: att.OptionsSet.Options.map(op => { return { Key: this.readOptionLabel(op), Value: op.Value } as IQueryOption; }), Type: this.readAttributeType(att.AttributeType), Targets: att.Targets } as IQueryColumn; }); return columns; } private ParseRelations( tableId: string, o2ms: XrmMetaOneToManyRelation[], m2os: XrmMetaOneToManyRelation[], m2ms: XrmMetaManyToManyRelation[], ): IQueryRelation[] { const relations: IQueryRelation[] = []; for (let i = 0; i < o2ms.length; i++) { const o2m = o2ms[i]; const relation: IQueryRelation = ({ ParentColumn: o2m.ReferencedAttribute, ParentTable: o2m.ReferencedEntity, ChildColumn: o2m.ReferencingAttribute, ChildTable: o2m.ReferencingEntity, Id: o2m.SchemaName, RelationType: QueryRelationType.OneToMany } as any) as IQueryRelation; relations.push(relation); } for (let i = 0; i < m2os.length; i++) { const m2o = m2os[i]; const relation: IQueryRelation = ({ ChildColumn: m2o.ReferencedAttribute, ChildTable: m2o.ReferencedEntity, ParentColumn: m2o.ReferencingAttribute, ParentTable: m2o.ReferencingEntity, Id: m2o.SchemaName, RelationType: QueryRelationType.ManyToOne } as any) as IQueryRelation; relations.push(relation); } for (let i = 0; i < m2ms.length; i++) { const m2m = m2ms[i]; let pC, cC, pT, cT, iP, iC; if (m2m.Entity1LogicalName.toLowerCase() === tableId.toLowerCase()) { pT = m2m.Entity1LogicalName; cT = m2m.Entity2LogicalName; iP = m2m.Entity1IntersectAttribute; iC = m2m.Entity2IntersectAttribute; } else { pT = m2m.Entity2LogicalName; cT = m2m.Entity1LogicalName; iP = m2m.Entity2IntersectAttribute; iC = m2m.Entity1IntersectAttribute; } // TODO: Add proper table id here pC = pT + "id"; cC = cT + "id"; const relation: IQueryRelation = { ChildColumn: cC, ChildTable: cT, ParentColumn: pC, ParentTable: pT, Id: m2m.SchemaName, RelationType: QueryRelationType.ManyToMany, IntermediateChildColumn: iC, IntermediateParentColumn: iP, IntermediateTable: m2m.IntersectEntityName } as IQueryRelation; relations.push(relation); } return relations; } //#region internal helpers private readLabel(metaRecord: any): string { try { const disp = metaRecord.Label as DisplayName; return disp.UserLocalizedLabel.Label; } catch { let label = null; for (let i = 0; i < metaRecord.DisplayName.LocalizedLabels.length; i++) { if (metaRecord.DisplayName.LocalizedLabels[i].LanguageCode === 1033) { label = metaRecord.DisplayName.LocalizedLabels[i].Label; } } if (label === null) { if (metaRecord.DisplayName.LocalizedLabels.length > 0) { label = metaRecord.DisplayName.LocalizedLabels[0].Label; } else { label = metaRecord.LogicalName; } } return label; } } private readOptionLabel(metaRecord: any): string { try { const disp = metaRecord.Label as DisplayName; return disp.UserLocalizedLabel.Label; } catch { let label = null; for (let i = 0; i < metaRecord.Label.LocalizedLabels.length; i++) { if (metaRecord.Label.LocalizedLabels[i].LanguageCode === 1033) { label = metaRecord.Label.LocalizedLabels[i].Label; } } if (label === null) { if (metaRecord.Label.LocalizedLabels.length > 0) { label = metaRecord.Label.LocalizedLabels[0].Label; } else { label = "Option #"; } } return label; } } private readAttributeType(type: string): QueryColumnType { switch (type) { case "Lookup": { return QueryColumnType.Lookup; } case "State": { return QueryColumnType.State; } case "Memo": { return QueryColumnType.Memo; } case "Boolean": { return QueryColumnType.Boolean; } case "String": { return QueryColumnType.String; } case "Integer": { return QueryColumnType.Integer; } case "DateTime": { return QueryColumnType.DateTime; } case "Status": { return QueryColumnType.Status; } case "Uniqueidentifier": { return QueryColumnType.Uniqueidentifier; } case "Picklist": { return QueryColumnType.Picklist; } case "Owner": { return QueryColumnType.Owner; } case "BigInt": { return QueryColumnType.BigInt; } case "EntityName": { return QueryColumnType.EntityName; } case "Virtual": { return QueryColumnType.Virtual; } case "Decimal": { return QueryColumnType.Decimal; } case "ManagedProperty": { return QueryColumnType.ManagedProperty; } case "Customer": { return QueryColumnType.Customer; } case "PartyList": { return QueryColumnType.PartyList; } case "Double": { return QueryColumnType.Double; } case "Money": { return QueryColumnType.Money; } case "CalendarRules": { return QueryColumnType.CalendarRules; } default: { return QueryColumnType.None; } } } private IsLocal(): boolean { return ( window.location.hostname === "localhost" || window.location.hostname === "127.0.01" ); } private getUrl() { return this.clientUrl || window.location.hostname; } private getError(resp) { if (resp.status === 12029) { return new Error("The attempt to connect to the server failed."); } if (resp.status === 12007) { return new Error("The server name could not be resolved."); } const faultXml = resp.responseXML; let errorMessage = "Unknown (unable to parse the fault)"; let faultstring = null; let ErrorCode = null; if (typeof faultXml === "object") { const bodyNode = faultXml.firstChild.firstChild; // Retrieve the fault node for (let i = 0; i < bodyNode.childNodes.length; i++) { const node = bodyNode.childNodes[i]; // NOTE: This comparison does not handle the case where the XML namespace changes if ("s:Fault" === node.nodeName) { for (let j = 0; j < node.childNodes.length; j++) { const testNode = node.childNodes[j]; if ("faultstring" === testNode.nodeName) { faultstring = this.getNodeText(testNode); } if ("detail" === testNode.nodeName) { for (let k = 0; k < testNode.childNodes.length; k++) { const orgServiceFault = testNode.childNodes[k]; if ("OrganizationServiceFault" === orgServiceFault.nodeName) { for (let l = 0; l < orgServiceFault.childNodes.length; l++) { const ErrorCodeNode = orgServiceFault.childNodes[l]; if ("ErrorCode" === ErrorCodeNode.nodeName) { ErrorCode = this.getNodeText(ErrorCodeNode); break; } } } } } } break; } } } if (ErrorCode !== null && faultstring !== null) { errorMessage = "Error Code:" + ErrorCode + " Message: " + faultstring; } else { if (faultstring !== null) { errorMessage = faultstring; } } return new Error(errorMessage); } private getRequest(entityFiltersValue: string): string { return null; } private xmlEncode(strInput) { let c: number; let XmlEncode = ""; if (strInput === null) { return null; } if (strInput === "") { return ""; } for (let cnt = 0; cnt < strInput.length; cnt++) { c = strInput.charCodeAt(cnt); if ( (c > 96 && c < 123) || (c > 64 && c < 91) || c === 32 || (c > 47 && c < 58) || c === 46 || c === 44 || c === 45 || c === 95 ) { XmlEncode = XmlEncode + String.fromCharCode(c); } else { XmlEncode = XmlEncode + "&#" + c + ";"; } } return XmlEncode; } private objectifyNode(node) { // Check for null if (node.attributes != null && node.attributes.length === 1) { if ( node.attributes.getNamedItem("i:nil") != null && node.attributes.getNamedItem("i:nil").nodeValue === "true" ) { return null; } } // Check if it is a value if (node.firstChild != null && node.firstChild.nodeType === 3) { const nodeName = this.getNodeName(node); switch (nodeName) { // Integer Values case "ActivityTypeMask": case "ObjectTypeCode": case "ColumnNumber": case "DefaultFormValue": case "MaxValue": case "MinValue": case "MaxLength": case "Order": case "Precision": case "PrecisionSource": case "LanguageCode": return parseInt(node.firstChild.nodeValue, 10); // Boolean values case "AutoRouteToOwnerQueue": case "CanBeChanged": case "CanTriggerWorkflow": case "IsActivity": case "IsAIRUpdated": case "IsActivityParty": case "IsAvailableOffline": case "IsChildEntity": case "IsCustomEntity": case "IsCustomOptionSet": case "IsDocumentManagementEnabled": case "IsEnabledForCharts": case "IsGlobal": case "IsImportable": case "IsIntersect": case "IsManaged": case "IsReadingPaneEnabled": case "IsValidForAdvancedFind": case "CanBeSecuredForCreate": case "CanBeSecuredForRead": case "CanBeSecuredForUpdate": case "IsCustomAttribute": case "IsManaged": case "IsPrimaryId": case "IsPrimaryName": case "IsSecured": case "IsValidForCreate": case "IsValidForRead": case "IsValidForUpdate": case "IsCustomRelationship": case "CanBeBasic": case "CanBeDeep": case "CanBeGlobal": case "CanBeLocal": return node.firstChild.nodeValue === "true" ? true : false; // OptionMetadata.Value and BooleanManagedProperty.Value and AttributeRequiredLevelManagedProperty.Value case "Value": // BooleanManagedProperty.Value if ( node.firstChild.nodeValue === "true" || node.firstChild.nodeValue === "false" ) { return node.firstChild.nodeValue === "true" ? true : false; } // AttributeRequiredLevelManagedProperty.Value if ( node.firstChild.nodeValue === "ApplicationRequired" || node.firstChild.nodeValue === "None" || node.firstChild.nodeValue === "Recommended" || node.firstChild.nodeValue === "SystemRequired" ) { return node.firstChild.nodeValue; } const numberValue = parseInt(node.firstChild.nodeValue, 10); if (isNaN(numberValue)) { // FormatName.Value return node.firstChild.nodeValue; } else { // OptionMetadata.Value return numberValue; } break; // String values default: return node.firstChild.nodeValue; } } // Check if it is a known array if (this.isMetadataArray(this.getNodeName(node))) { const arrayValue = []; for (let i = 0; i < node.childNodes.length; i++) { let objectTypeName; if ( node.childNodes[i].attributes != null && node.childNodes[i].attributes.getNamedItem("i:type") != null ) { objectTypeName = node.childNodes[i].attributes .getNamedItem("i:type") .nodeValue.split(":")[1]; } else { objectTypeName = this.getNodeName(node.childNodes[i]); } const b = this.objectifyNode(node.childNodes[i]); b._type = objectTypeName; arrayValue.push(b); } return arrayValue; } // Null entity description labels are returned as <label/> - not using i:nil = true; if (node.childNodes.length === 0) { return null; } // Otherwise return an object const c: any = {}; if (node.attributes.getNamedItem("i:type") != null) { c._type = node.attributes.getNamedItem("i:type").nodeValue.split(":")[1]; } for (let i = 0; i < node.childNodes.length; i++) { if (node.childNodes[i].nodeType === 3) { c[this.getNodeName(node.childNodes[i])] = node.childNodes[i].nodeValue; } else { c[this.getNodeName(node.childNodes[i])] = this.objectifyNode( node.childNodes[i] ); } } return c; } private isMetadataArray(elementName) { for (let i = 0; i < this._arrayElements.length; i++) { if (elementName === this._arrayElements[i]) { return true; } } return false; } private selectNodes(node, XPathExpression): any[] { if (typeof node.selectNodes != null) { return node.selectNodes(XPathExpression); } else { const output = []; const XPathResults = node.evaluate( XPathExpression, node, this.NSResolver, XPathResult.ANY_TYPE, null ); let result = XPathResults.iterateNext(); while (result) { output.push(result); result = XPathResults.iterateNext(); } return output; } return []; } private selectSingleNodeText(node, xpathExpr) { const x = this.selectSingleNode(node, xpathExpr); if (this.isNodeNull(x)) { return null; } if (typeof x.text != null) { return x.text; } else { return x.textContent; } } private selectSingleNode(node, xpathExpr) { if (typeof node.selectSingleNode != null) { return node.selectSingleNode(xpathExpr); } else { const xpe = new XPathEvaluator(); const xPathNode = xpe.evaluate( xpathExpr, node, this.NSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null ); return xPathNode != null ? xPathNode.singleNodeValue : null; } } private getNodeText(node) { if (typeof node.text !== "undefined") { return node.text; } else { return node.textContent; } } private isNodeNull(node) { if (node == null) { return true; } if ( node.attributes.getNamedItem("i:nil") != null && node.attributes.getNamedItem("i:nil").value === "true" ) { return true; } return false; } private getNodeName(node: any) { if (typeof node.baseName != null) { return node.baseName; } else { return node.localName; } } private setSelectionNamespaces(doc) { const nameSpace = [ 'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"', 'xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts"', 'xmlns:i="http://www.w3.org/2001/XMLSchema-instance"', 'xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"', 'xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata"' ]; doc.setProperty("SelectionNamespaces", nameSpace.join(" ")); } private NSResolver(prefix) { const nameSpace = { s: "http://schemas.xmlsoap.org/soap/envelope/", a: "http://schemas.microsoft.com/xrm/2011/Contracts", i: "http://www.w3.org/2001/XMLSchema-instance", b: "http://schemas.datacontract.org/2004/07/System.Collections.Generic", c: "http://schemas.microsoft.com/xrm/2011/Metadata" }; return nameSpace[prefix] || null; } private evaluateEntityFilters(xrmFilter: XrmEntityFilter): string { const entityFilterArray = []; if ((1 & xrmFilter) === 1) { entityFilterArray.push("Entity"); } if ((2 & xrmFilter) === 2) { entityFilterArray.push("Attributes"); } if ((4 & xrmFilter) === 4) { entityFilterArray.push("Privileges"); } if ((8 & xrmFilter) === 8) { entityFilterArray.push("Relationships"); } return entityFilterArray.join(" "); } //#endregion private RetrieveAllEntities(successCallBack, errorCallBack) { const _this = this; const entityFiltersValue = this.evaluateEntityFilters(1); const request = [ '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">', '<soapenv:Header><a:SdkClientVersion xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">7.0</a:SdkClientVersion></soapenv:Header>', "<soapenv:Body>", '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">', '<request i:type="a:RetrieveAllEntitiesRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">', '<a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">', "<a:KeyValuePairOfstringanyType>", "<b:key>EntityFilters</b:key>", '<b:value i:type="c:EntityFilters" xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata">' + this.xmlEncode(entityFiltersValue) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>RetrieveAsIfPublished</b:key>", '<b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">' + this.xmlEncode("true") + "</b:value>", "</a:KeyValuePairOfstringanyType>", "</a:Parameters>", '<a:RequestId i:nil="true" />', "<a:RequestName>RetrieveAllEntities</a:RequestName>", "</request>", "</Execute>", "</soapenv:Body>", "</soapenv:Envelope>" ].join(""); const req = new XMLHttpRequest(); req.open( "POST", this.getUrl() + "/XRMServices/2011/Organization.svc/web", true ); // try { // req.responseType = "msxml-document"; // } catch (e) {} req.setRequestHeader("Accept", "application/xml, text/xml, */*"); req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); req.setRequestHeader( "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute" ); req.onreadystatechange = function() { if (req.readyState === 4 /* complete */) { req.onreadystatechange = null; // Addresses potential memory leak issue with IE if (req.status === 200) { // Success const doc = req.responseXML; try { _this.setSelectionNamespaces(doc); } catch (e) {} const entityMetadataNodes = _this.selectNodes( doc, "//c:EntityMetadata" ); const entityMetadataCollection: XrmMetaEntity[] = []; for (let i = 0; i < entityMetadataNodes.length; i++) { const a = _this.objectifyNode(entityMetadataNodes[i]); a._type = "EntityMetadata"; entityMetadataCollection.push(a); } successCallBack(entityMetadataCollection); } else { errorCallBack(_this.getError(req)); } } }; req.send(request); } private RetrieveAttributes(LogicalName, successCallBack, errorCallBack) { let MetadataId = null; const _this = this; if (LogicalName == null) { throw new Error( "SDK.Metadata.RetrieveEntity requires either the LogicalName or MetadataId parameter not be null." ); } if (LogicalName != null) { if (typeof LogicalName !== "string") { throw new Error( "SDK.Metadata.RetrieveEntity LogicalName must be a string value." ); } MetadataId = "00000000-0000-0000-0000-000000000000"; } if (MetadataId != null && LogicalName == null) { if (typeof MetadataId !== "string") { throw new Error( "SDK.Metadata.RetrieveEntity MetadataId must be a string value." ); } } if (typeof successCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveEntity successCallBack must be a function." ); } if (typeof errorCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveEntity errorCallBack must be a function." ); } const entityFiltersValue = this.evaluateEntityFilters(2); let entityLogicalNameValueNode = ""; if (LogicalName == null) { entityLogicalNameValueNode = '<b:value i:nil="true" />'; } else { entityLogicalNameValueNode = '<b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">' + this.xmlEncode(LogicalName.toLowerCase()) + "</b:value>"; } const request = [ '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">', // Allows retrieval if ImageAttributeMetadata objects '<soapenv:Header><a:SdkClientVersion xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">6.0</a:SdkClientVersion></soapenv:Header>', "<soapenv:Body>", '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">', '<request i:type="a:RetrieveEntityRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">', '<a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">', "<a:KeyValuePairOfstringanyType>", "<b:key>EntityFilters</b:key>", '<b:value i:type="c:EntityFilters" xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata">' + this.xmlEncode(entityFiltersValue) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>MetadataId</b:key>", '<b:value i:type="ser:guid" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">' + this.xmlEncode(MetadataId) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>RetrieveAsIfPublished</b:key>", '<b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">' + this.xmlEncode("true") + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>LogicalName</b:key>", entityLogicalNameValueNode, "</a:KeyValuePairOfstringanyType>", "</a:Parameters>", '<a:RequestId i:nil="true" />', "<a:RequestName>RetrieveEntity</a:RequestName>", "</request>", "</Execute>", "</soapenv:Body>", "</soapenv:Envelope>" ].join(""); const req = new XMLHttpRequest(); req.open( "POST", this.getUrl() + "/XRMServices/2011/Organization.svc/web", true ); // try { // req.responseType = "msxml-document"; // } catch (e) {} req.setRequestHeader("Accept", "application/xml, text/xml, */*"); req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); req.setRequestHeader( "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute" ); req.onreadystatechange = function() { if (req.readyState === 4 /* complete */) { req.onreadystatechange = null; // Addresses potential memory leak issue with IE if (req.status === 200) { const doc = req.responseXML; try { _this.setSelectionNamespaces(doc); } catch (e) {} const a: XrmMetaEntity = _this.objectifyNode( _this.selectSingleNode(doc, "//b:value") ); a._type = "EntityMetadata"; successCallBack(a.Attributes); } else { // Failure errorCallBack(_this.getError(req)); } } }; req.send(request); } private RetrieveRelations( LogicalName, MetadataId, successCallBack, errorCallBack ) { const _this = this; if (LogicalName == null && MetadataId == null) { throw new Error( "SDK.Metadata.RetrieveEntity requires either the LogicalName or MetadataId parameter not be null." ); } if (LogicalName != null) { if (typeof LogicalName !== "string") { throw new Error( "SDK.Metadata.RetrieveEntity LogicalName must be a string value." ); } MetadataId = "00000000-0000-0000-0000-000000000000"; } if (MetadataId != null && LogicalName == null) { if (typeof MetadataId !== "string") { throw new Error( "SDK.Metadata.RetrieveEntity MetadataId must be a string value." ); } } if (typeof successCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveEntity successCallBack must be a function." ); } if (typeof errorCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveEntity errorCallBack must be a function." ); } // Attributes and entities const entityFiltersValue = this.evaluateEntityFilters(8); let entityLogicalNameValueNode = ""; if (LogicalName == null) { entityLogicalNameValueNode = '<b:value i:nil="true" />'; } else { entityLogicalNameValueNode = '<b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">' + this.xmlEncode(LogicalName.toLowerCase()) + "</b:value>"; } const request = [ '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">', // Allows retrieval if ImageAttributeMetadata objects '<soapenv:Header><a:SdkClientVersion xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">6.0</a:SdkClientVersion></soapenv:Header>', "<soapenv:Body>", '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">', '<request i:type="a:RetrieveEntityRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">', '<a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">', "<a:KeyValuePairOfstringanyType>", "<b:key>EntityFilters</b:key>", '<b:value i:type="c:EntityFilters" xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata">' + this.xmlEncode(entityFiltersValue) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>MetadataId</b:key>", '<b:value i:type="ser:guid" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">' + this.xmlEncode(MetadataId) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>RetrieveAsIfPublished</b:key>", '<b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">' + this.xmlEncode("true") + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>LogicalName</b:key>", entityLogicalNameValueNode, "</a:KeyValuePairOfstringanyType>", "</a:Parameters>", '<a:RequestId i:nil="true" />', "<a:RequestName>RetrieveEntity</a:RequestName>", "</request>", "</Execute>", "</soapenv:Body>", "</soapenv:Envelope>" ].join(""); const req = new XMLHttpRequest(); req.open( "POST", this.getUrl() + "/XRMServices/2011/Organization.svc/web", true ); // try { // req.responseType = "msxml-document"; // } catch (e) {} req.setRequestHeader("Accept", "application/xml, text/xml, */*"); req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); req.setRequestHeader( "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute" ); req.onreadystatechange = function() { if (req.readyState === 4 /* complete */) { req.onreadystatechange = null; // Addresses potential memory leak issue with IE if (req.status === 200) { const doc = req.responseXML; try { _this.setSelectionNamespaces(doc); } catch (e) {} const a: XrmMetaEntity = _this.objectifyNode( _this.selectSingleNode(doc, "//b:value") ); a._type = "EntityMetadata"; successCallBack(a); } else { // Failure errorCallBack(_this.getError(req)); } } }; req.send(request); } private RetrieveAttribute( EntityLogicalName, LogicalName, MetadataId, successCallBack, errorCallBack ) { const _this = this; if ( EntityLogicalName == null && LogicalName == null && MetadataId == null ) { throw new Error( "SDK.Metadata.RetrieveAttribute requires either the EntityLogicalName and LogicalName parameters or the MetadataId parameter not be null." ); } if ( MetadataId != null && EntityLogicalName == null && LogicalName == null ) { if (typeof MetadataId !== "string") { throw new Error( "SDK.Metadata.RetrieveEntity MetadataId must be a string value." ); } } else { MetadataId = "00000000-0000-0000-0000-000000000000"; } if (EntityLogicalName != null) { if (typeof EntityLogicalName !== "string") { { throw new Error( "SDK.Metadata.RetrieveAttribute EntityLogicalName must be a string value." ); } } } if (LogicalName != null) { if (typeof LogicalName !== "string") { { throw new Error( "SDK.Metadata.RetrieveAttribute LogicalName must be a string value." ); } } } if (typeof successCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveAttribute successCallBack must be a function." ); } if (typeof errorCallBack !== "function") { throw new Error( "SDK.Metadata.RetrieveAttribute errorCallBack must be a function." ); } let entityLogicalNameValueNode; if (EntityLogicalName == null) { entityLogicalNameValueNode = '<b:value i:nil="true" />'; } else { entityLogicalNameValueNode = '<b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this.xmlEncode(EntityLogicalName.toLowerCase()) + "</b:value>"; } let logicalNameValueNode; if (LogicalName == null) { logicalNameValueNode = '<b:value i:nil="true" />'; } else { logicalNameValueNode = '<b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this.xmlEncode(LogicalName.toLowerCase()) + "</b:value>"; } const request = [ '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">', // Allows retrieval if ImageAttributeMetadata objects '<soapenv:Header><a:SdkClientVersion xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">6.0</a:SdkClientVersion></soapenv:Header>', "<soapenv:Body>", '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">', '<request i:type="a:RetrieveAttributeRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">', '<a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">', "<a:KeyValuePairOfstringanyType>", "<b:key>EntityLogicalName</b:key>", entityLogicalNameValueNode, "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>MetadataId</b:key>", '<b:value i:type="ser:guid" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">' + _this.xmlEncode(MetadataId) + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>RetrieveAsIfPublished</b:key>", '<b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">' + _this.xmlEncode("true") + "</b:value>", "</a:KeyValuePairOfstringanyType>", "<a:KeyValuePairOfstringanyType>", "<b:key>LogicalName</b:key>", logicalNameValueNode, "</a:KeyValuePairOfstringanyType>", "</a:Parameters>", '<a:RequestId i:nil="true" />', "<a:RequestName>RetrieveAttribute</a:RequestName>", "</request>", "</Execute>", "</soapenv:Body>", "</soapenv:Envelope>" ].join(""); const req = new XMLHttpRequest(); req.open( "POST", _this.getUrl() + "/XRMServices/2011/Organization.svc/web", true ); // try { // req.responseType = "msxml-document"; // } catch (e) {} req.setRequestHeader("Accept", "application/xml, text/xml, */*"); req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); req.setRequestHeader( "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute" ); req.onreadystatechange = function() { if (req.readyState === 4 /* complete */) { req.onreadystatechange = null; // Addresses potential memory leak issue with IE if (req.status === 200) { // Success const doc = req.responseXML; try { _this.setSelectionNamespaces(doc); } catch (e) {} const a = _this.objectifyNode( _this.selectSingleNode(doc, "//b:value") ); successCallBack(a); } else { // Failure errorCallBack(_this.getError(req)); } } }; req.send(request); } }