Skip to content

Instantly share code, notes, and snippets.

@iwannabebot
Last active February 8, 2019 13:56
Show Gist options
  • Save iwannabebot/67bbe0ec8502c4a5631427e0899f9be4 to your computer and use it in GitHub Desktop.
Save iwannabebot/67bbe0ec8502c4a5631427e0899f9be4 to your computer and use it in GitHub Desktop.
XRM Metadata SDK in TypeScript
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
}
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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment